zoukankan      html  css  js  c++  java
  • 微信小程序 WebSocket 使用非 443 端口连接

    前言

    微信小程序支持使用 WebSocket 连接到服务器,准确地说是带 SSL 的 WebSocket,而微信小程序中不允许使用带端口的 wss 连接,只能使用 443 端口。想使用其他端口就需要在服务器做一层代理,本文以 Ubuntu 16.04 服务器为例,使用 nginx 做 Web Server 。本文参考了 如何在微信小程序的websocket上使用mqtt协议 ,在此感谢原作者。

    步骤

    安装 nginx 及配置的过程不再赘述,nginx 需要处理微信小程序 WebSocket 不支持 Sec-WebSocket-Protocol 头的问题,默认 nginx 不带这个功能,需要加上补丁 headers-more-nginx-module 后重新编译。Ubuntu 16.04 的 nginx 版本为 1.10.3 。

    wget https://nginx.org/download/nginx-1.10.3.tar.gz
    tar zxvf nginx-1.10.3.tar.gz
    git clone https://github.com/openresty/headers-more-nginx-module.git
    cp -r headers-more-nginx-module nginx-1.10.3
    cd nginx-1.10.3
    ./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=./headers-more-nginx-module
    make
    

    编译完成后将系统的 /usr/sbin/nginx 替换为 objs 目录中的 nginx 。

    sudo service nginx stop
    sudo cp /usr/sbin/nginx /usr/sbin/nginx.bak
    sudo cp ./objs/nginx /usr/sbin
    sudo service nginx start
    

    nginx 配置开启 443 端口及证书,可在腾讯云获取免费的 TrustAsia SSL 证书 ,/etc/nginx/sites-available/default 部分配置如下

    listen 80 default_server;
    #listen [::]:80 default_server;
    
    # SSL configuration
    #
    listen 443 ssl;
    # listen [::]:443 ssl default_server;
    ssl_certificate   /etc/nginx/ssl/xxxxxxxx.crt;
    ssl_certificate_key  /etc/nginx/ssl/xxxxxxxx.key;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:50m;
    ssl_protocols TLSV1.1 TLSV1.2 SSLv2 SSLv3;
    ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;
    

    用 Node.js 写了一个简易的 WebSocket 服务端,运行在 8080 端口。

    var WebSocket = require('ws');
    var WS_PORT = 8080;
    var ws_clients = [];
    
    var WebSocketServer = new WebSocket.Server({ host: '127.0.0.1', port: WS_PORT });
    console.log('开始监听Websocket端口:' + WS_PORT);
    
    WebSocketServer.on('connection', function(wsConnect, req) {
      ws_clients.push(wsConnect);
      console.log('Websocket客户端已连接:' + serial_number);
      console.log('Websocket客户端数量:' + ws_clients.length);
    
      wsConnect.on('message', function (message) {
        console.log('接收到消息:');
        console.log(message);
      });
    
      wsConnect.on('close', function(code, message) {
        ws_clients.splice(ws_clients.indexOf(wsConnect), 1);
        console.log('Websocket客户端已断开');
        console.log('Websocket客户端数量:' + ws_clients.length);
      });
    
      wsConnect.on('error', function(code, message) {
        ws_clients.splice(ws_clients.indexOf(wsConnect), 1);
        console.log('Websocket客户端已断开');
        console.log('Websocket客户端数量:' + ws_clients.length);
      });
    });
    

    在 /etc/nginx/sites-available/default 中添加一项 location,将来自 443 端口 /wss 的 Websocket 连接代理至 8080 端口。即在小程序的 wx.connectSocket 的 url 中填 wss://服务器域名/wss 。

    location /wss {
      proxy_pass http://127.0.0.1:8080;
      proxy_redirect off;
      proxy_read_timeout 86400;
      proxy_set_header Host xxx.xxx.xxx;
    
      proxy_set_header Sec-WebSocket-Protocol wss;
      more_clear_headers Sec-WebSocket-Protocol;
    
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
    

    不出问题的话,小程序 WebSocket 即可连接到服务器的非 443 端口,而原有的 Web 服务则不受影响。

  • 相关阅读:
    商户编号前三位代码对应的收单机构大全
    使用邮件模板(freemarker.jar)发送邮件
    Struts2自定义拦截器
    如何在jsp页面显示存储在数据库的图片
    正则表达式 大于0的数字(包含小数)
    Linux的关机命令
    maven的下载和安装
    web.py的安装
    安装第三方插件BeautifulSoup
    myeclipse离线安装pydev插件
  • 原文地址:https://www.cnblogs.com/HintLee/p/9499435.html
Copyright © 2011-2022 走看看