连接到mqtt broker
上一节我们生成了小程序中使用的mqtt库,这节我们来使用这个库。
首先 创建一个微信小程序项目,把mqtt.js、mqtt.min.js复制到utils目录
复制下面的代码到app.js
import { connect } from './utils/mqtt.min';
App({
onLaunch() {
let client = connect('wxs://mqttx.cn:8883/mqtt', {
clientId: 'test'
});
client.on('connect', function (connack) {
console.log('connected', connack);
});
}
});
import..from..是es6语法,mqtt库会导出一些方法,数据结构供外部使用,import的作用就是导入另一个文件中导出的方法、数据结构。
App的onLaunch是小程序的生命周期方法,小程序初始化完成时触发,全局只触发一次,我们在这个方法里连接到mqtt broker。
connect([url], options)就是创建一个连接并且返回一个对象,这个对象上可以监听事件,比如connect:表示连接成功,即接收到了connack、message事件:表示接收到了消息,即收到了publish数据包、offline事件:表示客户端离线,即发送的pingreq心跳包在一定时间内没有收到服务端pingresp数据包。
url参数是可选的,用options里传入protocol、host、port、path等参数可以达到同样的效果。
比如
let client = connect({
protocol: 'wxs',
host: 'mqttx.cn',
port: 8883,
path: '/mqtt'
});
url参数的格式是 协议://ip地址:port端口号/path
options对象比较复杂,其中比较重要的几个含义如下:
- keepalive 默认 60 秒, 设为 0 表示不发送心跳包,并且服务端也不会因为客户端没有发送心跳包主动断开客户端连接。
- clientId 默认是 'mqttjs_' + Math.random().toString(16).substr(2, 8),clientId是服务端对客户端的唯一标识,如果两个客户端使用了相同的clientId会发生不停的断线重连。在小程序调试中,如果clientId是固定字符串,建议后面加个 wx.getSystemInfoSync().platform以区分是模拟器还是真机调试,避免出现互相踢下线的情况。
- protocolVersion 默认是4,如果想用mqtt 5可以设置为5
- clean 即cleansession,默认为 true,如果想接受到qos 1、qos 2离线消息,clean需要设置为false。
- reconnectPeriod 自动重连间隔,默认1000毫秒,设置为0表示禁止断线重连。
- username MQTT connect数据包的username,用于用户鉴权的
- password MQTT connect数据包的password,用于用户鉴权的,为了服务端安全,不是所有客户端都可以链接上来。
- will {} 当客户端异常断开(没有发送disconnect就断开了,可能是网络异常或者用户直接离开了程序),服务端会用will qos向will topic发送will payload,以达到通知对方的目的,和人类的遗嘱很像,所以也叫遗嘱消息。
- topic publish消息的主题
- payload publish消息的payload
- qos publish消息的qos
- retain publish消息的retain,什么叫retain?当mqtt服务端收到retain消息时候会把这个消息保存到这个topic下,而且只保留最后一条retain消息。这么做的目的是让新的topic订阅者马上就可以收到最近的一个状态,比如上一次的温度,而不用等到下次发送。
connect方法返回一个MqttClient对象,上面可以注册事件,就像dom元素上用addEventListener、onClick注册事件差不多。
client.on('connect', callback) 表示在连接成功之后触发,内部实现是在收到connack并且returnCode为0时候,callback回调函数里会传入一个connack数据包,可以从上面获取 returnCode和sessionPresent,如果returnCode为0表示连接成功,1表示连接失败,协议版本不支持等。sessionPresent表示mqtt服务端是否存在此clientId的session,也就是这个clientId以前用clean: false连接过,并且session还在有效期内,sessionPresent为true,理论上你不需要重新订阅。
示例代码:
client.on('connect', function (connack) {
console.log('connected', connack.sessionPresent);
});
完整代码:
import { connect } from './utils/mqtt.min';
App({
onLaunch() {
let client = connect({
protocol: 'wxs',
host: 'mqttx.cn',
port: 8883,
path: '/mqtt',
clientId: 'test',
clean: false
});
client.on('connect', function (connack) {
console.log('connected', connack.sessionPresent);
});
}
});
说明
mqttx.cn是我为了测试搭建的mqtt服务,支持tcp、websocket,域名已备案,可以直接设置到小程序后台,大家可以用来做日常测试,如果发现不能使用了,请联系我,我会给你临时开通。