微信小程序由于校验合法域名和TLS版本以及https证书,所以如果不使用云开发,外部接口必须是HTTPS,我想在微信小程序上控制智能硬件设备,使用MQTT来实现,但是按照微信的要求,必须使用wss来连接MQTT服务器,也就是一般MQTT客户端在使用时,必须把usessl开关打开,置为true,否则即使ws或者tcp的mqtt能够连接,也不能通过微信的域名校验。下面我大致说一下我的方法。
1. MQTT服务搭建。MQTT服务一般较多的使用Mosquitto、EMQX和Apollo,我这次使用的Apollo。具体的方法可以参考:https://www.cnblogs.com/Esquecer/p/11430031.html。
2. 小程序配置MQTT客户端。
在这里我要说一下我遇到的坑,MQTT的客户端一般用的比较多是:https://github.com/mqttjs/MQTT.js和https://github.com/eclipse/paho.mqtt.javascript。我一开始使用了MQTT.js这个库,测试都比较正常,但是当我发送非string类型数据时,总是发不出去,网上大部分的测试例子都是发送string,发送string是正常的,就是不能发送buffer数据,尝试了各种办法,都是不行,我把代码贴出来,哪位大神能指点一下:
sendMqttMsg: function (msg, deviceId){
console.log("send msg length: " + msg.length);
console.log("send msg: " + bytes2StrForPrint(msg));
var buffer = new ArrayBuffer(msg.length);
var byteStream = new Uint8Array(buffer);
var options = { qos :2};
for (var i = 0; i < msg.length; i++) {
byteStream[i] = msg[i];
}
this.data.client.publish('bc/test', byteStream, options);
}
})
后来实在没办法,换成paho-mqtt.js,这次把不能发送buffer的问题解决了。
然后遇到了wss的问题,微信要求必须使用wss,但是使用wss直接连接MQTT服务器,一直报AMQJSC0001E Connect timed out错误,后来才了解,微信不支持直接使用wss连接MQTT服务器(也许我哪里配置不对),必须使用nginx转发一下,将wss端口转到ws端口上,所以下面开始安装nginx.
3. nginx安装与配置。
nginx安装可以搜索一下方法,比较简单,下载tar包,解压,make,make install,默认会安装到/usr/local/nginx目录下。下面说一下nginx配置,我的MQTT配置是按照Apollo的默认配置来的,ws端口是61623,wss端口是61624,我在nginx中监听61624,结果出现端口被占用,因为Linux不允许两个服务占用同一个端口号,所以我把apollo中wss端口改成443,其他改什么都无所谓,因为wss端口不会被小程序访问到,除非,你其他程序要访问wss,那么要正确填写apollo中配置的端口号。以下是我的nginx配置部分代码,其实就是把61624端口数据转到61623上来,其他的配置就是注意pem和key两个证书的位置,使用绝对路径,填写正确即可。
server {
# listen 80;
# server_name localhost;
listen 61624 ssl;
server_name wx.mypraise.cn;
ssl_certificate xxx.pem;
ssl_certificate_key xxxx.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
ssl_verify_client off;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# root html;
# index index.html index.htm;
proxy_redirect off;
proxy_pass http://xxxx:61623; #
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # 升级协议头
proxy_set_header Connection upgrade;
}
一顿操作猛如虎,都跑起来,总算解决了小程序MQTT连接问题了。