小菜啊
小菜啊
  • 发布:2021-01-14 17:59
  • 更新:2024-09-05 11:18
  • 阅读:15915

uniapp中使用mqtt,支持app,h5,小程序,使用node搭建mqtt本地服务,实现发布,订阅和接收消息

分类:uni-app

一:本地node搭建MQTT服务器

1 创建文件夹,在文件夹中添加依赖包

mqtt:npm install mqtt --save
mosca:npm install mosca --save

2 创建mqtt.js文件,并添加代码 (mtqq 服务端)

var mosca = require('mosca'); //构建服务器  
// 此处配置mqtt的http客户端,尤为重要,http.port则为你HTTP访问端口,可以在网页上输入127.0.0.1:8888(端口),能请求成功则配置成功  
var MqttServer = new mosca.Server({  
    port: 8083,  
    http: {  
        port: 8888,  
        bundle: true,  
        static: './'  
      }  
});  

//监听链接  
MqttServer.on("clientConnected", function(client) {  
    console.log("client connected", client.id);  
});  

//监听mqtt的主题消息  
MqttServer.on("published", function(packet, client) { //当客户端有连接的时候,发布主题消息  
    var topic = packet.topic;  
    console.log(packet);  
    switch (topic) {  
        case 'test':  
            console.log("message-publish", packet.payload.toString());  
            //mqtt转发主题消息  
            MqttServer.publish({  
                topic: 'other',  
                payload: '这是服务端发过来的消息!'  
            });  
            break;  
    }  
});  

MqttServer.on('ready', function() {  
    console.log("mqtt is running....");  
});

3 创建publish文件,并添加代码 (mqtt 发布者)

var mqtt = require('mqtt');  
var client = mqtt.connect('mqtt://127.0.0.1:8083');//连接到服务端  
var num = 1;  
var qtt = {};//定义消息(可以为字符串,对象等)  

setInterval(function() {  
    qtt.title = 'publish';  
    qtt.text = '这是第'+num+'条测试消息';  
    client.publish('test',JSON.stringify(qtt),{qos:1,retain:true});//hello mqtt +   
    num++  
    console.log("publish 发布了一条内容为text的消息")  
},2000);

4 创建subclient文件,并添加代码 (mqtt 订阅者)

// 接收消息的客户端;  
var mqtt = require('mqtt');  
let options = {  
    clientId:"test-id",  
    connectTimeout: 600000,  
    clean: true  
}  
var client2 = mqtt.connect("mqtt://127.0.0.1:8083",options);  
console.log(client2)  
//订阅主题为test的消息  
client2.subscribe('test',{qos:1},function(err){  
    if(!err) {  
        console.log('订阅主题成功')  
    }else{  
        console.log(err)  
    }  
});  

client2.on('message',function(top,message) {  
    console.log(message.toString());  
});

5 在当前文件夹下打开三个命令窗口,依次运行

node mqtt.js
node publish.js
node subclient.js
ps:遇到 schema 报错需注释掉 /node_modules/jsonschema/lib/validator.js 中的如下代码

if((typeof schema !== 'boolean' && typeof schema !== 'object') || schema === null){  
   throw new SchemaError('Expected `schema` to be an object or boolean');  
}

运行后的效果截图

至此,本地成功搭建mqtt服务端

二:在uniapp中使用mqtt,在H5和app端实现订阅,接收消息

1 创建一个uniapp 默认项目,并引入node依赖

npm install mqtt@3.0.0

2 在组件中发起订阅,订阅方法如下

connect() {  
    var self = this  
    var subscribe = "test"    
    var mqtt = require('mqtt/dist/mqtt.js')  
    // #ifdef H5  
    let options = {  
        clientId:"H5_test",  
        connectTimeout: 600000,  
        clean: true  
    }  
    // 此处的端口为mqtt.js中的http端口,否则H5和手机连接不上mqtt服务器  
    var client = mqtt.connect('ws://127.0.0.1:8888/mqtt',options)  
    // #endif  
    // #ifdef MP-WEIXIN||APP-PLUS  
    let options = {  
        clientId:"APP_test",  
        connectTimeout: 600000,  
        clean: true  
    }  
    // 此处需要改成你的主机ip,并保证测试手机跟你的电脑处于同一个局域网  
    var client = mqtt.connect('wx://xxx.xxx.x.xxx:8888/mqtt',options)  
        // #endif  
    client.on('connect', function(res) {  
        uni.showToast({  
            title:"连接成功",  
            duration:2000,  
            icon:"none"  
        })  

        client.subscribe(subscribe, function(err) {  
            if (!err) {  
                uni.showToast({  
                    title:"订阅成功",  
                    duration:2000,  
                    icon:"none"  
                })  
            }  
        })  
    }).on('message', function(topic, message) {  
        console.log(JSON.parse(message.toString()))  
    }).on('reconnect', function(topic, message) {  
        console.log("重连")  
    })  
}

