微信小程序使用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);
1
2
3
4

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;
 }
1
2
3
4
5
6
7
8
9
10
11

解决办法

Stomp.setInterval = function (interval, f) {
 return setInterval(f, interval);
};
Stomp.clearInterval = function (id) {
 return clearInterval(id);
};
1
2
3
4
5
6

问题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(){
 //
 }
 });
1
2
3
4
5
6
7
8
9

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;
}
1
2
3
4
5
6
7

另外,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)

相关推荐