云计算百科
云计算领域专业知识百科平台

we-mp-rss 内置 QtServer MQTT 服务器全指南:基于 aedes 的 TCP + WebSocket 双通道消息中枢

  • 后端
  • 网页爬虫
  • 前端

【免费下载链接】we-mp-rss

✨符合阅读习惯的微信公众号助手、微信公众号转MarkDown、微信公众号转PDF、定时更新订阅公众号文章、生成微信公众号RSS订阅源、导出微信公众号订阅源、支持微信公众号Webhook/微信公众号API/AI Agent接入微信公众号微信公众号、订阅微信公众号、微信公众号助手 、微信公众号阅读、微信公众号接口、微信公众号爬虫、微信公众号监测、标签订阅微信公众号、微信公众号源、微信公众号读书、微信公众号文章、微信公众号框架、微信公众号管理、微信公众号源、微信公众号平台、微信公众号代码、微信公众号系统、微信公众号源码

项目地址:
https://gitcode.com/gh_mirrors/we/we-mp-rss

点击查看 免费下载

本文是一份围绕 we-mp-rss 仓库 qtserver 目录的实战技术指南,系统讲解仓库内置的 Node.js MQTT 服务器的启动、配置、双协议客户端接入、WebSocket 消息 API 与源码级运行原理,并配套完整的自动化测试工具使用说明。读完本文,你将掌握如何在本地快速拉起一个同时支持标准 MQTT 3.1.1(TCP 1883)与浏览器 WebSocket(8083)的消息服务器,并能基于仓库源码理解其订阅发布、消息持久化与广播转发的底层实现。

一、项目定位:仓库里的“MQTT 助手”

qtserver/ 是 we-mp-rss 项目中一个独立、可单独部署的 Node.js 模块,其定位在仓库的 AGENTS.md 中被明确描述为 "MQTT helper",开发者可通过 npm install 与 npm run start 快速启动(见 AGENTS.md)。它不依赖主项目的 Python 后端,拥有独立的依赖声明与启动脚本,适合在需要实时消息推送、浏览器与设备间双向通信、任务状态广播等场景下作为消息中枢使用。

  • 协议层面:支持 MQTT 3.1.1(TCP)与 WebSocket 两种接入方式,浏览器客户端无需安装任何 MQTT 客户端库即可使用。
  • 架构层面:基于轻量级 MQTT Broker 库 aedes(^0.51.3)构建 TCP 服务,基于 ws(^8.18.0)构建 WebSocket 服务,客户端库 mqtt(^5.0.0)同时充当官方连接示例与测试工具(见 package.json)。
  • 功能层面:主题订阅/发布、心跳检测、多客户端管理、内存级消息持久化与历史回放一应俱全。

二、快速开始:三种方式拉起服务器

1. 安装依赖

进入模块目录安装 Node.js 依赖:

cd qtserver
npm install

依赖项包含三个运行时库与一个开发工具(见 package.json):

包名版本约束作用
aedes ^0.51.3 MQTT Broker 核心,负责 MQTT 3.1.1 协议的解析与会话管理
mqtt ^5.0.0 MQTT 客户端库,用于连接示例与测试脚本
ws ^8.18.0 WebSocket 实现,服务端与测试端均使用
nodemon ^3.1.7(dev) 开发模式自动重启

2. 启动服务器

官方提供三种启动方式(见 README.md):

# 方式1: 使用npm脚本(等价于 node mqtt-server.js)
npm start

# 方式2: 直接运行
node mqtt-server.js

# 方式3: 使用批处理文件(Windows)
start.bat

其中 start.bat 会在启动前自动完成三件事:校验 Node.js 是否安装(缺失时报错退出)、检查 node_modules 是否存在(不存在则自动执行 npm install)、最后启动 mqtt-server.js。若日常开发需要热重载,package.json 还提供了 npm run dev(等价于 nodemon mqtt-server.js)。

启动成功后控制台会输出两条监听信息:

MQTT服务器监听端口 1883
WebSocket MQTT服务器监听端口 8083

3. 可选环境变量配置

服务器在实例化时读取环境变量作为端口配置(对应源码 mqtt-server.js):

# MQTT端口(默认1883)
export MQTT_PORT=1883

# WebSocket端口(默认8083)
export WS_PORT=8083

