import mqtt from 'mqtt'
import MQTTConnect from '../../assets/js/MQTTConnect'
created: function () { this.userAgent = localStorage.getItem('devUserAgent') this.loadConnect() ------>加载默认配置信息 },
computed: { getStatus () { if (this.client.connected) { console.log('已连接') return '已连接' } if (this.loading) { return '正在连接...' } return '连接已断开' }, supportWebSocket () { return window.WebSocket } },
mounted: function () { this.initWVBridge() this.getWebVersion() this.getUserInfo() this.getDevInfo() this.getLocation() this.formateDateTime = this.formatDate(this.creatTime) this.mqttConnect()------->客户端接收消息 var self = this setTimeout(function () { self.subTopic = '/xxx/' + self.xwNum self.mqttSubscribe()------客户端接收订阅信息 }, 500) //localStorage.storageWebVersion = '2.1' // /iot/fise/in/Car // {"type": 1,"data": {"lng": "113.989822","lat": "22.681385","from_type": 1}} // from_type = 0-GPS定位 1-基站定位 2-WIFI定位 // {"type": 3,"data": {"battery":100,"mileage":1388,"defend":false,"work":true,"speed":300,"voltage":421,"status":{"control_error":false,"switch_error":false,"brake_error":false,"system_error":true}}} },
getWebVersion () { var self = this webVersion({ app_key: localStorage.storageAppKey, app_dev: localStorage.storageAppDev }).then(function (res) { if (res.data.error_code === 0) { self.newVersion = res.data.h5_version; if (localStorage.storageWebVersion) { //判断当前页面是否是新版本,如果是新版本清理webview缓存 //console.log(localStorage.storageWebVersion + ',' + self.newVersion) if (localStorage.storageWebVersion != self.newVersion) { //self.logInfo = '发现新版本:' + localStorage.storageWebVersion + ',' + self.newVersion if (self.userAgent == 'android') { //调用安卓函数清除webview缓存数据 window.android.jsCall_CleanCache() localStorage.storageWebVersion = self.newVersion; } else if (self.userAgent == 'ios') { //调用ios函数清除webview缓存数据 connectWebViewJavascriptBridge(function (bridge) { bridge.callHandler('jsCall_cleanWebViewCache', {}, function (response) { }) }) localStorage.storageWebVersion = self.newVersion; } } else { //self.logInfo = '已是最新版本:' + localStorage.storageWebVersion + ',' + self.newVersion localStorage.storageWebVersion = self.newVersion; } } else { localStorage.storageWebVersion = self.newVersion; } } }).catch(function (error) { if (error.message === 'Network Error') { Toast({ message: '网络异常', duration: 2000 }) } }) },
initWVBridge () { if (this.userAgent === 'ios') { // 联系xxx document.getElementById('contactDevBtn2').onclick = function () { connectWebViewJavascriptBridge(function (bridge) { bridge.callHandler('jsCall_ContactDev', {}, function (response) { }) }) } // 返回Appxxx页面 document.getElementById('jsCallGoBack2').onclick = function () { connectWebViewJavascriptBridge(function (bridge) { bridge.callHandler('jsCall_go_back', {}, function (response) { }) }) this.mqttDisconnect() } } else if (this.userAgent === 'android') { // 联系xxx document.getElementById('contactDevBtn2').onclick = function () { window.android.jsCall_ContactDev() } // 返回App xxx页面 document.getElementById('jsCallGoBack2').onclick = function () { window.android.jsCall_go_back() this.mqttDisconnect() } } },
// mqtt Websocket disconnectSwitch () { // connecting if (this.loading && !this.client.connected) { this.loading = false this.client.end() this.client = {} } else { this.mqttDisconnect() } }, mqttConnect () { if (!this.supportWebSocket) { console.log('不支持webSocket') return } // 防止通过键盘事件连接 if (this.client.connected || this.loading) { return } this.loading = true this.retryTimes = 0 const options = {-------->加上鉴权auth信息,否则知道IP就可以connect mqtt不安全 keepalive: this.keepalive, username: this.username, password: this.password, clientId: this.clientId, clean: this.clean, connectTimeout: 4000 } const protocol = this.isSSL ? 'wss' : 'ws' this.client = mqtt.connect(`${protocol}://${this.host}:${this.port}/mqtt`, options)--------->var client2 = mqtt.connect("mqtt://192.168.1.136:8000"); this.client.on('connect', () => { this.loading = false }) this.client.on('reconnect', () => { if (this.retryTimes > 1) { if (this.sending) { console.log('连接错误') } else { console.log(`${'连接失败'} ${this.host}:${this.port}`) } this.retryTimes = 0 this.sending = false this.loading = false this.client.end() this.client = {} } // 发送不合法的主题触发 if (this.sending) { console.log('连接错误') } this.retryTimes += 1 }) this.client.on('error', (error) => { console.log(error) // 防止重复连接 this.retryTimes = 0 }) // -------- // 接收消息 this.client.on('message', (topic, message, packet) => {---------->client2.on('message',function(top,message) { console.log(message.toString()); }); /* this.receivedMessages.unshift({ topic, message: message.toString() }) */ console.log('信息已接收') var msgInfo = JSON.parse(message) this.receivedMessages = msgInfo console.log(msgInfo) var self = this if (msgInfo.type === 1) { self.setMap(msgInfo.data.lng, msgInfo.data.lat) } else if (msgInfo.type === 2) { self.electricizeStatus = msgInfo.data.event_key } else if (msgInfo.type === 3) { self.batteryVal = msgInfo.data.battery self.totleMileage = msgInfo.data.mileage self.preventStatus = msgInfo.data.defend self.startStatus = msgInfo.data.work self.voltageVal = msgInfo.data.voltage / 10 self.speedVal = msgInfo.data.speed / 10 localStorage.storageCarErrorInfo = JSON.stringify(msgInfo.data.status) } }) }, mqttDisconnect () { if (this.client.connected) { this.client.end() this.client.on('close', () => { this.loading = false this.reset() this.client = {} }) } else { console.log('连接已断开') } }, mqttSubscribe () { if (this.client.connected) { this.subscriptions.forEach((x, index) => { if (x.topic === this.subTopic) { this.subscriptions.splice(index, index + 1) } }) this.client.subscribe(this.subTopic, (error) => {------> client2.subscribe('test',{qos:1});//订阅主题为test的消息 if (error) { console.log(error.toString()) } else { this.subscriptions.unshift({ topic: this.subTopic }) console.log('订阅成功') } }) } else { console.log('连接已断开') } }, mqttCacheScuscribe (topic) { if (!this.client.connected) { console.log('连接已断开') return } this.client.unsubscribe(topic, (error) => { if (error) { console.log('取消订阅失败') return } this.subscriptions.forEach((element, index) => { if (element.topic === topic) { this.subscriptions.splice(index, 1) // clear message which in this topic } }) }) },
reset () { this.subscriptions = [] this.receivedMessages = [] this.subTopic = '/xxx/' + this.xwNum }, loadConnect () { console.log(MQTTConnect.options) if (MQTTConnect.client && MQTTConnect.client.connected) { this.client = MQTTConnect.client Object.keys(MQTTConnect.options).forEach((item) => { this[item] = MQTTConnect.options[item] }) } }, stashConnect () { MQTTConnect.client = this.client console.log(MQTTConnect.options) Object.keys(MQTTConnect.options).forEach((item) => { MQTTConnect.options[item] = this[item] }) } }
MQTTConnect.js:
export default { client: {}, options: { host: '', port: 8083, username: '', isSSL: false, password: '', keepalive: 60, clean: true, clientId: '', subQos: 0, publishQos: 0, publishMessage: 'Hello world!', subTopic: '/World', publishTopic: '/World', publishRetain: false, receivedMessages: [], publishedMessages: [], subscriptions: [], }, }
https://blog.csdn.net/swimming_in_it_/article/details/78017624
nodejs中搭建mqtt
使用nodejs编写一个简单的服务器,然后在编写两个客户端,一个客户端用来接收消息,另一个客户端用来发送消息:
服务器代码为:不过,你第一次运行的时候,会缺少mosca模块,自己npm install mosca即可。具体功能,学过编程的大致都能看懂,然后里面都有注释。
- var mosca = require('mosca');//构建服务器
- /*var settings = {
- port:8989,
- backend:{
- type:'zmq',
- json:false,
- zmq:require("zmq"),
- port:"tcp://127.0.0.1:33334",
- controlPort:"tcp://127.0.0.1:33334",
- delay:5
- },
- persistence: {
- factory:mosca.persistence.Mongo,
- url:"mongodb://localhost:270117/mosca"
- }
- };
- var MqttServer = new mosca.Server(settings);*/
- var MqttServer = new mosca.Server({
- port:8000
- });
- //监听链接
- 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;
- case 'test2':
- console.log("payload:",packet.payload.toString());
- var msg = {
- topic:'repeat',
- payload:packet.payload,
- qos:0,
- retain:false
- };
- MqttServer.publish(msg,function() {
- console.log('repeat! ');
- });
- break;
- case 'other':
- console.log("case-other:",packet.payload.toString());
- break;
- }
- });
- MqttServer.on('ready',function() {
- console.log("mqtt is running....");
- });
发送消息客户端:
- var mqtt = require('mqtt');
- var client = mqtt.connect('mqtt://192.168.1.136:8000');//连接到服务端
- var num = 0;
- var qtt = {};//定义消息(可以为字符串,对象等)
- qtt.aa = '发布';
- qtt.bb = '消息!';
- setInterval(function() {
- //发布主题为Test的消息
- client.publish('test',JSON.stringify(qtt),{qos:1,retain:true});//hello mqtt + num++
- },1000);
- var mqtt = require('mqtt');
- var client2 = mqtt.connect("mqtt://192.168.1.136:8000");
- client2.subscribe('test',{qos:1});//订阅主题为test的消息
- client2.on('message',function(top,message) {
- console.log(message.toString());
- });
https://blog.csdn.net/u011216417/article/details/69666752
https://blog.csdn.net/wangshuminjava/article/details/80578109
几个MQTT的知识点
开始正文前需要感谢一下网友“小龙”和emqtt.io群里的网友们的帮助,本人刚刚开始使用MQTT有很多不懂的地方,在emqtt.io群里询问解决方法的时候,“小龙”给我详细的讲解了一些MQTT的知识点并提供了解决方案,甚是感谢。本人觉得里面提到的一些东西对初学者还是很有用的,因此,在这里把我与“小龙”的聊天记录整理一下供大家参考。
问题一:单片机缓存有限,处理能力有限的情况下,消息不可能一次发出,这种情况下要怎样通过MQTT发布消息?
先组装publish协议的头,里面写好payload的长度,通过tcp发出去,然后一点一点发payload。如果拿不到payload总长度,这个事情就难办。因为你发了一个publish协议报,服务端读到head里面的payload的长度之后,就会一直读,读到需要的长度,才算这个publish结束。所以,你的需求是首先确认你发布的内容的长度,然后组publish数据包头,填写payload长度,tcp:send(head),之后一段一段发送payload,比如一次1k,还是按照正常的tcp发送数据,一直发送完毕,就算这个publish结束了。接下来的send,都属于tcp层的,这些不用你干预的。如果在tcp层,send失败,那一定是socket有问题了,连接断了,你就得重新连接mqtt服务器了,如果没有发完,那么服务端的会话也会结束,就是说服务端也没有接收到数据。重新连接,你就得重发,发送消息中途,只要断掉,就得重连,是否要重发数据,取决于你是否保存了以前的数据。还有如果消息重要,可以使用qos=1或者2,可以确保服务端收到消息,qos=1需要一个来回,qos=2需要四个来回,qos=0非常简单,只要send出去就不管了。
问题二:MQTT的开源资源多吗?
http://www.mqtt.org里面很多
问题三:MQTT为什么一般不提供持久化的功能
mqtt协议里面是按照设备一直在线设计的,数据都是保存在内存里的
问题四:MQTT是不是很耗内存?
MQTT是比较吃内存的,emqtt的实测数据是:38W,内存占14G,CPU 15%
问题五:session与client之间的关系是怎样的?
这样的,比如你一个板子,作为客户端,发起mqtt的连接请求connect到mqtt服务器,比如说就是emqtt服务吧,emqtt服务端收到这个板子的连接请求之后,在tcp层上会和板子建立一个tcp的连接,在emqtt内部,会产生一个进程,和这个板子做数据通讯,同时还会产生一个进程,叫session,这个sessoin是专门管理这个板子订阅的主题,其它板子如果发布了这个板子感兴趣的主题的时候,也会发到这个板子对应的这个session里面,如果这个session收到订阅的主题之后,发现对用的client还活着,就通过这个client把数据经过tcp发到这个板子上,如果发现client已经没有了,就是说板子和服务端断掉了,那么session就会把收到的订阅的主题,先保存在session里面,下次板子连接上了,而且cleansession=false,那么这个session就不会清除,在这次连接时,就会把以前收到的订阅消息,发给板子,大概就是这个意思。
问题六:emqtt怎么知道连上来的client是同一个呢?
连接的时候,需要设置一个clientid,这个id可以不设置,如果不设置,在emqtt服务端会自动产生一个唯一的id,如果你要用到session,必须有一个唯一个id,你可以用imei。如果你一定要收到离线消息的话,就必须使用确定的id了。
问题七:emqtt的session时间可以修改吗?
你可以改一下session的时间,现在是48小时,你可以改为一周,如果要永久,恐怕emqtt不太适合。
问题八:emqtt的访问权限什么的都是写在配置文件里的?
etc/acl.config
问题九:emqtt的分布式是怎么回事?
分布式简单说就是把你的几台服务器连在一起,里面任意一台或者多台,只要不是全坏了,emqtt都可以正常运行。emqtt的数据是在几个节点共享的,某个节点出问题,数据是不会丢的,但是节点上的session数据会丢失。
使用nodejs编写一个简单的服务器,然后在编写两个客户端,一个客户端用来接收消息,另一个客户端用来发送消息:
服务器代码为:不过,你第一次运行的时候,会缺少mosca模块,自己npm install mosca即可。具体功能,学过编程的大致都能看懂,然后里面都有注释。
- var mosca = require('mosca');//构建服务器
- /*var settings = {
- port:8989,
- backend:{
- type:'zmq',
- json:false,
- zmq:require("zmq"),
- port:"tcp://127.0.0.1:33334",
- controlPort:"tcp://127.0.0.1:33334",
- delay:5
- },
- persistence: {
- factory:mosca.persistence.Mongo,
- url:"mongodb://localhost:270117/mosca"
- }
- };
- var MqttServer = new mosca.Server(settings);*/
- var MqttServer = new mosca.Server({
- port:8000
- });
- //监听链接
- 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;
- case 'test2':
- console.log("payload:",packet.payload.toString());
- var msg = {
- topic:'repeat',
- payload:packet.payload,
- qos:0,
- retain:false
- };
- MqttServer.publish(msg,function() {
- console.log('repeat! ');
- });
- break;
- case 'other':
- console.log("case-other:",packet.payload.toString());
- break;
- }
- });
- MqttServer.on('ready',function() {
- console.log("mqtt is running....");
- });
发送消息客户端:
- var mqtt = require('mqtt');
- var client = mqtt.connect('mqtt://192.168.1.136:8000');//连接到服务端
- var num = 0;
- var qtt = {};//定义消息(可以为字符串,对象等)
- qtt.aa = '发布';
- qtt.bb = '消息!';
- setInterval(function() {
- //发布主题为Test的消息
- client.publish('test',JSON.stringify(qtt),{qos:1,retain:true});//hello mqtt + num++
- },1000);
- var mqtt = require('mqtt');
- var client2 = mqtt.connect("mqtt://192.168.1.136:8000");
- client2.subscribe('test',{qos:1});//订阅主题为test的消息
- client2.on('message',function(top,message) {
- console.log(message.toString());
- });