Sever.on监听的事件何时回调
这次的demo和之前用的相同的代码,但是控制台打印的不一样,因此写一个笔记记录下在测试连接通信以及测试 on 方法时,发现的一些现象。
先给出broker的代码:
js
const mosca = require("mosca");
const MqttServer = new mosca.Server({
port: 1883,
id: "ZZK", //固定我们服务器的ID
});
// 监听客户端连接事件
MqttServer.on("clientConnected", (client) => {
console.log(`Client connected: ${client.id}`);
});
// 监听客户端断开事件
MqttServer.on("clientDisconnected", (client) => {
console.log(`Client disconnected: ${client.id}`);
});
// 监听 MQTT 消息发布事件
MqttServer.on("published", (packet, client) => {
console.log(
`Published: topic: ${packet.topic} || message: ${packet.payload.toString()}`
);
});
// 监听 Mosca 服务器就绪事件
MqttServer.on("ready", () => {
console.log("Mosca server is up and running");
});
在这里,我们主要监听了3个事件,客户端的连接和断开、以及broker发送消息
client_test1 代码:
js
const mqtt = require("mqtt");
const url = "mqtt://localhost:1883";
const options = {
clientId: "test1"
};
// 连接到本地 MQTT 服务器
const client = mqtt.connect(url, options);
// 监听连接事件
client.on("connect", () => {
console.log("Connected to MQTT server");
// 订阅一个主题(client_test2会发送这个主题的消息)
client.subscribe("test2/topic", (err) => {
if (!err) {
console.log("test1 订阅test2/topic成功");
}
});
//这个主题是 broker 默认给出的,ZZK 代表我们服务器的id,# 为通配符,其余的字段固定
client.subscribe("$SYS/ZZK/new/#", (err) => {
if (!err) {
console.log("test1 订阅$SYS/ZZK/new/#成功");
}
});
});
// 监听消息到达事件
client.on("message", (topic, message) => {
console.log(`Received message on topic ${topic}: ${message.toString()}`);
});
client_test2 代码:
js
const mqtt = require("mqtt");
const url = "mqtt://localhost:1883";
const options = {
clientId: "test2",
};
// 连接到本地 MQTT 服务器
const client = mqtt.connect(url, options);
client.on("connect", () => {
// 订阅一个主题(这里主要是来测试 broker是否会发送消息)
client.subscribe("test1/topic", (err) => {
if (!err) {
console.log("test2 订阅test1/topic成功");
}
});
console.log("Connected to Mosca server");
setInterval(() => {
client.publish("test2/topic", "This is test2 publish");
console.log("Message sent to test2/topic");
}, 10000); // 10 秒
});
至此,我们的 broker、client1、client2 就编写好了。
主要的逻辑如下:
client1 订阅两个主题(test2/topic 与 $SYS/ZZK/new/#)
client2 订阅一个主题(test1/topic),并每个10s 发送主题为 test2/topic 的消息
client1 控制台会打印接收到的所有消息,格式为Received message on topic 主题:消息
broker会打印其发出去的消息,格式为Published: topic: 主题|| message: 消息
我们的测试流程如下: 首先启动broker,然后启动client1,再启动client2。当client2发布了几条消息后,关闭它,然后再启动它。 在broker控制台的打印:
bash
Mosca server is up and running
Client connected: test1
Published: topic: $SYS/ZZK/new/clients || message: test1
Published: topic: $SYS/ZZK/new/subscribes || message: {"clientId":"test1","topic":"test2/topic"}
Published: topic: $SYS/ZZK/new/subscribes || message: {"clientId":"test1","topic":"$SYS/ZZK/new/#"}
Client connected: test2
Published: topic: $SYS/ZZK/new/clients || message: test2
Published: topic: $SYS/ZZK/new/subscribes || message: {"clientId":"test2","topic":"test1/topic"}
Published: topic: test2/topic || message: This is test2 publish
Client disconnected: test2
Published: topic: $SYS/ZZK/new/unsubscribes || message: {"clientId":"test2","topic":"test1/topic"}
Published: topic: $SYS/ZZK/disconnect/clients || message: test2
Client connected: test2
Published: topic: $SYS/ZZK/new/clients || message: test2
Published: topic: $SYS/ZZK/new/subscribes || message: {"clientId":"test2","topic":"test1/topic"}
Published: topic: test2/topic || message: This is test2 publish
Client disconnected: test2
Published: topic: $SYS/ZZK/new/unsubscribes || message: {"clientId":"test2","topic":"test1/topic"}
Published: topic: $SYS/ZZK/disconnect/clients || message: test2
Client disconnected: test1
Published: topic: $SYS/ZZK/new/unsubscribes || message: {"clientId":"test1","topic":"test2/topic"}
Published: topic: $SYS/ZZK/new/unsubscribes || message: {"clientId":"test1","topic":"$SYS/ZZK/new/#"}
Published: topic: $SYS/ZZK/disconnect/clients || message: test1
我们可以看到:
- 当有client连接broker的时候,broker会自动发送一条
topic
为$SYS/brokerID/new/clients
的message
:clientId
。而如果客户端client_X
订阅了某个主题topic_x
。那么broker还会自动发送一条topic
为$SYS/brokerID/new/subscribes
的message
:{"clientId":"client_X","topic":"topic_x"}
。取消订阅也是如此。以上是broker自动发送的。 - 当client向broker发送消息的时候,broker会自动将其转发(这个是必然的)。
- 当client取消订阅时,broker会自动发送一条
topic
为$SYS/brokerID/new/unsubscribes
的message
, 与订阅时的格式一样,就是主题换了。同理,当client下线时也是如此。
这些就自动发送的消息就可以帮助我们知道client的一些行为,从而进行一些处理。
为了验证是否是由broker发送的,我们的client_test1的代码因此就订阅了$SYS/ZZK/new/#
主题,同时通过将client_test2
上线下线查看clien_test1
控制台的输出:
bash
Connected to MQTT server
Received message on topic $SYS/ZZK/new/subscribes: {"clientId":"test1","topic":"test2/topic"}
test1 订阅test2/topic成功
Received message on topic $SYS/ZZK/new/subscribes: {"clientId":"test1","topic":"$SYS/ZZK/new/#"}
test1 订阅$SYS/ZZK/new/#成功
Received message on topic $SYS/ZZK/new/clients: test2
Received message on topic $SYS/ZZK/new/subscribes: {"clientId":"test2","topic":"test1/topic"}
Received message on topic test2/topic: This is test2 publish
Received message on topic $SYS/ZZK/new/unsubscribes: {"clientId":"test2","topic":"test1/topic"}
Received message on topic $SYS/ZZK/new/clients: test2
Received message on topic $SYS/ZZK/new/subscribes: {"clientId":"test2","topic":"test1/topic"}
Received message on topic test2/topic: This is test2 publish
Received message on topic $SYS/ZZK/new/unsubscribes: {"clientId":"test2","topic":"test1/topic"}
从这里我们可以看到,client_test1
不仅仅接收到了client_test2
发送的topic为test2/topic
的消息:This is test2 publish
,还接收到了 topic
为 $SYS/ZZK/new/subscribes
、$SYS/ZZK/new/clients
的消息。这些就是broker自动发送的。
因此我们可以知道,server.on(Event)
方法是当broker去执行这些event的时候才会触发。且由于broker自带的一些回调函数,除了会执行我们编写的回调函数外,还会相应的自动去发送一些特定主题的消息。