最近公司有一个需求是用小程序扫码来控制设备的开关电源,然后保存开关纪录,以备后面查询统计。
首先分析一下需求,看下需要准备的东西。
1、小程序。需要https域名的接口,这里可以到阿里云、七牛云等等申请1年免费的ssl证书。然后把拿到的证书放到指定文件夹下,Nginx配置,域名解析,能正常访问https://xx.xxx.com就可以了。
2、MQTT服务端,小程序一方作为客户端,电子硬件那边还要有一个客户端,三端之间进行通信。因为时间有限,催促的比较着急,这里选择了一个第三方EMQ X。
3、小程序专属wss(wxs)域名配置。
首先我们先用docker安装EMQ X Broker,
docker run -d --name emqx -p 1883:1883 -p 8093:8093 -p 8883:8883 -p 8094:8094 -p 18083:18083 emqx/emqx:v4.0.0
因为这里我8083和8084端口被占用了,分别改为了8093和8094,运行成功后,进到docker容器里面,
docker exec -it emqx /bin/sh
打开配置文件
vi /opt/emqx/etc/emqx.conf
修改:
listener.ws.external = 8093
listener.wss.external = 8094
listener.wss.external.mqtt_path = /mqtt
listener.wss.external.keyfile = etc/wss.key //这里是申请的免费ssl证书 路径自己定义 放到docker容器里
listener.wss.external.certfile = etc/wss.crt //这里是申请的免费ssl证书 路径自己定义 放到docker容器里
保存重启emqx服务,emqx restart,可以在18083后台看到端口已经更改成功,这里还需要配置一下Nginx。
找到Nginx的配置文件,一般在/usr/local/nginx/conf/nginx.conf
upstream websocket {
server 192.168.xx.xxx:8093;
}
server {
listen 80;
listen 443 ssl;
server_name xx.xxx.com;
ssl_certificate /usr/ssl/xx.xxx.com.crt;
ssl_certificate_key /usr/ssl/xx.xxx.com.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
client_header_timeout 300s;
location / {
root html;
proxy_pass http://192.168.xx.xxx;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
chunked_transfer_encoding off;
keepalive_timeout 300;
client_max_body_size 120m;
client_body_timeout 300s;
index index.html index.php;
}
location /mqtt {
proxy_pass http://websocket/mqtt;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
按照以上格式修改之后,重启Nginx服务,/usr/local/nginx/sbin/nginx -s reload
自此小程序通过wxs://xx.xxx.com/mqtt就可以连接到MQTT服务端了,电子硬件那边可以通过1883端口连接到MQTT服务端,通过clientid或者同一个订阅,就可以实现3端之间的通信,从而实现小程序控制设备的开和关。
下面为部分小程序连接MQTT服务代码,仅供参考:
data: {
urls:'wxs://applet.allifetech.com/mqtt',
client:null,
//MQTT连接的配置
options: {
clientId: 'Test',
clean: false,
password: 'admin',
username: 'public',
keepalive:60, //心跳时间
}
},
onLoad: function (options) {
var that = this
that.data.client = mqtt.connect(that.data.urls,that.data.options)
that.data.client.on('connect', () => {
// 订阅默认主题
that.data.client.subscribe('defaulttopic', (err) => {
console.log(err || '订阅默认主题成功')
})
//发布消息
that.data.client.publish('defaulttopic', 'testmsg', (err) => {
console.log(err || '发送信息成功')
})
//收取消息
that.data.client.on('message', (topic, message) => {
let msg = message.toString();
console.log('收到来自', topic, '的消息:', message.toString());
//接收打开或者关闭设备返回的信息
if(action == '10001001'){
wx.request({
url: 'https://xx.xxx.com/api/api/add', //添加开关记录
method:'get',
data:{xx:xx,yy:yy,zz:zz},
success:function(e){
console.log(e);
}
})
}
})
}
电子硬件那边的客户端根据自己的语言来找连接MQTT服务的代码吧,方法类似,都是先订阅在发送和接收消息,端口可以选择1883,就微信小程序的要求比较多还比较特殊。
因为我也是第一次用MQTT服务,花费了两三天的时间,中间肯定还会出一些奇奇怪怪的问题,不要着急,静下心去一点一点拆分学习、操作,慢慢就会成功啦!