基于开源库编写MQTT通讯
目录
- 1. MQTT是什么?
- 2. 开发交互UI
- 3. 服务器核心代码
- 4. 客户端核心代码
- 5. 消息订阅与发布
- 6. 通讯测试
- 7. MQTT与PLC通讯
- 最后. 核心总结
1. MQTT是什么?
MQTT(Message Queuing Terlemetry Transport)消息队列遥测协议;是一种轻量级的发布/订阅消息传输协议,专为IOT、低带宽、高延迟的网络环境设计,具有高效、低耗、海量设备连接特性。
1.通讯原理
- 发布(Publisher):发布消息到特定主题(Topic)
- 订阅(Subscriber):订阅主题接收消息
- 代理(Broker):消息路由管理,接收发布的消息,颁发给所有订阅者
示例:传感器(Publisher)发送消息到主题(Topic),代理(Broker)接收消息并检查该主题的所有客户端,订阅者(Subscriber)实时接收消息
2.消息结构
- 主题(topic)+负载(payload)
3.必要条件
- MQTT Broker: 消息代理服务器
- 客户端库: 设备或应用需集成MQTT客户端
- 端口: 默认非加密端口 1883,加密端口 8883(TLS/SSL)
- 连接认证: 支持用户名/密码、客户端证书等认证方式
- QoS服务质量/策略
QoS等级 | 描述 | 适用场景 |
---|---|---|
0 | 最多一次(无确认) | 实时性高,允许丢数据 |
1 | 至少一次(需确认) | 数据需可靠但不重复 |
2 | 精确一次(握手确认) | 关键数据,严格不重复 |
4. 关键特性
遗嘱消息(Last Will)
- 设备异常断开时,Broker 自动发布预设消息(如“设备离线”),通知其他客户端。
保留消息(Retained)
- Broker 保存主题的最新消息,新订阅者首次连接时立即获取。
主题层级(Topic Hierarchy)
- 支持多级通配符(+ 单层,# 多层)
- 例如:
home/floor1/temperature; home/+/status(匹配所有楼层状态)
5.应用场景
- 移动设备远程监控(AGV状态上报)
- 跨厂区数据汇聚(通过云平台中转)
2. 开发交互UI
创建WindowsFormAPP项目,NuGet安装MQTTnet开源库(项目-属性-框架;需与程序包的依赖项一致<否则安装错误>:PM> NuGet\Install-Package MQTTnet -Version 2.8.2
)
控件
- label、TextBox、ComboBox、Button
- ListView(Dock=停靠<视图=Details;小Imagelist=Imagelist1;编辑列=Infoname、Content>)
容器
- SplitContainer(Orienting=垂直;SplitterWith=1;BorderStyle=边框)
组件
- Imagelist(添加图像)
- timer(Enabled=true、Interval=1000)
状态
- StatusStrip(系统时间、连接数量、版本说明)
Server端
- 窗体设置(Text=标题、Font=字体、StartPosition=位置、FormBoardStyle=边框)
- 给定服务IP,固定端口号,设置开始、停止服务、快捷打开客户端按钮
- 设置日志消息显示窗口;设置状态栏
Client端
- 技巧:复制FrmServer(修改窗口、Designer代码)
- 容器:在SP1的Panel2添加SplitContainer2(Listview放在SP2的Panel1中);
- 设置SP1的FixedPanel的Panel1不动;设置SP2的FixedPanel的Panel2不动
- 客户端可发布主题消息
- 设置连接、订阅、取消订阅、发布主题按钮;
- 主题信息、给定QoS策略
3. 服务器核心代码
初始化-public FrmServer(){…}
- 获取IP集合
(Dns.GetHostAddresses)
- 绑定控件
(cmb_iplist.DataSource、.SelectedIndex)
创建服务器对象(IMqttServer)(->服务启动按钮点击事件)
- 创建服务器配置 _
var optionsBuilder = new MqttServerOptionsBuilder()
– 验证用户密码_.WithConnectionValidator(c =>...
- 实例化服务对象_
mqttServer = new MqttFactory().CreateMqttServer();
- 创建MQTT事件方法_
mqttServer.ClientConnected += MqttServer_ClientConnected;
– 方法日志显示_this.AddLog(0, "MQTT客户端已连接" + "ClietID:" + e.ClientId.Length);
- 启动服务_
mqttServer.StartAsync(optionsBuilder.Build());
日志对象
- 创建委托_
public delegate void AddlogDelegate(int index, string info);
- 委托方法_
private void AddlogMothod(int index, string info){...}
- 委托对象_
private AddlogDelegate AddLog;
- 对象绑定方法 _
this.AddLog = this.AddlogMothod;
- 对象应用eg:_
this.AddLog(0, "MQTT服务端已停止");
状态栏
- 系统时间_
this.tss_time.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- 连接个数(连接/断开事件更新)_
this.tss_connnum.Text = mqttServer.GetClientSessionsStatusAsync().Result.Count.ToString();
其他
- 停止服务_
mqttServer.StopAsync();
- 清空日志_
this.lst_info.Items.Clear();
- 打开客户端(注意“重新生成解决方案”)_
new FrmClient().Show();
- 当前时间_
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
- 关闭窗体停止服务
4. 客户端核心代码
初始化
- 获取IP集合
(Dns.GetHostAddresses)
- 绑定控件
(cmb_iplist.DataSource、.SelectedIndex)
快捷打开客户端,ServerIP、Port自动填写
- 创建带参数的初始化构造方法_
public FrmClient(string ip, string port)
创建客户端对象(IMqttClient)(->客户端连接按钮点击事件)
- 创建客户端配置_
var option = new MqttClientOptions() { ClientId = Guid.NewGuid().ToString("D") };
- 创建通道配置_
option.ChannelOptions = new MqttClientTcpOptions()
- 是否启用账户_
if (this.chk_isuserpwd.Checked)
- 创建会话配置_
option.CleanSession = true;
- 创建客户端对象_
mqttClient = new MqttFactory().CreateMqttClient();
- 连接服务器_
mqttClient.ConnectAsync(option);
- 绑定事件方法(添加日志)_
mqttClient.Connected += mqttClient_Connected;
日志显示
- 创建委托方法_与服务端一致
- 创建委托对象_与服务端一致
- 初始化对象绑定方法_与服务端一致
- 对象引用eg_与服务端一致
其他
- 断开连接_
mqttClient.DisconnectAsync();
5. 消息订阅与发布
客户端可以正确连接后,只有订阅与发布消息,才算真正进行数据通讯;消息的订阅和发布均在客户端进行,服务端只需提供一个服务供客户连接(桥梁的作用);小节解释消息订阅发布的核心代码。
QoS服务策略(下拉框获取)
- QoS服务策略(枚举类型)_
this.cmb_qos_pub.DataSource = Enum.GetNames(typeof(MqttQualityOfServiceLevel));
消息订阅
- 订阅主题_
mqttClient.SubscribeAsync(new List<TopicFilter>(){...});
1
消息取消订阅
- 取消订阅_
mqttClient.UnsubscribeAsync(this.txt_topic_sub.Text);
消息发布
- 创建消息对象_
var msg = new MqttApplicationMessage(){...}
2 - 发布消息_
mqttClient.PublishAsync(msg);
6. 通讯测试
7. MQTT与PLC通讯
将msg对象中的Payload更改为PLC的寄存器即可
自动发布
- 添加定时器timer1_设置频率,事件(消息内容,自动发布)
- 连接成功时启动定时器_
this.timer1.Enabled = true;
消息内容
- 添加引用(西门子通讯库)
- 创建PLC对象
- 读取PLC变量
- 添加到msg中的Payload中_
Payload = Encoding.UTF8.GetBytes(plcmsg),
最后. 核心总结
1. 开发实现
服务端:
- 功能:IP/端口配置、启动/停止服务、连接监控
- 初始化 MqttServer 对象
- 处理连接/断开事件(日志记录、状态更新)
客户端:
- 功能:连接/断开、订阅/取消主题、消息发布
- 配置 MqttClient(IP、端口、认证)
- 实现订阅 (SubscribeAsync) /发布 (PublishAsync)
2. 进阶应用
PLC 集成:
- 自动发布:定时器读取 PLC 数据并推送
- 数据格式:Payload 封装寄存器值(如 Siemens PLC 数据)
异常测试:
- 基础测试:服务端启停、客户端连接/断开
- 消息流验证:订阅发布功能、QoS 策略生效
- 异常测试:网络断开重连、遗嘱消息触发
附:关键代码片段
服务端启动:
var options = new MqttServerOptionsBuilder().WithDefaultPort(1883).Build();
mqttServer = new MqttFactory().CreateMqttServer();
mqttServer.StartAsync(options);
客户端发布消息:
var msg = new MqttApplicationMessage {Topic = "sensor/temp",Payload = Encoding.UTF8.GetBytes("25℃"),QoS = MqttQualityOfServiceLevel.AtLeastOnce
};
client.PublishAsync(msg);
PLC 数据读取:
var plcValue = SiemensPLC.Read("DB1.DBD0"); // 读取浮点数
var payload = $"{{\"temperature\": {plcValue}}}";
源码链接
创建TopicFilter对象_
new TopicFilter(this.txt_topic_sub.Text, (MqttQualityOfServiceLevel)Enum.Parse(typeof(MqttQualityOfServiceLevel),this.cmb_qos_sub.Text))
↩︎消息对象赋值_
Topic = this.txt_topic_pub.Text, QualityOfServiceLevel =(MqttQualityOfServiceLevel)Enum.Parse(typeof(MqttQualityOfServiceLevel), this.cmb_qos_pub.Text), Payload = Encoding.UTF8.GetBytes(this.txt_msg_pub.Text), Retain = false,
↩︎
相关文章:

基于开源库编写MQTT通讯
目录 1. MQTT是什么?2. 开发交互UI3. 服务器核心代码4. 客户端核心代码5. 消息订阅与发布6. 通讯测试7. MQTT与PLC通讯最后. 核心总结 1. MQTT是什么? MQTT(Message Queuing Terlemetry Transport)消息队列遥测协议;是…...
Kafka Connect连接器的全生命周期:
以下是基于Vue和PySide2的两种图形化界面设计方案,用于管理Kafka Connect连接器的全生命周期: 方案一:Vue3 Web管理平台 技术栈 - 前端:Vue3 + Element Plus + ECharts - 通信:Axios + WebSocket - 安全:JWT + HTTPS - 打包:Vite + Docker核心功能模块 <!-- 连接器…...

磁盘空间不足|如何安全清理以释放磁盘空间(开源+节流)
背景: 最近往数据库里存的东西有点多,磁盘不够用 查看磁盘使用情况 df -h /dev/sda5(根目录 /) 已使用 92% 咱们来开源节流 目录 背景: 一、开源 二、节流 1.查找 大于 500MB 的文件: 1. Snap 缓存…...
DeepSeek vs Grok vs ChatGPT:大模型三强争霸,谁将引领AI未来?
DeepSeek vs. Grok vs. ChatGPT:大模型三强争霸,谁将引领AI未来? 在人工智能领域,生成式模型的竞争已进入白热化阶段。DeepSeek、Grok和ChatGPT作为三大代表性工具,凭借独特的技术路径和应用优势,正在重塑…...

2025国家护网HVV高频面试题总结来了04(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 一、HVV行动面试题分类 根据面试题的内容,我们将其分为以下几类: 漏洞利用与攻击技术 …...

我的AI工具箱Tauri版-通用音频转文本
本模块支持FunAsr和FasterWhisper两种模式,可批量处理音频与视频文件,自动生成txt文本与srt字幕,满足多种应用场景需求。 工具内置FunAsr,无需额外参数调整,特别适用于中文语音的高质量转录,确保识别准确率…...
Vue.js计算属性
计算属性 基础示例 模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。比如说,我们有这样一个包含嵌套数组的对象: js const author = reactive({name: John Doe,books: [Vue 2 - Advanced Guide,Vue 3 - Bas…...

品佳诚邀您参加 3/12『英飞凌汽车方案引领智能座舱新纪元』在线研讨会
英飞凌汽车方案引领智能座舱新纪元 時間:2025年3月12日 14:00-15:30 品佳诚邀您参加本次线上直播,深入了解英飞凌如何引领智能座舱技术革新! 随著科技的飞速发展,汽车已不再仅仅是交通工具,而是集成了丰富智能功能的…...

科普|无人机专业术语
文章目录 前言一、飞控二、电调三、通道四、2S、3S、4S电池五、电池后面C是什么意思?六、电机的型号七、什么是电机的KV值?八、螺旋桨的型号九、电机与螺旋桨的搭配 前言 无人机飞控系统控制飞行姿态,电调控制电机转速,遥控器通道控制飞行动作。电池C…...
Tauri跨平台开发问题及解决方案深度解析(React版)
Tauri跨平台开发问题及解决方案深度解析(React版) 一、环境配置与项目初始化难题(React适配) 1.1 React项目初始化 推荐模板: # 使用ReactTypeScript模板 npm create tauri-applatest -- --template react-ts# 项目…...

基于单片机和Wifi技术的智能台灯设计
摘要 :本文主要介绍了基于单片机AT89C51和Wifi技术的智能台灯的硬件和软件设计。该智能台灯具有根据当前光线自动调节灯光亮度的功能,还可对用户使用台灯时处于非正常的距离和姿态时给予报警提示,用户可以随时通过手机app查询智能台灯的报警记…...
ds回答-开源llm应用开发平台
以下是几个著名的开源 LLM 应用开发平台,涵盖不同场景和技术特点: 1. Dify 特点:低代码 / 无代码开发、支持 RAG 检索、Agent 智能体、模型管理、LLMOps 全流程优化。核心功能:可视化工作流编排、数百种模型兼容(如 GP…...
【量化策略】均值回归策略
【量化策略】均值回归策略 🚀量化软件开通 🚀量化实战教程 技术背景与应用场景 在金融市场中,价格波动是常态,但长期来看,资产价格往往会围绕其历史平均水平上下波动。均值回归策略正是基于这一现象设计的量化交易…...
iterm2更新后主题报错
报错 .oh-my-zsh/themes/agnoster.zsh-theme:307: parse error near <<<。方法1:更新Oh My Zsh主题(以agnoster为例) 适用场景:使用Oh My Zsh自带主题(如agnoster)时出现语法错误。 备份当前主题…...

深度学习架构Seq2Seq-添加并理解注意力机制(一)
第一章:人工智能之不同数据类型及其特点梳理 第二章:自然语言处理(NLP):文本向量化从文字到数字的原理 第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码) 第四章:循环神经网络RNN、LSTM以及GR…...
Kafka底层结构
1. Kafka 架构总览 Kafka 是一个分布式消息队列,采用**发布-订阅(Pub-Sub)**模式,核心组件包括: Producer(生产者): 负责向 Kafka 发送消息。Broker(Kafka 服务器&…...

[BUUCTF]web--wp(持续更新中)
ps:文章所引用知识点链接,如有侵权,请联系删除 [极客大挑战 2019]EasySQL 题目类型:简单SQL注入 发现是登录页面,用万能登录方法测试,两种语句均能解出flag [极客大挑战 2019]Havefun 题目类型:代码审计…...
axios请求设置request umijopenai生产前端请求 ts状态全局 v-if v-else 与动态js变量
axios请求 安装 npm install axios全局自定义请求 集中处理设置 集体通用请求 example const instance axios.create({baseURL: https://some-domain.com/api/,timeout: 1000,headers: {X-Custom-Header: foobar} });请求前 请求后 拦截器 // 添加请求拦截器 axios.in…...

SparkSQL全之RDD、DF、DS ,UDF、架构、资源划分、sql执行计划、调优......
1 SparkSQL概述 1.1 sparksql简介 Shark是专门针对于spark的构建大规模数据仓库系统的一个框架Shark与Hive兼容、同时也依赖于Spark版本Hivesql底层把sql解析成了mapreduce程序,Shark是把sql语句解析成了Spark任务随着性能优化的上限,以及集成SQL的一些…...

深入理解Linux内存缓存:提升性能的关键
在深入探索 Linux 系统的奇妙世界时,内存管理无疑是一个至关重要的领域。而在 Linux 内存体系中,Cache 扮演着举足轻重的角色。它就像是一位默默奉献的幕后英雄,为系统的高效运行立下汗马功劳。那么,Linux 内存中的 Cache 究竟是什…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技
无需布线的革命:电力载波技术赋能楼宇自控系统 在楼宇自动化领域,传统控制系统依赖复杂的专用通信线路,不仅施工成本高昂,后期维护和扩展也极为不便。电力载波技术(PLC)的突破性应用,彻底改变了…...

ABAP设计模式之---“Tell, Don’t Ask原则”
“Tell, Don’t Ask”是一种重要的面向对象编程设计原则,它强调的是对象之间如何有效地交流和协作。 1. 什么是 Tell, Don’t Ask 原则? 这个原则的核心思想是: “告诉一个对象该做什么,而不是询问一个对象的状态再对它作出决策。…...
更新 Docker 容器中的某一个文件
🔄 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法,适用于不同场景。 ✅ 方法一:使用 docker cp 拷贝文件到容器中(最简单) 🧰 命令格式: docker cp <…...