使用 nodejs 快速搭建 MQTT 服务器及实时推送、获取数据


本文首发于个人网站,永久地址:[https://iiter.cn/blogs/13](https://iiter.cn/blogs/13) 点进去给几个访问量也行啊
github 仓库源代码:[github](https://github.com/isnl/mqtt-server)

@[toc]
### MQTT 的概念

> MQTT(Message Queue Telemetry Transport,翻译成中文为消息队列遥测传输)是 ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP 协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。<br>
> MQTT 是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT 协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

看到这,我们可能或许大概已经明白,MQTT 这货就是个通信协议,且被广泛应用在 M2M、IoT、智能家居等环境中。下面这张图,可以让我们更清楚的了解它具体的应用场景
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9hZTAxLmFsaWNkbi5jb20va2YvVWJjYjllMTFjMzcxYjQxNmE4MWM2OTViMWQ2M2Y0ZDliRC5wbmc?x-oss-process=image/format,png)

### 和其他传输协议的区别

看到这里就有人想不明白了,MQTT 既然也是一个基于客户端-服务器的消息发布/订阅传输协议,那么它和我们平常所使用的 websocket 有什么区别呢?
借用百度物联网产品经理的知乎回答:

两者的应用场景不一样:

- MQTT 是为了物联网场景设计的基于 TCP 的 Pub/Sub 协议,有许多为物联网优化的特性,比如适应不同网络的 QoS、层级主题、遗言等等。
- WebSocket 是为了 HTML5 应用方便与服务器双向通讯而设计的协议,HTTP 握手然后转 TCP 协议,用于取代之前的 Server Push、Comet、长轮询等老旧实现。两者之所有有交集,是因为一个应用场景:如何通过 HTML5 应用来作为 MQTT 的客户端,以便接受设备消息或者向设备发送信息,那么 MQTT over WebSocket 自然成了最合理的途径了。

### MQTT 客户端的语言支持

- Java
- Javascript
- C/C++
- Python
- Ruby
- Objective-C

### 搭建基于 nodejs 的 MQTT 服务器

#### 创建服务端

1.先从初始化一个 ==package.json== 开始。

```bash
npm init
```

2.安装 mqtt 服务器必要依赖项 ==mosca== ==mqtt==

```bash
npm install mosca mqtt
```

3.根目录下创建 ==mqtt.js== 文件,写入以下内容,创建 mqtt 简易服务器。

```javascript
const mosca = require("mosca");
const MqttServer = new mosca.Server({
port: 1883
});
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== 推送文件,写入以下内容:

```javascript
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);
client.publish("temperature", value.toString(), { qos: 0, retain: true });
}, 3000);
```

#### 创建客户端接收

根目录下创建 ==subscribe.js== 接收文件,写入以下内容:

```javascript
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("temperature", { qos: 1 }); //订阅主题为test的消息
});
client.on("message", function(top, message) {
console.log("当前topic:", top);
console.log("当前温度:", message.toString());
});
```

#### 测试功能

1.启动服务端 ==mqtt.js==
根目录下命令行输入 node mqtt.js/node mqtt 运行服务端,启动成功出现以下信息:
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9hZTAxLmFsaWNkbi5jb20va2YvVTE5MTAwZWMyNWUyZTRjOTBiYTFlMGEzOGU2MDYwNmU3Yi5wbmc?x-oss-process=image/format,png)

<!-- ![](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZzA0LnNvZ291Y2RuLmNvbS9hcHAvYS8xMDA1MjAxNDYvODcyOTgxMDdGNDEyOUYwNTc1RkNCMkNEQ0EyNUNFNkQ?x-oss-process=image/format,png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hIsGxlbH-1575468975915)(https://shop.io.mi-img.com/app/shop/img?id=shop_87298107f4129f0575fcb2cdca25ce6d.png)]
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9ncmFwaC5iYWlkdS5jb20vcmVzb3VyY2UvMTE2NDQxMWYwNzFiODQ1MDAyYTFhMDE1NzU0NjQ0ODEuanBn?x-oss-process=image/format,png)
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZS5zdW5pbmcuY24vdWltZy9aUi9zaGFyZV9vcmRlci8xNTc1NDY0NDg0NzQ3NjgyMzQuanBn?x-oss-process=image/format,png)
![](https://imgconvert.csdnimg.cn/aHR0cDovL3lhbnh1YW4ubm9zZG4uMTI3Lm5ldC9hOTMwMzQyNGYzMWQ2YmZkNDEwODk2ZGMyNWI0MTdlZi5wbmc?x-oss-process=image/format,png) -->

2.启动推送客户端 ==publish.js==
根目录下命令行输入 node publish.js/node publish 运行推送客户端 3.启动接收客户端 ==subscribe.js==
根目录下命令行输入 node subscribe.js/node subscribe 运行接收客户端,不出意外,控制台将会每隔 5 秒打印以下信息:
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9hZTAxLmFsaWNkbi5jb20va2YvVWFjOTE0MWUwYWQzMTQ2ZDJiYjg4NjA2OWJmMDU2YmU3Si5naWY)

<!-- ![](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZzAxLnNvZ291Y2RuLmNvbS9hcHAvYS8xMDA1MjAxNDYvNjZBRTMxNjRCOEY3Mzc5QTNCNjZBQ0VDODgxQTZDQzE?x-oss-process=image/format,png)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XXcXGAo5-1575468975922)(https://shop.io.mi-img.com/app/shop/img?id=shop_66ae3164b8f7379a3b66acec881a6cc1.gif)]
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9ncmFwaC5iYWlkdS5jb20vcmVzb3VyY2UvMTE2ZjcwMmE1NThlNzQzY2MxM2FmMDE1NzU0NjUyNjMuanBn?x-oss-process=image/format,png)
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZS5zdW5pbmcuY24vdWltZy9aUi9zaGFyZV9vcmRlci8xNTc1NDY1MjY0OTY1MzU1MTAuanBn?x-oss-process=image/format,png)
![](https://imgconvert.csdnimg.cn/aHR0cDovL3lhbnh1YW4ubm9zZG4uMTI3Lm5ldC9kOTg5OWYwNWM3OTBjZjFhOWYwZTJkZTNhODVjNDg4NC5naWY) -->

至此,一个基于 nodejs 的简易 mqtt 服务器就搭建完成了。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM