nodejs 使用 mqtt 实现与web端通信
mqtt.js
mosca 下载不成功时,先npm i node-gyp ,还报错的话,把nodemodules报错文件内的 抛出异常删掉
const mosca = require("mosca");
const MqttServer = new mosca.Server(
{
port: 1883,
http:{
port: 3000,
}
},
);
MqttServer.on("clientConnected", function (client) {
//当有客户端连接时的回调.
console.log("client connected", client.id);
});
/**
* 监听MQTT主题消息
* 当客户端有连接发布主题消息时
**/
MqttServer.on("published", function (packet, client) {
var topic = packet.topic;
switch (topic) {
case "temperature":
// console.log('message-publish', packet.payload.toString());
//MQTT可以转发主题消息至其他主题
//MqttServer.publish({ topic: 'other', payload: 'sssss' });
break;
case "other":
console.log("message-123", packet.payload.toString());
break;
}
});
MqttServer.on("ready", function () {
//当服务开启时的回调
console.log("mqtt is running...");
});
publish.js
const mqtt = require("mqtt");
const client = mqtt.connect("mqtt://127.0.0.1:1883"); //连接到mqtt服务端
//写个定时器定时每隔3秒定时推送天气信息,此业务可替换为自己的实际需求
setInterval(function () {
const value = Math.ceil(Math.random() * 40);
let str='web端,你听到了吗'
client.publish("/nodeserver", JSON.stringify(str), { qos: 0, retain: true });
}, 3000);
subscribe.js
const mqtt = require("mqtt");
// const mqtt = require('./node_modules/mqtt/dist/mqtt.min.js')
const client = mqtt.connect("mqtt://127.0.0.1:1883"); //指定服务端地址和端口
client.on("connect", function() {
console.log("服务器连接成功");
// connected = client.connected
client.subscribe("/clientSend", { qos: 1 }); //订阅主题为test的消息
});
client.on("message", function(top, message) {
console.log("当前topic:", top);
console.log("客户端的内容", message.toString());
});
web端
//"_from": "paho-mqtt@^1.1.0",
import Paho from 'paho-mqtt';
//初始化mqtt
var that = this;
let client = new Paho.Client('127.0.0.1', 3000, uuid.v4());
console.log('client', client.connect);
client.onConnectionLost = function (responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
};
client.onMessageArrived = function (message) {
for (let item of that.mqttCallback.entries()) {
const any: any = item[1];
any && any(message.topic, message.payloadString);
}
};
client.connect({
onSuccess: function () {
that.mqttConnect = true;
console.log('mqtt on connect');
that.subscribeArr.forEach(item => {
that.mqttClient.subscribe(item);
})
},
onFailure: function (e) {
console.log('e', e);
console.log('失败了',);
},
useSSL: false
});
this.mqttClient = client;
//订阅、监听topic
this.props.appStore.mqttSubscribe(`/nodeserver`);
var that = this;
let mqttOut = this.props.appStore.mqttRegisterCallback(function (topic, payloadString) {
let result = JSON.parse(payloadString);
console.log('topic', topic);
console.log('result', result);
//给服务器发送信息
that.sendFnc()
})
sendFnc = () => {
let str = 'OK,我听到了'
this.props.appStore.mqttSend(`/clientSend`, str)
}
部署代码块
const mosca = require("mosca");
const MqttServer = new mosca.Server(
{
port: 1883,
http:{
port: 3000,
}
},
);
MqttServer.on("clientConnected", function (client) {
//当有客户端连接时的回调.
console.log("client connected", client.id);
});
/**
* 监听MQTT主题消息
* 当客户端有连接发布主题消息时
**/
MqttServer.on("published", function (packet, client) {
var topic = packet.topic;
var message = packet.payload.toString();
console.log('topic',topic);
console.log('message',message);
if(topic.indexOf('tell')>=0){
setTimeout(() => {
MqttServer.publish({ topic: '/reTell', payload: '好的,链接上就行!' });
}, 500)
}
if(topic.indexOf('chat')>=0){
setTimeout(() => {
MqttServer.publish({ topic: '/reTell', payload: '好啊'+message });
}, 500)
}
});
MqttServer.on("ready", function () {
//当服务开启时的回调
console.log("mqtt is running...");
});
import * as React from 'react';
import { AppStore } from "../../stores/AppStore";
import { inject, observer } from "mobx-react";
import {
Form,
Row,
Col,
Card,
Select,
Collapse,
Descriptions,
Input,
Button,
message,
InputNumber
} from 'antd';
import { FormComponentProps } from "antd/lib/form/Form";
import Paho from 'paho-mqtt';
import uuid from 'node-uuid';
interface PermitMgrProps extends FormComponentProps {
appStore?: AppStore,
type?: number
}
@inject('appStore')
@observer
class PermitMgr extends React.Component<PermitMgrProps, any> {
constructor(props) {
super(props);
this.btnRef = React.createRef();
this.state = {
ChatDataArr: [],
}
}
mqttClient = null
mqttCallback = new Map();
btnRef = null;
async componentDidMount() {
this.initMqttPound()
let mqttId = this.mqttRegisterCallback((topic, message) => {
console.log('topic', topic);
console.log('message', message);
this.setState({ ChatDataArr: [...this.state.ChatDataArr, { msg: message, type: 'server' }] })
setTimeout(() => {
const box = document.querySelector('.info-box');
let num = box.scrollHeight - box.clientHeight
console.log('box', box);
console.log('num', num);
box.scrollTo(0, num + 20);
}, 0)
})
}
mqttRegisterCallback = (callback) => {
let id = uuid.v1();
this.mqttCallback.set(id, callback);
return id;
}
initMqttPound = () => {
var that = this;
let client = new Paho.Client('127.0.0.1', 3000, uuid.v4());
client.onConnectionLost = function (responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
console.log('%c服务重连中……', 'font-size:50px;text-shadow:0 0 5px #f00');
that.initMqttPound()
}
};
client.onMessageArrived = function (message) {
for (let item of that.mqttCallback.entries()) {
const any: any = item[1];
any && any(message.topic, message.payloadString);
}
};
client.connect({
onSuccess: function () {
console.log('%c服务已连接!', 'font-size:50px;text-shadow:0 0 5px #0f0');
client.subscribe('/reTell');
var message = new Paho.Message('我链接上了啊!');
message.destinationName = '/tell';
that.setState({ ChatDataArr: [...that.state.ChatDataArr, { msg: '我链接上了啊!', type: 'web' }] })
client.send(message);
},
onFailure: function (e) {
console.log('%c服务重连中……', 'font-size:50px;text-shadow:0 0 5px #f00');
that.initMqttPound()
},
useSSL: false
});
this.mqttClient = client;
}
send = () => {
let value = this.btnRef.current.state.value
var message = new Paho.Message(value);
message.destinationName = '/chat';
this.mqttClient.send(message);
this.setState({ ChatDataArr: [...this.state.ChatDataArr, { msg: value, type: 'web' }] })
this.btnRef.current.state.value = ''
setTimeout(() => {
const box = document.querySelector('.info-box');
let num = box.scrollHeight - box.clientHeight
console.log('box', box);
console.log('num', num);
box.scrollTo(0, num + 20);
}, 0)
}
render() {
const { form } = this.props;
const { ChatDataArr } = this.state;
const { getFieldDecorator } = form;
return (
<Card bordered={false} className="promotion-channel">
<div style={{ width: '80%', marginLeft: '10%', padding: 20 }}>
<div style={{ width: 800, height: 300, border: '1px solid #ccc', overflowY: 'auto', padding: 20 }} className='info-box'>
{ChatDataArr && ChatDataArr.map(k =>
<div style={k.type == 'web' ? {} : { textAlign: 'right' }}>{k.msg}</div>
)}
</div>
<Input.TextArea ref={this.btnRef} onPressEnter={this.send} />
<Button className="add-button permitMgr_3" icon='search' type="primary" onClick={this.send} >发送</Button>
</div>
</Card>
)
}
}
export default Form.create<PermitMgrProps>()(PermitMgr);