uniapp app端接入mqtt踩坑提示

2,876 阅读2分钟

接入版本必须是

"mqtt": "^3.0.0"//或者4.1.0

引入方式,必须是dist文件下

import mqtt from "mqtt/dist/mqtt.js";

端口号app端不支持ws://,必须是wx://

clientId动态生成

完整代码如下 (客户端id,clientId最好获取用户id进行拼接,不然用户切换账号会发生取消订阅还是可以收到消息情况)

//定义clientId
let clientId;
// #ifdef H5
clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8);
// #endif
// #ifdef APP-PLUS 
clientId = plus.push.getClientInfo().clientid; //获取客户端推送标识信息
// #endif


//定义option
connectOption: {
	clean: false,//没有接收到的消息重连后可以再次接收
	clientId: clientId,
	username: 'xxxx',
	password: 'xxxx',
	connectTimeout: 4000, //超时时间,默认3000毫秒
	keepAlive: 15, // 心跳时间 默认60s, 设置0为禁用
	reconnection: true, //断开是否重连
	reconnectPeriod: 1000, // 重连间隔时间,单位为毫秒,默认为 1000 毫秒,注意:当设置为 0 以后将取消自动重连
        qos:2
},



//对应页面使用mqtt
import mqtt from "mqtt/dist/mqtt.js";
//也可使用uuid生成clientId
import { v4 } from 'uuid';

connect() {
	let client
  //生成clientId
	connectOption.clientId = v4()
	let that = this
	// #ifdef H5
	client = mqtt.connect('ws://xxxxxx/ws', connectOption)
	// #endif
	// #ifdef MP-WEIXIN||APP-PLUS
	client = mqtt.connect('wx://xxxxxx/ws', connectOption)
	// #endif
	client.on('connect', function() {
		console.log('连接成功')
		client.subscribe('xxxxxx',{qos:2}, function(err) {
			if (!err) {
				console.log('订阅成功!')
			}
		})
	}).on('reconnect', function(error) {
		console.log('正在重连...', 'test_uniapp')
	}).on('error', function(error) {
		console.log('连接失败...', error)
	}).on('end', function() {
		console.log('连接断开')
	}).on('message', function(topic, message) {
		// console.log(topic, message)
                console.log('接收推送信息:', message.toString())
	})
},

取消订阅

try{
    client.unsubscribe('tieju/user/' + this.userInfo.id, (error) => {
        if (error) {
                console.log('取消订阅出错', this.userInfo.id);
        } else {
                //断开连接
                client.end()
                this.$store.commit('setClient', {})
                console.log('取消订阅成功', this.userInfo.id);
        }
    });
}catch{

}

可能会遇到的报错

TypeError: socketTask.onOpen is not a function

在mqtt.js中修改

socketTask = wx.connectSocket({
    url: url,
    protocols: websocketSubProtocol,
    success:()=>{}//增加这行
  })
TypeError: cb is not a function

循环订阅多个topic,不可以将连接mqtt的代码写入循环中

// #ifdef H5
//将连接mqtt的代码放在循环外面
client = mqtt.connect('ws://' + LGMqttUrl, connectOption)
// #endif
// #ifdef APP-PLUS
client = mqtt.connect('wx://' + LGMqttUrl, connectOption)
// #endif
for (let index = 0; index < topicData.length; index++) {
	client.on('connect', function() {
		try {
			client.subscribe(topicPath, function(err) {
				if (!err) {
					console.log('订阅成功!', topicPath)
				}
			})
		} catch (e) {
			console.log(e);
		}
	}).on('reconnect', function(error) {
		console.log('正在重连...', 'test_uniapp')
	}).on('error', function(error) {
		console.log('连接失败...', error)
	}).on('end', function() {
		console.log('连接断开')
	})
}

不可以在循环中处理订阅消息,不然会出现多次订阅相同主题的情况。 封装方法,单独处理获取订阅消息逻辑

client.on('message', function(topicPath, message) {
	if (message) {
		let data = message.toString('utf-8');
		data = JSON.parse(data);
                //判断是哪条topic的订阅消息
		let topicItem = topicData.filter((item) => item.topic == topicPath)[0]	
	}
})