C#中MQTT的使用小結(jié)
一、MQTT:物聯(lián)網(wǎng)通信協(xié)議
MQTT(Message Queuing Telemetry Transport,消息隊(duì)列遙測(cè)傳輸)是一種輕量級(jí)的通信協(xié)議,專(zhuān)為物聯(lián)網(wǎng)(IoT)設(shè)計(jì),作用是:
輕量級(jí)通信:協(xié)議頭極?。ü潭^部?jī)H2字節(jié)),適合低帶寬、低功耗設(shè)備發(fā)布/訂閱模式:設(shè)備無(wú)需直接通信,通過(guò)中間代理(Broker)傳遞消息多種QoS級(jí)別:支持QoS 0/1/2,確保消息可靠傳遞 適合場(chǎng)景:智能家居、工業(yè)自動(dòng)化、車(chē)聯(lián)網(wǎng)、智慧城市等物聯(lián)網(wǎng)應(yīng)用
典型應(yīng)用:智能燈泡通過(guò)主題home/light/control接收開(kāi)關(guān)指令,土壤傳感器將濕度數(shù)據(jù)發(fā)布到farm/section1/moisture,灌溉系統(tǒng)訂閱該主題并自動(dòng)控制水泵。
1.1 核心模型:發(fā)布/訂閱模式
MQTT的使用模型最核心的就是發(fā)布/訂閱模式,它由三個(gè)關(guān)鍵角色組成:

1.2 工作流程(簡(jiǎn)單版)

