使用Service worker让页面支持离线访问

    Google最近推行的Progressive Web Apps是个很酷的东西,而且采用的技术也是w3c的标准,不像微信小程序那样自己搞了一套封闭的东西。其实里边相关的一项技术service worker早在去年就有了,目前只有高版本的Chrome和Firefox支持,这个东西就可以把网页做成支持离线访问。

    首先要在入口页面注册service worker

    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/serviceworker.js').then(function(registration) {
        console.log('ServiceWorker registration successful with scope: ', registration.scope);
      }).catch(function(err) {
        console.log('ServiceWorker registration failed: ', err);
      });
    }
    

    注意这个serviceworker.js必须放在根目录下。

    然后就是编辑这个serviceworker.js文件,控制哪些文件需要在本地缓存:

    // 缓存名称
    var ONLINE_CACHE_NAME = '2016-12-30 16:35';
    // 缓存页面
    var onlineCacheUrl = [
      '/',
      '/foo/bar/xxx.js',
      '/foo/bar/xxx.css',
      '/foo/bar/xxx.html',
      '/foo/bar/xxx.png',
    ];
    

    删除过期的缓存

    this.addEventListener('activate', function(event) {
      var cacheWhitelist = [ONLINE_CACHE_NAME];
    
      event.waitUntil(
        caches.keys().then(function(keyList) {
          return Promise.all(keyList.map(function(key) {
            if (cacheWhitelist.indexOf(key) === -1) {
              console.log('delete ' + key);
              return caches.delete(key);
            }
          }));
        })
      );
    });
    
    self.addEventListener('install', function(event) {
      event.waitUntil(
        caches.open(ONLINE_CACHE_NAME)
        .then(function(cache) {
          console.log('Opened cache');
          return cache.addAll(onlineCacheUrl);
        })
      );
    });
    

    下面这个fetch事件是最重要的,这相当于一个本地的代理服务器,所有的请求都会经过这里,然后把缓存里存在的东西原样返回,缓存里没有的东西从服务器获取再返回。

    self.addEventListener('fetch', function(event) {
      event.respondWith(
        caches.match(event.request)
        .then(function(response) {
            if (response) {
                return response;
            }
            return fetch(event.request);
        })
      );
    });
    

    最后还有一点,除了本地调试用的localhost以外,只有https的页面才能采用service worker。可以参考这个最简单的demo:

    service-worker-demo

    首次打开页面以后,把网络关掉再次打开,就不会出现Chrome的小恐龙了。

    serviceworker0

    打开Chrome的调试工具,在Application -> ServiceWorker一栏可以看到已经成功启用。

    serviceworker1

    用Telegram控制Shadowsocks

    最近花了好多时间重写这个项目,带来插件机制,更方便扩展功能,同时也不仅限于webgui,因此不想用网页来管理的人还可以用telegram的bot来管理。

    具体步骤如下:

    安装shadowsocks-manager,这个项目需要Node.js 6.*的版本:

    npm i -g shadowsocks-manager
    

    申请telegram的bot,先跟BotFather交谈,输入/newbot它就会创建一个,同时给了一个token,类似于:

    Use this token to access the HTTP API:
    172476948:AQItZe7PuRpq_rZqvlkEdx049oEJZV5KK9f
    

    创建~/.ssmgr/tg.yml文件,把刚刚的token填进去,内容如下:

    type: m
    empty: false
    shadowsocks:
      address: 127.0.0.1:6001
    manager:
      address: 127.0.0.1:6002
      password: '123456'
    plugins:
      telegram:
        use: true
        token: '172476948:AQItZe7PuRpq_rZqvlkEdx049oEJZV5KK9f'
      flowSaver:
        use: true
    db: 'tg.sqlite'
    

    运行shadowsocks,后面增加参数--manager-address=127.0.0.1:6001

    运行ssmgr

    ssmgr -s 127.0.0.1:6001 -m 127.0.0.1:6002
    

    运行另一个ssmgr

    ssmgr -c tg.yml
    

    然后用自己的telegram跟之前创建的bot交谈,先输入auth成为管理员,然后就能通过它来控制shadowsocks的端口新增、删除、密码修改、流量统计等事情了:

    • add (端口号) (密码) 添加一个端口并设置密码
    • del (端口号) 删除某个端口
    • list 查看已添加的端口
    • flow2hour 查看2小时内产生的流量

    更多功能就不一一列举了,可输入help查看具体的命令和参数,文档请参见这里

    Telegram01

    Telegram02

    跨设备同步

    之前一直在使用pushbullet,可以在电脑显示Android手机的通知,更重要的是可以在一台设备按Ctrl + C,在另一台设备按Ctrl + V。但是最近这个应用开始收费了,而且还不是一次性收费,包月用户才拥有高级功能,因此得找替代品。

    1.snapcopy

    snapcopy支持Chrome和Android,不需要两个设备在同一局域网,可以同步剪切板的文字。

    2.snapdrop

    snapdrop只有网页版,同一局域网的设备同时打开这个页面,就能互相发送文字或文件,貌似是用WebRTC实现的。

    3.airdroid

    这个应用的功能太多了,除了没有剪切板同步。

    CoreOS

    最近一直在尝试Docker,于是注意到这个CoreOS

    1.安装

    安装方式比较特别,首先到这里下载镜像文件,在虚拟机里用这个镜像启动,启动后就是一个完整的系统,不过是只读的,我们要先把它安装在硬盘里。

    先根据这个指南创建一个cloud-config.yaml文件,内容如下:

    #cloud-config
    hostname: core4
    
    coreos:
      etcd:
        discovery: https://discovery.etcd.io/<mytoken>
        addr: 192.168.10.9:4001
        peer-addr: 192.168.10.9:7001
      fleet:
        public-ip: 192.168.10.9
      units:
        - name: etcd.service
          command: start
        - name: fleet.service
          command: start
        - name: static.network
          content: |
            [Match]
            Name=enp0s3
    
            [Network]
            Address=192.168.10.9/24
            Gateway=192.168.10.1
            DNS=192.168.10.1
    users: 
        - name: core
          ssh-authorized-keys:
            - ssh-rsa 
    
        - groups:
            - sudo
            - docker
    

    然后执行coreos-install -d /dev/sda -c ./cloud-config.yaml,安装过程中会联网下载最新版的镜像文件,若干分钟后装好重启就能用了。

    2.集群

    CoreOS默认安装了etcd和fleet,组集群的方式有多种:

    • 每台机的配置文件配置相同的discovery: https://discovery.etcd.io/<mytoken>,这个token值可以到这个地址获取新的。

    • 主机上只需配置address和peer-address,其他的机器上增加一个peers指向主机的peer-address。

    • 另外还有其他的方式比较复杂,我也没有尝试。

    配置好集群后,在任意一台机可以启动容器,集群会自动安排容器运行在哪里,如果那台机被关闭了会自动在另一台启动相同的容器。