- 物联网
- 消息队列
- 后端
【免费下载链接】mosquitto
Eclipse Mosquitto - An open source MQTT broker
本篇文章基于 Mosquitto 官方博客在 2012 年发布的 mqtt2pachube 历史文章,深入讲解这款将 MQTT 消息转发到 Pachube(后更名为 Cosm、Xively)物联网数据平台的桥接工具:它的设计动机、主题到数据流(datastream)的映射思路、对 Mosquitto 客户端库版本的要求,以及围绕它沉淀下来的 MQTT 客户端实操方法。读完本文,你将理解"传感器逐条消息 → MQTT 订阅 → 云端数据流"这条数据链路的经典实现方案,并掌握用 Mosquitto 命令行客户端对接此类平台的完整手法。
说明:该文章发布于 2012 年,已被官方标记为Obsolete(过时),文中涉及的 Pachube 服务早已经历 Cosm、Xively 的改名与业务调整。本文将其作为 Mosquitto 生态中"MQTT 与外部数据平台集成"的代表性案例来解读,所有事实均以当前仓库内的文档、手册与变更记录为准。
一、背景与动机:为什么需要 mqtt2pachube
2012 年初,Mosquitto 作者在官方博客中介绍了一个自己编写的工具mqtt2pachube,其核心诉求非常具体:
当时 Pachube 提供的客户端库对"单一 datastream 的 feed 更新"和"更新 feed 内全部 datastream"支持良好,但对单独更新任意一个 datastream的支持却很有限。而传感器数据往往以"一条消息对应一次读数"的方式逐个到达,这让直接把传感器消息灌入 Pachube 变得很困难。
换句话说,传感器侧产生的是高频、离散、逐个到达的消息流,而 Pachube 侧需要的是一次性、整块的数据流更新——两者之间存在明显的"阻抗失配"。mqtt2pachube就是为此而生的中间桥接层:它订阅 MQTT 主题,收到消息后按主题规则把消息映射到指定的 Pachube feed 与 datastream id,从而完成"传感器 → MQTT → Pachube 数据流"的自动流转。
与同期生态的呼应
这篇博文并非孤立事件。仓库中的同期文章可以佐证当时的上下文:
- Challenge: Web based MQTT graphing 提到
test.mosquitto.org通过一个 IBM broker 的数据馈送,开始在energy/主题树下发布英国发电与用电数据,并号召开发者用 MQTT 把数据接到网页图表中; - Quick start guide for MQTT with Pachube/Cosm/Xively 则是紧随其后、更完整的"MQTT 对接 Pachube"操作指南,说明当时社区对"MQTT 上云"的需求已经相当集中。
mqtt2pachube正是这条"上云"路径上的一次具体工程实践。
二、工具核心原理:订阅选择 + 主题到数据流映射
博文对mqtt2pachube工作方式的描述只有两句话,但信息量十足:
mqtt2pachubeallows you to choose what mqtt subscriptions to make and then match incoming messages by their topics to a pachube feed and datastream id.
可以将其拆解为两个明确的设计要点:
- 订阅选择(Subscription Selection):用户可以自行决定建立哪些 MQTT 订阅,而不是写死在程序里。这意味着同一套工具可以灵活对接不同的传感器主题树,例如
energy/generation/...、sensors/kitchen/...等。 - 主题匹配(Topic Matching):每条到达的消息按主题被匹配到一个Pachube feed id与datastream id,消息负载(payload)作为该数据流的新值提交。
这种"按主题路由到数据流"的设计,本质上就是后来 IoT 平台集成中普遍采用的主题即数据路由表思路。虽然仓库中没有mqtt2pachube工具本身的源码(它托管在外部代码托管站点,且已标记为过时),但从 Mosquitto 客户端库的角度看,主题匹配正是这一类桥接程序的通用基础能力——Mosquitto 客户端库为此提供了专门的 API:
- include/mosquitto/libcommon_topic.h 中声明了
mosquitto_topic_matches_sub(),用于判断某个具体主题是否与某个订阅(可含+/#通配符)匹配; - 同期变更记录显示该函数于 0.15 时代加入(见下文版本小节),后续又不断修复了
+作为末级、foo/bar与foo/bar/#边界等匹配细节(见 ChangeLog.txt 中历次 "Fix mosquitto_topic_matches_sub()..." 条目)。
对于任何想自己实现"MQTT → 第三方数据平台"桥接的开发者,主题匹配这一环都可以直接复用这些库函数,而不必自己处理通配符展开。
三、版本要求与编译限制:0.15.90 与客户端库的"不足"
博文明确指出了当时的使用前提:
At the moment it is still experimental, but seems to work. It has highlighted a shortcoming in the mosquitto client library, so requires version 0.15.90 (ie. the in-progress work for the next release).
这段描述包含三个关键事实:
- 工具仍处于实验阶段,作者自述"看起来能用"(seems to work),属于边用边验证的状态;
- 它暴露了 Mosquitto 客户端库的一个缺陷,因此必须依赖开发中的 0.15.90 版本——即0.15 发布后、1.0 正式版之前的在研版本(0.15.90 是 Mosquitto 的"开发版"编号惯例);
- 没有 Windows 支持,也没有二进制安装包,感兴趣的人只能自己编译源码。
用仓库中的版本历史可以还原这一时间线:
- ChangeLog.txt 记录0.15 - 20120205(2012 年 2 月 5 日发布),该版本在客户端库部分新增了
mosquitto_topic_matches_sub()、mosquitto_sub_topic_tokenise()等主题工具函数,并修复了 "messages to topica/bincorrectly matching on a subscriptionaif another subscriptiona/#exists" 这类订阅重叠时的错误匹配问题; - 紧随其后,1.0 - 20120814(2012 年 8 月 14 日发布)正式落地了 SSL/TLS、TLS-PSK、
mosquitto_connect_async()、回调签名重构等一大批特性,0.15.90 正是这条通往 1.0 的中间路线上承载"在研特性"的版本号; - 同期博文 www/posts/2012/07/upcoming-release.md 也印证了这一点:0.15.90 这类编号正是"下一个版本(即 1.0)的在研版本"。
由此可以推断:mqtt2pachube依赖的正是 0.15 到 1.0 之间客户端库新增/修正的主题匹配与回调能力。换句话说,这个小小的工具实际上是 Mosquitto 客户端库在 0.15/1.0 时代能力演进的早期验证者。
四、实际应用案例:test.mosquitto.org 数据驱动的两个 Pachube Feed
为了验证工具的可用性,作者用test.mosquitto.org公开 broker 上的数据创建了两个 Pachube feed 作为展示:
test.mosquitto.org details(对应 feed 43810)UK energy data - generation source percentage(对应 feed 47080)
第二个 feed 与仓库中另一篇博文直接相关:Challenge: Web based MQTT graphing 中说明test.mosquitto.org在energy/主题树下发布英国能源发电与需求数据(数据由 IBM broker 提供),并提到可用它做"发电机组成比例饼图""电网频率仪表盘"等可视化。mqtt2pachube将这批energy/主题下的消息按比例映射为 Pachube feed 的 datastream,正是把"M2M 消息流"变成"云端可查询数据流"的完整闭环演示。
这两条 feed 也直观展示了桥接的价值:MQTT 侧的实时消息流,经过桥接后变成 Pachube 侧带历史记录的图表数据,供 Web 应用直接消费。
五、配套实操:用 Mosquitto 命令行客户端对接此类平台
虽然mqtt2pachube工具本身已过时,但它所属的"MQTT ↔ 数据平台"集成场景在同期沉淀下了大量可直接复用的命令行手法。仓库中的 Quick start guide for MQTT with Pachube/Cosm/Xively 给出了完整示例,这里摘录并补充说明。
5.1 发布数据:单条消息
以 Xively(Pachube 后来的名字)为例,用 API key 作为用户名,向 feed 的 CSV 端点发布单条数据:
mosquitto_pub -h api.xively.com -u <your xively api-key> -t /v2/feeds/504.csv -m "0,29"含义:连接到api.xively.com,以 API key 作为用户名,向 feed 504 的 CSV 主题发布"0,29"——即 datastream 0 的新值为 29。等价写法是直接指定 datastream:
mosquitto_pub -h api.xively.com -u <your xively api-key> -t /v2/feeds/504/datastreams/0.csv -m 295.2 发布数据:从标准输入逐行发布
mosquitto_pub支持从 stdin 读取数据并逐行发布,这正好贴合"传感器逐条读数"的场景。在 Unix 类系统上可以这样串联:
sensor_read | mosquitto_pub -h api.xively.com -u <api-key> -t /v2/feeds/504/datastreams/0.csv -l其中-l(--stdin-line)选项表示"把 stdin 的每一行当作一条独立消息发送"。该选项的权威说明见 man/mosquitto_pub.1.xml:"Send messages read from stdin, splitting separate lines into separate messages."前提是sensor_read这类假想的读数程序需要把每次读数打印为一行文本。同期手册示例也给出了同样的惯用法——用 Current Cost 电表解析脚本配合-l逐行发布(见 man/mosquitto_pub.1.xml 中read_cc128.pl | mosquitto_pub -t sensors/cc128 -l的例子)。
5.3 订阅获取数据
MQTT 世界里"取数据"靠订阅。同样指定 CSV 端点即可持续收到该 datastream 的更新:
mosquitto_sub -h api.xively.com -u <api-key> -t /v2/feeds/504/datastreams/0.csv每次 datastream 0 更新时,mosquitto_sub会打印一行 CSV 数据。
5.4 遗嘱消息(Last Will and Testament):断线监控
MQTT 的遗嘱特性是连接监控的利器:客户端连接时可向 broker 登记一个"遗嘱"(topic + message);若客户端未发送 DISCONNECT 而异常断开,broker 会代为发布该遗嘱消息。利用这一点,客户端上线时发布"1"、同时登记遗嘱在意外断开时向同一主题发布"0",监控方即可通过订阅该主题判断客户端是否在线:
mosquitto_sub -h api.xively.com -u <api-key> -t /v2/feeds/504/datastreams/0.csv --will-topic /v2/feeds/12345/datastreams/0.csv --will-payload "0"示例中,若mosquitto_sub意外断开,Xively broker 会向 feed 12345 的 datastream 0 发布值"0"。指南原文也客观指出:受mosquitto_sub能力所限,这个例子并非最实用——要发挥 MQTT 的完整优势(主题通配符、持久会话、遗嘱组合等),通常还是应该为具体应用编写自己的客户端。
六、历史视角:从 Pachube 到 Cosm/Xively,及对今日的启示
从仓库内的时间线可以还原这条演进的完整脉络:
- 2012-01:test.mosquitto.org 上线,公开 Mosquitto broker 可供任何人连接;
- 2012-02:
mqtt2pachube发布,打通 MQTT → Pachube 数据流(本文主题); - 2012-03:Quick start guide for MQTT with Pachube/Cosm/Xively 发布,Pachube 官宣支持 MQTT beta 接入,命令行与自研客户端两条路径都有了官方背书。
Pachube 随后先后更名为 Cosm、Xively,"MQTT 直连数据平台"也从实验性质变为平台原生能力。今天回看这篇 Obsolete 博文,其价值在于清晰地记录了一个通用问题与通用解法:
- 问题:传感器消息是离散、逐条的,而云端数据流平台偏好像整块更新;
- 解法:中间桥接层订阅 MQTT、按主题路由到目标 feed/datastream,把"消息流"翻译成"数据流"。
这种"订阅-路由-上报"的三段式架构,在今日的 IoT 数据管道、边缘网关、规则引擎中依然随处可见。如果你要在现代 Mosquitto 上实现类似桥接,客户端库的mosquitto_topic_matches_sub()家族函数(include/mosquitto/libcommon_topic.h)依然是做主题路由最可靠的地基。
参考资料(仓库内)
- 本文主体:www/posts/2012/02/mqtt2pachube.md
- MQTT 对接 Pachube/Cosm/Xively 实操指南:www/posts/2012/03/quick-start-guide-for-mqtt-with-pachube.md
- UK 能源数据来源背景:www/posts/2012/01/challenge-web-based-mqtt-graphing.md
- 公开测试 broker 上线公告:www/posts/2012/01/mosquitto-test-server.md
- 版本历史(0.15 / 1.0 变更记录):ChangeLog.txt
mosquitto_pub手册(-l/--stdin-line等选项):man/mosquitto_pub.1.xml- 主题匹配 API 声明:include/mosquitto/libcommon_topic.h
- 物联网
- 消息队列
- 后端
【免费下载链接】mosquitto
Eclipse Mosquitto - An open source MQTT broker
相关推荐
Mosquitto 快速入门:用 MQTT 命令行客户端对接 Xively(原 Pachube/Cosm)数据平台
Mosquitto 快速入门:用 MQTT 命令行客户端对接 Xively(原 Pachube/Cosm)数据平台 本文整理自本仓库历史博客《Quick sta
后端消息队列消息路由EMQX PostgreSQL 数据桥接:将 MQTT 物联网数据写入 PostgreSQL 的完整指南
EMQX PostgreSQL 数据桥接:将 MQTT 物联网数据写入 PostgreSQL 的完整指南 导读 :本文以 EMQX 开源仓库中的 apps/em
后端物联网消息队列通信GP2040-CE固件升级终极指南:从v0.7.11快速升级到v0.7.12
GP2040 CE固件升级终极指南:从v0.7.11快速升级到v0.7.12 GP2040 CE是一款专为Raspberry Pi Pico和其他RP2040开
嵌入式硬件开发游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考