端口说明:MQTT 端口 1883 是标准 MQTT 协议端口,供各类 MQTT 客户端通过 TCP 直连;WebSocket 端口 8083 供浏览器等 Web 客户端建立 ws:// 连接。两个端口独立监听,互不影响。

三、双协议客户端接入示例

3.1 标准 MQTT 客户端(Node.js / 嵌入式设备)

使用 mqtt 客户端库连接 1883 端口,即可完成订阅、发布与消息接收(示例取自 README.md,可直接复制运行):

const mqtt = require('mqtt');

// 连接到MQTT服务器
const client = mqtt.connect('mqtt://localhost:1883');

client.on('connect', () => {
console.log('连接成功');

// 订阅主题
client.subscribe('test/topic');

// 发布消息
client.publish('test/topic', 'Hello MQTT!');
});

client.on('message', (topic, message) => {
console.log(`收到消息: ${topic} – ${message.toString()}`);
});

3.2 WebSocket 客户端(浏览器端)

浏览器直接使用原生 WebSocket 连接 8083 端口即可,无需引入任何依赖:

// 浏览器端JavaScript
const ws = new WebSocket('ws://localhost:8083');

ws.onopen = () => {
console.log('WebSocket连接成功');

// 订阅主题
ws.send(JSON.stringify({
type: 'subscribe',
topic: 'test/topic'
}));

// 发布消息
ws.send(JSON.stringify({
type: 'publish',
topic: 'test/topic',
payload: 'Hello from WebSocket!'
}));
};

ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'message') {
console.log(`收到消息: ${data.topic} – ${data.payload}`);
}
};

建立连接后服务器会首先推送一条 connected 消息(含服务器分配的 clientId),订阅成功后推送 suback,发布成功后推送 puback,业务消息以 message 类型下发——这些由服务端 handleWebSocketMessage 与连接回调保证(见 mqtt-server.js)。

四、WebSocket 消息协议详解

服务端对 WebSocket 帧统一按 JSON 解析,消息体必含 type 字段。以下是 README.md 定义的四类客户端请求:

type用途请求体
subscribe 订阅主题 { "type": "subscribe", "topic": "your/topic" }
unsubscribe 取消订阅 { "type": "unsubscribe", "topic": "your/topic" }
publish 发布消息 { "type": "publish", "topic": "your/topic", "payload": "your message" }
ping 心跳 { "type": "ping" }

对应的 JSON 示例(完整继承自原文档):

{
"type": "subscribe",
"topic": "your/topic"
}

{
"type": "unsubscribe",
"topic": "your/topic"
}

{
"type": "publish",
"topic": "your/topic",
"payload": "your message"
}

{
"type": "ping"
}

除上述请求外,服务端还会向下发送多种响应类型(源码可证,见 mqtt-server.js):

  • connected:连接建立成功后返回,携带服务器分配的 clientId(格式为 ws_时间戳_随机串);
  • suback / unsuback:订阅/取消订阅的确认回执,含 topic 与 success 字段;
  • puback:发布确认,含 topic 与 success 字段;
  • message:业务消息,含 topic、payload、timestamp、clientId(来源客户端);
  • pong:对 ping 心跳的应答;
  • error:JSON 解析失败等异常时返回,携带 message: "消息格式错误"。

其中 message 消息体中额外携带的 timestamp(ISO 8601 格式)与 clientId 字段,来自服务端持久化时的记录(见 mqtt-server.js)。

五、服务器管理

服务器启动后提供两种关闭方式(见 README.md 与 mqtt-server.js):

  • Ctrl+C:在终端前台运行时优雅关闭;
  • SIGINT / SIGTERM:进程信号关闭,适用于 kill 命令或容器化部署时的停止流程。

两种信号均注册了统一处理器:打印 "收到 SIGINT/SIGTERM 信号,正在关闭服务器…" 后依次执行 server.close()(TCP)、aedes.close()(MQTT Broker)、wsServer.close()(WebSocket),最后以退出码 0 结束进程(见 mqtt-server.js)。

六、故障排除

端口被占用

若 1883 或 8083 被占用,优先修改环境变量 MQTT_PORT / WS_PORT 重新指定端口;若需彻底改端口,也可直接修改 mqtt-server.js 中的默认值。注意修改源码后 WebSocket 客户端连接地址与 MQTT 客户端连接地址需同步更新。

依赖安装失败

确保 Node.js 版本 >= 12.0.0(原文档声明的版本下限),并尝试清除 npm 缓存后重装:

