Skip to main content

连接到mqtt broker

上一节我们生成了小程序中使用的mqtt库,这节我们来使用这个库。

首先 创建一个微信小程序项目,把mqtt.js、mqtt.min.js复制到utils目录

复制下面的代码到app.js

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);
});

完整代码:

app.js
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,域名已备案,可以直接设置到小程序后台,大家可以用来做日常测试,如果发现不能使用了,请联系我,我会给你临时开通。