微信小程序使用STOMP(WebSocket)

微信小程序使用STOMP(WebSocket)

小程序的WebSocket API跟一般浏览器的有点差别,存在一些限制。本文主要涉及小程序使用STOMP时注意事项。

基础

  • 小程序需要维护两个状态:

    • 微信服务器登录状态
    • 第三方(即我们自己服务器)的登录状态
  • 小程序使有wx.request()来发起请求,使用wx.connectSocket()创建WebSocket连接

    • wx.request()不会自动加上cookie来,可以自己加cookie到header或使用其他session标识
    • wx.connectSocket()跟wx.request()类似,handshake时加上session标识
  • 真实环境需要在微信平台预设相关域名,必须使用TLS,即使用https、wss协议。开发调试时可以不限制。

使用STOMP与WebSocket遇到的问题

问题1: 连接成功后,很快自动断开

因为刚开始使用STOMP时,同事在网上找到以下代码。出现问题我打开代码看了一下,刚看到肯定都觉得两个空方法很奇怪,原来不写会报错。打开stomp.js一看,很快找到原因,setInterval是用来发心跳包的,而小程序没有window对象。

网络文章

var Stomp = require('../../utils/stomp.js').Stomp;
Stomp.setInterval = function () { }
Stomp.clearInterval = function () { }
var client = Stomp.over(ws);

stomp.js部分源码

if (typeof window !== "undefined" && window !== null) {
    Stomp.setInterval = function (interval, f) {
      return window.setInterval(f, interval);
    };
    Stomp.clearInterval = function (id) {
      return window.clearInterval(id);
    };
    window.Stomp = Stomp;
  } else if (!exports) {
    self.Stomp = Stomp;
  }

解决办法

Stomp.setInterval = function (interval, f) {
    return setInterval(f, interval);
};
Stomp.clearInterval = function (id) {
  return clearInterval(id);
};

问题2: 电脑开发时连接正常,手机远程调试时连接失败

一开始 返回 401 UNAUTHORIZED,后来看到client日志提示draft handshake refused。
逐步排除 域名限制、TLS证书有效性、Nginx配置、跨域问题。本应该先关注 401状态码的,通过服务器日志与后台调试,发现问题所在:client发起连接时没有在代码加上session标识,server需要它来验证的,所以握手时就失败。而在电脑开发时,websocket连接却自动带上了cookie,所以做成了手机与电脑的不一致。

解决办法,连接时加上session标识

wx.connectSocket({
      url: 'wss://example.qq.com',
      header:{ 
        'Session-Id': 'xxxxxxxx'
      },
      success(): function(){
          //
      }
 });

Nginx配置WebSocket反向代理

location /websocket {
   proxy_pass http://127.0.0.1:8080;
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection $connection_upgrade;
}

另外,Nginx对外服务可以使用https,RealServer可以只用http

小程序websocket官方说明

基础库 1.7.0 之前,一个微信小程序同时只能有一个 WebSocket 连接,如果当前已存在一个 WebSocket 连接,会自动关闭该连接,并重新创建一个 WebSocket 连接。基础库版本 1.7.0 及以后,支持存在多个 WebSokcet 连接,每次成功调用 wx.connectSocket 会返回一个新的 SocketTask。— https://mp.weixin.qq.com

示例代码

wx.connectSocket({
  url: 'wss://example.qq.com',
  data:{
    x: '',
    y: ''
  },
  header:{ 
    'content-type': 'application/json'
  },
  protocols: ['protocol1'],
  method:"GET"
})

你可能感兴趣的:(微信小程序使用STOMP(WebSocket))