npm cache clean –force
npm install

若仍失败,可检查网络对 npm registry 的连通性,或改用仓库中已生成的 yarn.lock 通过 yarn install 安装(该锁文件由 yarn v1 生成)。

七、源码级原理剖析:从连接建立到消息广播

本节基于 mqtt-server.js 深入讲解服务器内部工作机制,帮助读者理解为何 README 描述的功能都能成立。

7.1 双服务器模型与状态容器

MQTTServer 类构造时默认 port = 1883、wsPort = 8083,并初始化两个核心容器(mqtt-server.js):

  • this.clients(Map):以 client.id 为键,跟踪所有已连接的 MQTT 客户端;
  • this.topics(Map):以主题名为键,值为消息数组,实现内存级消息持久化。

7.2 TCP MQTT 服务的 aedes 集成

MQTT Broker 通过 aedes() 实例与 Node 原生 net 模块组合而成(mqtt-server.js):

this.aedes = aedes();
this.server = net.createServer(this.aedes.handle);

aedes.handle 是标准的 TCP 流处理器,负责完成 MQTT 3.1.1 协议握手、报文编解码与会话管理。围绕它注册了五个关键事件:

aedes 事件触发时机服务端行为
client 客户端完成连接 记录到 clients Map 并打印客户端 ID
clientDisconnect 客户端断开 从 clients Map 移除
publish 收到发布消息 持久化到 topics 并广播给订阅者
subscribe 客户端订阅主题 记录订阅并初始化对应主题的存储数组
unsubscribe 客户端取消订阅 打印取消日志
clientError 客户端协议异常 打印错误详情

值得注意的是,publish 处理器在广播前会把消息连同 timestamp、clientId 一起压入主题数组(mqtt-server.js),这正是“消息持久化存储”功能的实现来源。

7.3 WebSocket 服务的桥接设计

WebSocket 服务(mqtt-server.js)为每个连接对象附加了两个自定义属性:

  • ws.clientId:形如 ws_时间戳_9位随机串 的全局唯一标识;
  • ws.subscriptions:一个 Set,记录该浏览器客户端订阅的主题。

handleWebSocketMessage 按 data.type 分发处理(mqtt-server.js):

  • subscribe:加入 ws.subscriptions,回 suback,并立即重放该主题的历史消息——这是 WebSocket 客户端可以收到订阅前历史消息的关键机制;
  • unsubscribe:从 ws.subscriptions 删除并回 unsuback;
  • publish:持久化到 topics 后调用 broadcastMessage,再回 puback;
  • ping:回 pong 实现心跳应答;
  • default:打印未知消息类型告警。

7.4 跨协议广播:一次发布、两端送达