1.3 詳細(xì)工作流程
- 建立連接:客戶(hù)端與代理(Broker)建立TCP連接(可選加密,端口1883或8883)
- 訂閱主題:客戶(hù)端向代理發(fā)送訂閱請(qǐng)求,如
home/light/control - 發(fā)布消息:發(fā)布者向指定主題發(fā)布消息,如
home/light/control,內(nèi)容為{"status": "on"} - 消息分發(fā):代理將消息轉(zhuǎn)發(fā)給所有訂閱了該主題的客戶(hù)端
- 接收消息:訂閱者接收并處理消息
1.4 超輕量級(jí)(最突出的特點(diǎn)?。?/h3>
- 固定報(bào)文頭最小僅2字節(jié),比HTTP協(xié)議的報(bào)文小多了
- 控制報(bào)文只有幾個(gè)字節(jié),開(kāi)發(fā)人員可以很快理解和實(shí)現(xiàn)
- 網(wǎng)絡(luò)開(kāi)銷(xiāo)極低,特別適合帶寬有限的設(shè)備
- 擁有多語(yǔ)言客戶(hù)端(Java、Python、C#、Go等)
- 支持多種連接方式:TCP、SSL/TLS、WebSocket等
- 開(kāi)源實(shí)現(xiàn)豐富,社區(qū)支持好
二、基礎(chǔ)使用示例
C#中主要用兩個(gè)庫(kù):
- MQTTnet(推薦?。? 輕量級(jí)、功能全,最新版已經(jīng)支持MQTT 5.0
- M2Mqtt - 老牌庫(kù),適合簡(jiǎn)單場(chǎng)景
小貼士:MQTTnet 4.3.7+版本是目前主流選擇,功能更豐富,社區(qū)支持也更好
1.安裝庫(kù)(NuGet)
使用NuGet安裝 Install-Package MQTTnet
2.簡(jiǎn)單客戶(hù)端連接示例
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
// 創(chuàng)建MQTT工廠
var factory = new MqttFactory();
// 配置連接選項(xiàng)
var options = new MqttClientOptionsBuilder()
.WithClientId("CSharpClient")
.WithTcpServer("broker.hivemq.com", 1883) // 替換為你的MQTT服務(wù)器地址
.WithCleanSession()
.Build();
// 創(chuàng)建并連接客戶(hù)端
var mqttClient = factory.CreateMqttClient();
var connectResult = await mqttClient.ConnectAsync(options);
if (connectResult.ResultCode == MqttClientConnectResultCode.Success)
{
Console.WriteLine("已成功連接到MQTT服務(wù)器!");
// 發(fā)布消息
var message = new MqttApplicationMessageBuilder()
.WithTopic("test/topic")
.WithPayload("Hello from C# MQTT!")
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce) // QoS 1
.Build();
await mqttClient.PublishAsync(message);
// 訂閱主題
await mqttClient.SubscribeAsync("test/topic");
// 處理收到的消息
mqttClient.ApplicationMessageReceivedAsync += (e) =>
{
Console.WriteLine($"收到消息: {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
return Task.CompletedTask;
};
}3.斷開(kāi)重連機(jī)制(重要!)
在實(shí)際項(xiàng)目中會(huì)遇到網(wǎng)絡(luò)波動(dòng)問(wèn)題,MQTTnet自帶了重連機(jī)制:
// 配置自動(dòng)重連
var options = new MqttClientOptionsBuilder()
.WithClientId("CSharpClient")
.WithTcpServer("your-broker-address", 1883)
.WithKeepAlivePeriod(TimeSpan.FromSeconds(30))
.WithConnectionRetryInterval(TimeSpan.FromSeconds(5)) // 重連間隔
.Build();
// 連接時(shí)處理重連
mqttClient.ConnectAsync(options);
mqttClient.DisconnectedAsync += (e) =>
{
Console.WriteLine("連接已斷開(kāi),正在嘗試重連...");
return Task.CompletedTask;
};三、QoS級(jí)別選擇指南
選擇QoS級(jí)別是MQTT使用中的關(guān)鍵決策:

- QoS 0:最多一次,適合不重要的數(shù)據(jù)(如傳感器狀態(tài))
- QoS 1:至少一次,適合一般重要數(shù)據(jù)(如設(shè)備控制指令)
- QoS 2:只有一次,適合關(guān)鍵數(shù)據(jù)(如訂單確認(rèn)、支付信息)
在物聯(lián)網(wǎng)場(chǎng)景中,QoS 1是最佳平衡點(diǎn),既保證可靠性又不會(huì)過(guò)度消耗資源
四、實(shí)際應(yīng)用場(chǎng)景
4.1 物聯(lián)網(wǎng)數(shù)據(jù)上傳
// 模擬傳感器數(shù)據(jù)
var sensorData = new { Temperature = 25.5, Humidity = 60 };
var json = JsonConvert.SerializeObject(sensorData);
// 發(fā)布到MQTT
var message = new MqttApplicationMessageBuilder()
.WithTopic("sensors/room1")
.WithPayload(json)
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
.Build();
await mqttClient.PublishAsync(message);4.2 MQTT到ModbusRTU數(shù)據(jù)轉(zhuǎn)發(fā)(工業(yè)場(chǎng)景)
// 從MQTT接收數(shù)據(jù),轉(zhuǎn)發(fā)到Modbus設(shè)備
private void HandleReceivedMessage(MqttApplicationMessageReceivedEventArgs e)
{
var payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
// 解析數(shù)據(jù)并寫(xiě)入Modbus設(shè)備
ModbusWriter.WriteToDevice(payload);
}五、專(zhuān)業(yè)建議
- 使用異步編程:MQTT操作都是I/O密集型,務(wù)必使用
async/await,避免阻塞主線程 - 錯(cuò)誤處理:不要只檢查連接狀態(tài),要處理所有可能的異常
try
{
await mqttClient.ConnectAsync(options);
}
catch (Exception ex)
{
// 記錄錯(cuò)誤并嘗試重連
Console.WriteLine($"連接失敗: {ex.Message}");
}- 會(huì)話管理:根據(jù)需求設(shè)置
WithCleanSession(),持久會(huì)話適合需要恢復(fù)訂閱的場(chǎng)景 - 安全考慮:生產(chǎn)環(huán)境務(wù)必使用SSL/TLS加密
.WithTls() .WithTlsVersion(TlsVersion.Tls12)
安全性
- 傳輸加密:使用 TLS/SSL(端口 8883)加密通信,防止中間人攻擊。
- 身份認(rèn)證:
- 用戶(hù)名/密碼認(rèn)證(推薦強(qiáng)密碼)。
- 更高級(jí)方案:客戶(hù)端證書(shū)(mTLS)、OAuth 2.0(部分 Broker 支持)。
- 訪問(wèn)控制(ACL):配置 Broker 的 ACL 規(guī)則,限制客戶(hù)端對(duì)主題的發(fā)布/訂閱權(quán)限。
- 避免明文敏感數(shù)據(jù):即使使用 TLS,也建議對(duì) payload 進(jìn)行加密或脫敏。
資源與性能優(yōu)化
- 消息大小控制:MQTT 不適合傳輸大文件,建議 payload 控制在 KB 級(jí)別。
- 心跳與超時(shí):合理設(shè)置 keepAlive 和 broker 的 session expiry。
- Broker 選型與部署:根據(jù)并發(fā)量選擇合適 Broker(如 Mosquitto、EMQX、HiveMQ),并做好集群與監(jiān)控。
六、與MQTT類(lèi)似的協(xié)議對(duì)比

七、協(xié)議選擇建議
- 如果你的設(shè)備資源極其有限(電池壽命要求高)→ 選CoAP
- 你需要高可靠性和復(fù)雜路由 → 選AMQP
- 你想要簡(jiǎn)單易用的文本協(xié)議 → 選STOMP
- 你需要實(shí)時(shí)交互和擴(kuò)展性 → 選XMPP
- 你主要是管理設(shè)備 → 選LwM2M
到此這篇關(guān)于C#中MQTT的使用小結(jié)的文章就介紹到這了,更多相關(guān)C# MQTT使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# 7.0之ref locals and returns(局部變量和引用返回)
這篇文章主要介紹了C# 7.0之ref locals and returns,即局部變量和引用返回,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
C# WinForm讀取Excel的三種方法及對(duì)比詳解
本文對(duì)比分析了三種方法(Microsoft Interop、EPPlus組件、NPOI)用于讀取Excel數(shù)據(jù),詳細(xì)闡述了各自的特點(diǎn)、優(yōu)勢(shì)及局限性,并通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2025-08-08
c#高效率導(dǎo)出多維表頭excel的實(shí)例代碼
這篇文章介紹了c#高效率導(dǎo)出多維表頭excel的實(shí)例代碼,有需要的朋友可以參考一下2013-11-11

