基于开源库编写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 究竟是什…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