broadcastMessage(topic, payload, fromClientId)(mqtt-server.js)是服务器连通性的枢纽:

  • 调用 this.aedes.publish({ topic, payload, qos: 0 }),将消息注入 MQTT Broker,由 aedes 转发给所有订阅该主题的 TCP MQTT 客户端(QoS 固定为 0,即至多一次投递);
  • 遍历 wsServer.clients,向 readyState === OPEN 且 subscriptions 包含该主题、且非消息来源方(clientId !== fromClientId)的 WebSocket 客户端发送 message 帧。
  • 因此,MQTT 客户端发布的消息可以推送到浏览器端,反之亦然,实现了双协议客户端的消息互通。qos: 0 意味着消息不保证至少一次投递,适合实时状态通知类场景;如需可靠投递可在此基础上扩展 QoS 等级。

    7.5 可编程扩展接口

    MQTTServer 类同时导出了两个可在二次开发中复用的 API:

    // 获取服务器状态
    mqttServer.getStatus();
    // 返回 { mqttClients: <在线MQTT客户端数>, wsClients: <在线WebSocket客户端数>,
    // topics: [<主题列表>], totalMessages: <累计消息总数> }

    // 优雅关闭
    mqttServer.close();

    getStatus()(mqtt-server.js)统计 clients Map、wsServer.clients、topics Map 的大小与消息总量,可直接用于健康检查接口;close() 顺序关闭 TCP、aedes 与 WebSocket 三套资源。文件末尾通过 module.exports = MQTTServer 暴露类,且默认实例在 require 该文件时即自动启动。

    八、配套测试工具:MQTT 客户端自动化验证

    qtserver/ 目录自带完整的客户端测试工具,详细说明见 README-TEST.md,实现见 mqtt-client-test.js。

    8.1 一键运行完整测试

    # 先启动服务器
    npm start

    # 另开终端运行完整测试
    node mqtt-client-test.js

    测试将依次执行三类用例(见 mqtt-client-test.js):

  • MQTT 连接测试:建立 TCP 连接并验证连接状态(testMQTTConnection);
  • MQTT 消息测试:订阅 test/topic → 发布测试消息 → 校验收到 → 取消订阅(testMQTTMessaging);
  • WebSocket MQTT 测试:连接 8083 → 订阅 test/ws/topic → 发布 → 收到 → 取消订阅(testWebSocketMQTT + testWebSocketMessaging)。
  • 测试全程内置超时保护(消息接收超时 5 秒判定失败),结束后自动清理 MQTT 与 WebSocket 连接,并汇总输出总测试数、通过数、失败数及逐项明细(mqtt-client-test.js)。

    8.2 按需单独测试与自定义配置

    MQTTClientTest 类暴露了可组合的异步测试方法,支持只测某一环节:

    const MQTTClientTest = require('./mqtt-client-test');

    // 创建测试客户端
    const testClient = new MQTTClientTest({
    host: 'localhost', // MQTT服务器地址
    port: 1883, // MQTT端口
    wsPort: 8083, // WebSocket端口
    clientId: 'my_test_client'
    });

    // 只测试MQTT连接
    await testClient.testMQTTConnection();

    // 只测试MQTT消息收发
    await testClient.testMQTTMessaging();

    // 只测试WebSocket MQTT
    await testClient.testWebSocketMQTT();

    // 运行所有测试
    await testClient.runAllTests();

    构造函数默认值分别为 localhost、1883、8083 与 test_client_时间戳(mqtt-client-test.js),连接参数同时支持自定义:

    const testClient = new MQTTClientTest({
    host: '192.168.1.100', // 自定义服务器地址
    port: 8883, // 自定义MQTT端口
    wsPort: 8884, // 自定义WebSocket端口
    clientId: 'custom_client_id'
    });

    8.3 测试前置条件

    运行测试前请确认:MQTT 服务器已启动;目标主机与端口可从测试端访问;防火墙放行 1883/8083 端口;依赖包安装完整。若测试失败,输出中会明确标注是连接失败、订阅失败、发布失败还是消息接收超时,可据此定位问题。

    九、小结

    qtserver 为 we-mp-rss 提供了一套开箱即用的双协议 MQTT 消息中枢:TCP 侧由 aedes 支撑标准 MQTT 3.1.1,WebSocket 侧由 ws 支撑浏览器直连,两者通过 topics 持久化容器与 broadcastMessage 完成跨协议消息互通。原文档中的启动方式、环境变量、客户端示例、消息协议与故障排查均可直接照用,而源码级细节(事件驱动、消息回放、QoS 0 广播、getStatus 统计)则为深度定制与二次开发提供了明确依据。模块遵循 MIT License(见 README.md),相关实现文件为 mqtt-server.js、mqtt-client-test.js,更多模块说明可参考 README-TEST.md。

    赞

    分享

    • 后端
    • 网页爬虫
    • 前端

    【免费下载链接】we-mp-rss

    ✨符合阅读习惯的微信公众号助手、微信公众号转MarkDown、微信公众号转PDF、定时更新订阅公众号文章、生成微信公众号RSS订阅源、导出微信公众号订阅源、支持微信公众号Webhook/微信公众号API/AI Agent接入微信公众号微信公众号、订阅微信公众号、微信公众号助手 、微信公众号阅读、微信公众号接口、微信公众号爬虫、微信公众号监测、标签订阅微信公众号、微信公众号源、微信公众号读书、微信公众号文章、微信公众号框架、微信公众号管理、微信公众号源、微信公众号平台、微信公众号代码、微信公众号系统、微信公众号源码

    项目地址:
    https://gitcode.com/gh_mirrors/we/we-mp-rss

    点击查看 免费下载

    上一篇:
    Adobe Downloader:macOS平台终极免费下载工具完整指南

    下一篇:
    DotNext写入前日志(WAL)实现原理与性能调优终极指南

    创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » we-mp-rss 内置 QtServer MQTT 服务器全指南:基于 aedes 的 TCP + WebSocket 双通道消息中枢
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!