附上H5和手机端订阅后的效果,需要两个demo的可以留言邮箱

有时没看到消息的话 可去 https://gitee.com/lianzhichao/mqtt-serverandclient/tree/master/rar 下载

本文借鉴猫猫猫猫的mqtt-demo,因为在猫猫发布的篇中参与评论后,许多小伙伴联系我,想要从0开始搭建,使用mqtt,所以写了这篇文章,如果有大佬发现错误或有侵权之处,联系侵删,多有不足之处请原谅,觉得不错麻烦给个赞哦,谢谢各位

15 关注 分享
天涯2020 OlyLis 3***@qq.com tuonioooo wuyi 朱小 1***@qq.com 1***@qq.com 1***@qq.com DCloud_UNI_OttoJi 套马杆的套子 clai 2***@qq.com DCloud_UNI_CHB 唐家三少

要回复文章请先登录注册

小菜啊

小菜啊 (作者)

回复 yaodaren :
我的意思是你离开当前页面不是取消订阅了么?在其他页面是否还能收到当前页面订阅的主题发送的消息
2021-09-17 11:04
yaodaren

yaodaren

回复 小菜啊 :
有输出的,我是二次封装了一个js文件,里面写了mqtt初始化及相关方法,然后需要用到的页面引入该js文件,并重写订阅、发布和接收方法 ,因为每个页面都有发布和订阅。所以关闭当前页面还是可以收到mqtt消息的
2021-09-17 10:57
小菜啊

小菜啊 (作者)

回复 yaodaren :
不知道你怎么写的,但是我怀疑你的mqttClient在页面关闭后还在一直监听着mqtt消息,你可以尝试在方法里输出一下,跳转到其他页面后看看还会不会输出
2021-09-17 09:27
小菜啊

小菜啊 (作者)

回复 1***@163.com :
有一种情况会一直重连,就是clientID一致,你检查一下你连接mqtt的方法是不是用同一个id
2021-09-17 09:22
yaodaren

yaodaren

我好像误导你了,收到重复消息不是因为订阅或者发布了多次,这些不影响。而是因为mqttClient.on('message', function(topic, message) {}); 这个接收消息的方法调用几次,消息就重复几次。页面初始化的时候创建该方法,页面关闭后再进来相当于又创建了一次(消息从始至终都只发了一次,不懂为啥接收消息的代码跑了多次),mqttClient是我把mqtt相关连接封装到js里面的一个公共客户端。
2021-09-16 19:46
1***@163.com

1***@163.com

大佬,再请教下,在本地自己开服务能接收到。ping服务端也能ping通,但是一直提示重连是什么原因
2021-09-16 18:20
yaodaren

yaodaren

回复 小菜啊 :
mqtt.js里面好像只有一个end()方法关闭客户端,我用这个之后,再connect重新连接就报错了
2021-09-16 16:51
小菜啊

小菜啊 (作者)

回复 1***@163.com :
一样的,接收方==客户端 发送方 == 服务端 ,你客户端只要能ping通客户端,订阅消息后就能接收到,也就是说 客户端网址为 : www.mqtt_client.com:8080,服务端mqtt接口地址为:www.mqtt_service.com:18083,只要客户端订阅了www.mqtt_service.com:18083就能接到消息
2021-09-16 11:57
1***@163.com

1***@163.com

你好,这个不在同一网络下怎么接收消息,业务真实场景下,发送的和接收不在一个网络里
2021-09-16 11:28
小菜啊

小菜啊 (作者)

回复 yaodaren :
那你取消订阅后尝试一下断开链接试试 disconnect()
2021-09-16 10:19