基於.net C# Socket WinForm MQTT 使用者端開發

2022-11-28 06:02:34

 

1、什麼是MQTT?
  MQTT(Message Queuing Telemetry Transport,訊息佇列遙測傳輸協定),是一種基於釋出/訂閱(publish/subscribe)模式的"輕量級"通訊協定,該協定構建於TCP/IP協定上,由IBM在1999年釋出。MQTT最大優點在於,可以以極少的程式碼和有限的頻寬,為連線遠端裝置提供實時可靠的訊息服務。作為一種低開銷、低頻寬佔用的即時通訊協定,使其在物聯網、小型裝置、移動應用等方面有較廣泛的應用。

  MQTT是一個基於使用者端-伺服器的訊息釋出/訂閱傳輸協定。MQTT協定是輕量、簡單、開放和易於實現的,這些特點使它適用範圍非常廣泛。在很多情況下,包括受限的環境中,如:機器與機器(M2M)通訊和物聯網(IoT)。其在,通過衛星鏈路通訊感測器、偶爾撥號的醫療裝置、智慧家居、及一些小型化裝置中已廣泛使用。
(具體描述自行百度)

 

  本文將基於.Net C# Socket WinForm MQTT 使用者端開發,實現伺服器端連線,訊息釋出,訊息訂閱,取消訂閱及接收伺服器端返回訊息功能。

 

 

2、連線伺服器端

  使用者端連線伺服器端,啟動非同步接收伺服器端訊息。

 1                     //連線選項
 2                     var option = new MQTT.MQTTClientOption()
 3                     {
 4                         ClientId = this.txtClientId.Text,
 5                         IpString = this.txtServer.Text,
 6                         Port = Convert.ToInt32(this.txtPort.Text),
 7                         UserName = this.txtUserName.Text,
 8                         Password = this.txtPassword.Text
 9                     };
10                     //範例使用者端
11                     this.mqttClient = new MQTT.MQTTClient();
12                     this.mqttClient.ClientReceived += MqttClient_ClientReceived;
13                     var result = await this.mqttClient.ConnectAsync(option);
14                     if(result.State == false)
15                     {
16                         MessageBox.Show(result.Fail, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
17                         return;
18                     }
19                     //開始接收
20                     this.mqttClient.BeginReceive();

3、釋出訊息

  使用者端向伺服器端傳送訊息,主要包括主題,內容及訊息質量。

  傳送訊息程式

 1         private short _PacketId = 1;
 2         private async void BtnPublish_Click(object sender, EventArgs e)
 3         {
 4             this.btnPublish.Enabled = false;
 5             this.Cursor = Cursors.WaitCursor;
 6             try
 7             {
 8                 short qos = 0;
 9                 if (rdbLevel1.Checked)
10                     qos = 1;
11                 if (rdbLevel2.Checked)
12                     qos = 2;
13                 
14                 var data = new MQTT.PublishEntity()
15                 {
16                     Topic = this.txtTopic.Text,
17                     Reload = System.Text.Encoding.UTF8.GetBytes(this.txtContent.Text),
18                     Qos = qos,
19                     PacketId=_PacketId
20                 };
21                 var result = await this.mqttClient.PublishAsync(data,false);
22                 if(result.State == false)
23                 {
24                     this.AppendText("傳送失敗:" + result.Fail);
25                     return;
26                 }
27                 this._PacketId++;
28                 this.AppendText("傳送成功,返回結果:" + result.Result);
29             }
30             finally
31             {
32                 this.btnPublish.Enabled = true;
33                 this.Cursor = Cursors.Default;
34             }
35         }

 

4、訂閱訊息

  使用者端訂閱訊息,主要包括過濾主題及訊息質量。

  訂閱訊息方法:

 1 private async void BtnSubscribe_Click(object sender, EventArgs e)
 2         {
 3             this.btnSubscribe.Enabled = false;
 4             this.Cursor = Cursors.WaitCursor;
 5            
 6             try
 7             {
 8                 string fail = string.Empty;
 9 
10                 short qos = 0;
11                 if (rdbQos1.Checked)
12                     qos = 1;
13                 if (rdbQos2.Checked)
14                     qos = 2;
15 
16                 MQTT.SubscribeEntity entity = new MQTT.SubscribeEntity();
17                 entity.Filter = this.txtFilter.Text;
18                 entity.Qos = qos;
19 
20                 this.AppendText("開始訂閱...");
21                 //if (mqttClient.Subscribe(this.txtFilter.Text, qos, out result, out fail) == false)
22                 //{
23                 //    this.AppendText(fail);
24                 //    return;
25                 //}
26                 var result = await mqttClient.SubscribeAsync(entity.Filter,entity.Qos);
27                 if (result.State == false)
28                 {
29                     this.AppendText(result.Fail);
30                     return;
31                 }
32                
33                 this.AppendText("訂閱成功!返回結果:" + result.Result);
34                 MQTT.SubscribeHelper.Save(entity);
35 
36                 DataRow drData = this.dtSubscribes.NewRow();
37                 drData["Id"] = entity.Id;
38                 drData["Filter"] = entity.Filter;
39                 drData["Qos"] = entity.Qos;
40                 drData["Count"] = 0;
41                 dtSubscribes.Rows.Add(drData);
42             }
43             finally
44             {
45                 this.btnSubscribe.Enabled = true;
46                 this.Cursor = Cursors.Default;
47             }
48         }

 

5、取消訂閱

  使用者端取消某一訂閱訊息。雙擊訂閱訊息行,取消訂閱訊息。

 

  取消訂閱方法:

 1         private async void DataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
 2         {
 3             if (this.dataGridView1.CurrentCell == null)
 4                 return;
 5 
 6             DataRowView drv = this.dataGridView1.CurrentRow.DataBoundItem as DataRowView;
 7             if (drv == null)
 8                 return;
 9 
10             if (MessageBox.Show("確認取消當前選擇:" + drv["Filter"].ToString() + " 訂閱?", "確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
11                 return;
12             try
13             {
14                 this.AppendText("開始取消訂閱...");
15                 var result = await mqttClient.UnSubscribeAsync(drv["Filter"].ToString());
16                 if (result.State == false)
17                 {
18                     this.AppendText(result.Fail);
19                     return;
20                 }
21                 this.AppendText("取消訂閱成功!返回結果:" + result.Result);
22                 MQTT.SubscribeHelper.Delete(drv["Id"].ToString());
23                 this.dataGridView1.Rows.RemoveAt(this.dataGridView1.CurrentCell.RowIndex);
24             }
25             catch (Exception ex)
26             {
27                 this.AppendText("取消訂閱異常:" + ex.ToString());
28             }
29 
30         }

 

6、接收伺服器端訊息

  使用者端接收伺服器端轉發過來的訊息。

 

1         private void MqttClient_ClientReceived(MQTT.MQTTClient client, MQTT.ReceiveResult receive)
2         {
3             if(receive.Data != null)
4                 this.AppendText("DataReceived state="+receive.State+" topic="+ receive.Data.Topic + " content=" + System.Text.Encoding.UTF8.GetString(receive.Data.Reload));
5             else if(receive.State)
6                 this.AppendText("DataReceived state=" + receive.State + " result=" + receive.Result);
7             else
8                 this.AppendText("DataReceived state=" + receive.State + " fail=" + receive.Fail);
9         }

 

至此,使用者端工具主要功能簡介完畢,不當之處,歡迎指正!

使用者端下載地址(碼雲伺服器):https://gitee.com/ShiQuan25/full-product-management/raw/master/WinMQTTClient/WinMQTTClient.zip