大家知道,微信小程序的websocket API他们自己定制了,这样一些运行在浏览器里的库默认是运行不了的,比如mqttjs这个库:https://github.com/mqttjs/MQTT.js
由于搜狗公司兄弟团队的一个微信小程序要跑mqtt协议,我研究了下,结果如下:
一、打包出一个可以运行在微信小程序里的my_mqtt.js客户端库
第一步:
参考此库官方说明:https://github.com/mqttjs/MQTT.js#browserify
npm install -g webpack // install webpack
cd node_modules/mqtt
npm install . // install dev dependencies
webpack mqtt.js ./my_mqtt.js --output-library-target commonjs2
第二步:
将生成的my_mqtt.js文件里所有的:
(function() { return this; }())
替换为:
window
第三步:
在my_mqtt.js文件顶部加上代码:
var setImmediate = setTimeout;
var clearImmediate = clearTimeout;
var socketOpen = false
var socketMsgQueue = []
function sendSocketMessage(msg) {
console.log('send msg:', typeof msg)
console.log(msg);
if (socketOpen) {
wx.sendSocketMessage({
data: msg
})
} else {
socketMsgQueue.push(msg)
}
}
var document = {
URL: ''
}
var window = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
WebSocket: function (url) {
console.log('call window WebSocket', arguments)
var ws = {
send: sendSocketMessage,
close: wx.closeSocket,
onopen: null,
onmessage: null,
onclose: null,
onerror: null
}
wx.connectSocket({ url: url })
wx.onSocketOpen(function (res) {
console.log('收到onopen事件:', arguments)
socketOpen = true
for (var i = 0; i < socketMsgQueue.length; i++) {
sendSocketMessage(socketMsgQueue[i])
}
socketMsgQueue = []
ws.onopen && ws.onopen.apply(ws, arguments)
})
wx.onSocketMessage(function (res) {
console.log('收到onmessage事件:', arguments)
console.log(res.data)
ws.onmessage && ws.onmessage.apply(ws, arguments)
})
wx.onSocketClose(function () {
console.log('收到onclose事件:', arguments)
ws.onclose && ws.onclose.apply(ws, arguments)
})
wx.onSocketError(function () {
console.log('收到onerror事件:', arguments)
ws.onerror && ws.onerror.apply(ws, arguments)
})
return ws;
}
}
二、微信小程序里调用my_mqtt.js
var mqtt=require('../../utils/my_mqtt.js')
var client = mqtt.connect('wss://workyun.com/mqtt')
client.subscribe("mqtt/demo")
client.on("message", function (topic, payload) {
console.log([topic, payload].join(": "))
client.end()
})
client.publish("mqtt/demo", "hello workyun.com !")
三、用nginx处理微信小程序的websocket不支持HTTP头:Sec-WebSocket-Protocol问题
nginx.conf:
location /mqtt {
proxy_pass http://test.mosquitto.org:8080;
proxy_redirect off;
proxy_set_header Host test.mosquitto.org:8080;
proxy_set_header Sec-WebSocket-Protocol mqtt;
more_clear_headers Sec-WebSocket-Protocol;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
http://test.mosquitto.org:8080是mqttjs官方给搭建的一个mqtt协议测试服务器,参见:MQTT on Websocket sample
你要是有你自己的mqtt服务器,请替换成您自己的,比如activeMQ服务器。
nginx的more_clear_headers配置添加参见:openresty/headers-more-nginx-module
以上为大佬的操作:下面为自己炒作
1.引入mqtt插件:var { Client, Message } = require('utils/paho-mqtt.js');
插件下载地址:
2.来一个对象: client: new Client('ws://192.168.1.105:8084/mqtt', "wxMqtt." + util.stimapTime(new Date())), // client 为全局变量
3.创建链接。注意:小程序只能链接一个WebSocket,所以哪个页面用到就使用那个页面,要不就全局变量控制全部页面数据
// 链接mqtt
_createMqtt: function(){
let that = this;
if(!client.isConnected()) // 先判断是否已连接
client.connect({ // 链接mqtt
useSSL: true,
cleanSession: false,
keepAliveInterval: 10,
reconnect: true,
onSuccess: function () {
client.subscribe("topic", { qos: 2 }); // 监听的主题topic和服务质量qos
},
onFailure: function (res) {
console.log(res)
}
})
client.onConnectionLost = function (responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage)
}
}
},
4.接收监听的主题消息
client.onMessageArrived = function (msg) {
//console.log(msg.topic +"-->"+ msg.payloadString)
var content = JSON.parse(msg.payloadString) // 将json字符串转换为json格式
if(msg.topic == 'topic'){ // 通过判断主题分辨不同的topic
}
}
client.onConnectionLost = function (responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
}