# 物联网微信小程序-阿里云 **Repository Path**: Egrt/wechat_aliyun ## Basic Information - **Project Name**: 物联网微信小程序-阿里云 - **Description**: 微信小程序连阿里云平台,获取车辆设备定位、车速、电量,实现远程控制断油断电。 - **Primary Language**: JavaScript - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 36 - **Forks**: 13 - **Created**: 2020-01-17 - **Last Updated**: 2024-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 微信小程序阿里云物联网平台 使用小程序原生云开发搭建, 界面使用-[ColorUI](https://github.com/weilanwl/ColorUI) ## 目标功能: 1.用户管理 2.设备管理 3.设备属性读取、定位 4.设备命令下发 5.实现了车联网设备(Cat.1)的定位,远程控制车辆断油断电,超过辖区范围自动报警的功能。 ## 模组介绍 ``` 小熊派Cat.1开发板 继电器模块 微信小程序 ``` - **更新日志** 2020/7/19 版本号:1.0.0 2020/7/22 版本号:1.1.0 内容:引入了Color Ui 优化了系统界面。 2020/7/23 版本号:1.2.0 内容:优化了TabBar的Ui,实现了动态效果。引入了onfire.js实现了多页面之间的通信。 - **展示** ![首页](https://images.gitee.com/uploads/images/2020/0722/121531_6b7c5052_4815563.jpeg "首页") ![我的](https://images.gitee.com/uploads/images/2020/0722/121715_4270efa5_4815563.jpeg "我的") ### 微信小程序Websocket > 依靠在微信客户端的一个小程序,其开发语言不是原生的,而是采用 html+JavaScript+css 这样类似的前端代码,接近原生体验!既然是一种类似 ”寄生虫“ 附属在微信客户端 ”宿主“ 里生存,那就不得不按照 ”宿主“ 的生存习惯,所以必须对于在微信小程序上实现 websocket连接阿里云IOT物联网平台服务器,那就必须遵循以下重要的准则: 1. 连接的端口号必须是 443 ,必须是 https协议;这里采用原生的即可。 2. websocket之上再实现 mqtt 协议数据发送和接受,即可实现以 mqtt 协议通讯;而我这里采用的是这个很出名的库:https://github.com/mqttjs/MQTT.js 来实现对数据的处理。 ### 阿里云IOT物联网平台 websocket 阿里云IOT物联网平台支持基于WebSocket的MQTT协议。您可以首先使用WebSocket建立连接,然后在WebSocket通道上,使用 MQTT 协议进行通信,即MQTT over WebSocket! 1.证书准备。 WebSocket可以使用ws和wss两种方式,ws就是普通的WebSocket连接,wss就是增加了TLS加密。如果使用wss方式进行安全连接,需要使用和TLS直连一样的根证书。而我本次提供给大家的不需要根证书的。 2.连接说明: 使用WebSocket方式进行连接,区别主要在MQTT连接URL的协议和端口号,MQTT连接参数和TCP直接连接方式完全相同,其中要注意securemode参数,使用wss方式连接时securemode=2,使用ws方式连接时 securemode=3。 连接域名(服务器地址),华东2节点(即上海节点): ${YourProductKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com:443 其中 ${YourProductKey} 是个变量,请替换为您的产品key。 Connect指令中需要设置 Keep Alive(保活时间)。保活心跳时间取值范围为30至1200秒。如果心跳时间不在此区间内,物联网平台会拒绝连接。建议取值300秒以上。如果网络不稳定,将心跳时间设置高一些。 设备端在保活时间间隔内,至少需要发送一次报文,包括 PING 请求。 如果物联网平台在保活时间内无法收到任何报文,物联网平台会断开连接,设备端需要进行重连。 MQTT连接参数参数如下: ``` mqttClientId: clientId+"|securemode=3,signmethod=hmacsha1,timestamp=132323232|" mqttUsername: deviceName+"&"+productKey mqttPassword: sign_hmac(deviceSecret,content)sign签名需要把以下参数按字典序排序后,再根据signmethod加签。 content=提交给服务器的参数(productKey,deviceName,timestamp,clientId), 按照字母顺序排序, 然后将参数值依次拼接 ``` 其中, ``` clientId:表示客户端ID,建议mac或sn,64字符内。 timestamp:表示当前时间毫秒值,可选。 mqttClientId:格式中||内为扩展参数。 signmethod:表示签名算法类型。 securemode:表示目前安全模式,可选值有2 (wss协议)和3(ws协议)。 参考示例,如果预置前提如下: clientId = 12345,deviceName = device, productKey = pk, timestamp = 789,signmethod=hmacsha1,deviceSecret=secret ``` 使用ws方式 ``` 连接域名 ws://pk.iot-as-mqtt.cn-shanghai.aliyuncs.com:443 连接参数 mqttclientId=12345|securemode=3,signmethod=hmacsha1,timestamp=789| mqttUsername=device&pk mqttPasswrod=hmacsha1("secret","clientId12345deviceNamedeviceproductKeypktimestamp789").toHexString(); ``` 使用wss方式 连接域名 ``` wss://pk.iot-as-mqtt.cn-shanghai.aliyuncs.com:443 连接参数 mqttclientId=12345|securemode=2,signmethod=hmacsha1,timestamp=789| mqttUsername=device&pk mqttPasswrod=hmacsha1("secret","clientId12345deviceNamedeviceproductKeypktimestamp789").toHexString(); ``` ### 如何移植和使用 上面已经详细地说明了阿里云物联网平台 websocket 的协议,那么总的来说就是一个**加密算法**,因为我之前已经开源了一个在微信小程序上实现 Mqtt协议连接服务器,这只要拿到了连接的一些参数,那就不成问题了! 上面反复提到 hmacsha1 加密算法,那我就去找一个呗。还好,去官网 [GitHub找了一个:](https://github.com/xihu-fm/aliyun-iot-client-sdk) , 拿到了加密算法文件,按照上面说明,分别生成:mqttclientId、mqttUsername、mqttPasswrod、port端口号、url域名,就可以实现链接啦! - 为了简单实用,降低耦合,我一度封装起来生成的算法,其封装源码如下。 ``` exports.getAliyunIotMqttClient = function(opts) { //是否传入三元组 if (!opts || !opts.productKey || !opts.deviceName || !opts.deviceSecret) { throw new Error('options need productKey,deviceName,deviceSecret'); } if (opts.protocol === 'mqtts' && !opts.ca) { throw new Error('mqtts need ca '); } //是否传入区域 if (!opts.host && !opts.regionId) { throw new Error('options need host or regionId (aliyun regionId)'); } const deviceSecret = opts.deviceSecret; delete opts.deviceSecret; let secureMode = (opts.protocol === 'mqtts') ? 3 : 2; var options = { productKey: opts.productKey, deviceName: opts.deviceName, timestamp: Date.now(), clientId: Math.random().toString(36).substr(2) } let keys = Object.keys(options).sort(); // 按字典序排序 keys = keys.sort(); const list = []; keys.map((key) => { list.push(`${key}${options[key]}`); }); const contentStr = list.join(''); //加密算法生成 password opts.password = crypto.hex_hmac_sha1(deviceSecret, contentStr); opts.clientId = `${options.clientId}|securemode=${secureMode},signmethod=hmacsha1,timestamp=${options.timestamp}|`; opts.username = `${options.deviceName}&${options.productKey}`; opts.port = opts.port || 1883; //生成域名 opts.host = opts.host || `${opts.productKey}.iot-as-mqtt.${opts.regionId}.aliyuncs.com`; return (opts); //返回给上层 } ``` - 如何使用呢? 非常简单,只需要调用 getAliyunIotMqttClient(option) 传进一些参数即可获取全部东西; option 对象的定义如下: | 参数 | 含义 | |-|-| | productKey | 三元组信息 productKey | | deviceName | 三元组信息 deviceName | | deviceSecret | 三元组信息 deviceSecret | | regionId | 可选域,目前国内仅支持上海,所以是 cn-shanghai | | port | 443 不可修改,唯一! | 返回的对象的定义如下: | 参数 | 含义 | |-|-| | clientId | 连接参数 | | password | 连接参数 | | username | 连接参数 | | host | 连接的域名 | ### 例子 ``` data: { aliyunInfo: { productKey: 'a1o3SXAACTs23', deviceName: 'rgb2812', deviceSecret: 'RurAqmlt0duwMilKv6Oa856WDcQ279685a', regionId: 'cn-shanghai', } } var that = this //传进去三元组等信息,拿到mqtt连接的各个参数 let clientOpt = aliyunOpt.getAliyunIotMqttClient({ productKey: that.data.aliyunInfo.productKey, deviceName: that.data.aliyunInfo.deviceName, deviceSecret: that.data.aliyunInfo.deviceSecret, regionId: that.data.aliyunInfo.regionId, port: that.data.aliyunInfo.port, }); //得到连接域名 let host = 'wxs://'+clientOpt.host; this.setData({ 'options.clientId': clientOpt.clientId, 'options.password': clientOpt.password, 'options.username': clientOpt.username, }) //开始连接 this.data.client = mqtt.connect(host, this.data.options); this.data.client.on('connect', function(connack) { wx.showToast({ title: '连接成功' }) }) ``` ## onfire.js 待写(2020/7/23 21.51) ## 参考文档 - [ColorUI](https://github.com/weilanwl/ColorUI) - [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)