基于C#實現(xiàn)MQTT通信實戰(zhàn)
MQTT(Message Queueing Telemetry Transport) 消息隊列遙測傳輸,在物聯(lián)網(wǎng)領(lǐng)域應(yīng)用的很廣泛,它是基于Publish/Subscribe模式,具有簡單易用,支持QoS,傳輸效率高的特點。
它被設(shè)計用于低帶寬,不穩(wěn)定或高延遲的網(wǎng)絡(luò)環(huán)境,因此非常適合于設(shè)備之間的數(shù)據(jù)通信。
EMQX提供了MQTT的服務(wù)器,并且可以在后臺網(wǎng)頁查看面板,還支持中文顯示。
由于5.0之后的版本不再支持Windows所以使用的是4.0版本的包,在下載完壓縮包后,不用安裝,進入cmd導(dǎo)航到安裝的bin目錄下(注意:路徑中不能包含中文),執(zhí)行命令:emqx start,看見沒有報錯就說明啟動成功了。
之后在瀏覽器里輸入:http://127.0.0.1:18083 進入面板。

在WebSocket菜單里可以模擬發(fā)布/訂閱的操作,接下來我們將使用C#完成這一系列的操作。
1、連接主機
首先新建一個WPF項目,然后在Nuget中下載MQTTnet。
// 連接主機
MqttFactory factory = new MqttFactory();
_client = factory.CreateMqttClient();
var options = new MqttClientOptionsBuilder().
WithTcpServer(this.ipAddress.Text, Convert.ToInt32(this.port.Text))
.WithClientId(this.clientId.Text)
.Build();
var result = await _client.ConnectAsync(options, CancellationToken.None);
if (result.ResultCode == MqttClientConnectResultCode.Success)
{
this.log.Text = DateTime.Now.ToString() + " 連接成功" + Environment.NewLine + this.log.Text;
}
else
{
this.log.Text = DateTime.Now.ToString() + $" 連接失敗,{result.ReasonString}" + Environment.NewLine + this.log.Text;
return;
}2、訂閱消息
訂閱消息分為兩塊,一個是消息的回顯,一個是訂閱消息。
// 訂閱消息
var option = new MqttClientSubscribeOptions();
MqttQualityOfServiceLevel level;
switch (this.subscribeQos.SelectedIndex)
{
case 0:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce;
break;
case 1:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce;
break;
case 2:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
break;
default:
throw new Exception("請選擇服務(wù)質(zhì)量");
}
option.TopicFilters = new List<MqttTopicFilter>()
{
new MqttTopicFilter()
{
Topic = this.subscribeTopic.Text,
QualityOfServiceLevel = level
}
};
this._client.SubscribeAsync(option, CancellationToken.None);
// 將訂閱的消息回顯到日志區(qū)
this._client.ApplicationMessageReceivedAsync += e =>
{
var task = Task.Factory.StartNew(() => {
try
{
var array = e.ApplicationMessage.PayloadSegment.Array;
if (array == null)
{
return;
}
var str = Encoding.UTF8.GetString(array);
// 跨線程更新UI
Application.Current.Dispatcher.Invoke(() => {
this.log.Text = DateTime.Now.ToString() + " 收到消息:" + str + Environment.NewLine + this.log.Text;
});
}
catch (Exception ex)
{
this.log.Text = DateTime.Now.ToString() + $" {ex.Message}" + Environment.NewLine + this.log.Text;
}
});
return task;
};
this.log.Text = DateTime.Now.ToString() + " 訂閱成功" + Environment.NewLine + this.log.Text;訂閱消息只需要兩個參數(shù):主題Topic和服務(wù)質(zhì)量QoC,主題是用來區(qū)分不同頻段的消息,避免出現(xiàn)沖突,如果想接收到所有的消息可以這么寫:topicXXX/#,#就代表不限制范圍,如果打算只接受固定區(qū)域的消息,則需要將#改成某個字符串。
服務(wù)質(zhì)量QoC是用來控制可用性的,0是最低等級,最多只發(fā)送一次,1是中級,至少發(fā)一次,但有可能出現(xiàn)重復(fù)接收的情況,2是最高級,只發(fā)一次,不會多也不會少。
將消息回顯需要注冊ApplicationMessageReceivedAsync事件,傳入的參數(shù)是回顯對象,返回值是一個Task類型,是在Task中獲取回顯的值并完成控件的更新操作。
3、發(fā)布消息
發(fā)布消息的參數(shù)比訂閱多兩個:消息內(nèi)容Payload,持久會話(在恢復(fù)連接后保留之前的訂閱和消息傳遞狀態(tài))
var msg = new MqttApplicationMessage();
msg.Topic = this.topic.Text;
msg.PayloadSegment = Encoding.UTF8.GetBytes(this.msg.Text);
msg.Retain = isSave.IsChecked??false;
MqttQualityOfServiceLevel level;
switch (this.publishQos.SelectedIndex)
{
case 0:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce;
break;
case 1:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce;
break;
case 2:
level = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
break;
default:
throw new Exception("請選擇服務(wù)質(zhì)量");
}
msg.QualityOfServiceLevel = level;
var resultPublish = await _client.PublishAsync(msg, CancellationToken.None);
if (resultPublish.IsSuccess == true)
{
this.log.Text = DateTime.Now.ToString() + " 發(fā)送成功" + Environment.NewLine + this.log.Text;
}
else
{
this.log.Text = DateTime.Now.ToString() + " 發(fā)送失敗" + Environment.NewLine + this.log.Text;
}到此這篇關(guān)于基于C#實現(xiàn)MQTT通信實戰(zhàn)的文章就介紹到這了,更多相關(guān)C# MQTT通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中Hashtable和Dictionary的區(qū)別
Hashtable 和 Dictionary 都是 C# 中用于存儲鍵值對的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了C#中Hashtable和Dictionary的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-04-04
C#實現(xiàn)千萬數(shù)據(jù)秒級導(dǎo)入的代碼
在實際開發(fā)中excel導(dǎo)入很常見,現(xiàn)代社會中很容易遇到大數(shù)據(jù)處理業(yè)務(wù),所以本文我就給大家分享一下千萬數(shù)據(jù)秒級導(dǎo)入怎么實現(xiàn),文中有詳細的代碼示例供大家參考,需要的朋友可以參考下2025-09-09
C# string格式的日期時間字符串轉(zhuǎn)為DateTime類型的方法
這篇文章主要介紹了C# string格式的日期時間字符串轉(zhuǎn)為DateTime類型的方法,需要的朋友可以參考下2017-02-02

