主要参考C#MQTT编程06--MQTT服务器和客户端(winform版)_c#mqttserver-CSDN博客
但由于使用的.NET版本和MQTT库版本存在差异,因此有些不同。
MQTT协议内容在此不做描述,仅介绍VS使用C#的实现过程。本次使用VS2015,.netframwork4.6。
C#语言本身没有MQTT的库,当然你也可以利用TCP自行完成MQTT协议实现,一般我们采用第三方的mqtt库。
新建一个winform项目,在解决方案资源管理器的“引用”右键,选择“管理Nuget程序包”,找到下面两个包并安装。注意,我这里用的版本是V3.0.0。
接下来根据需要绘制窗体,添加控件。这里有两个按钮,一个连接MQTT服务器,一个是断开,然后就是订阅和发布相关的输入框和按钮。除此以外,我这边需要测试发布几条指令,做到下方的按钮里了,省的手动输入。
接下来是代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Windows.Forms;
using System.Threading.Tasks;using MQTTnet.Protocol;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet;namespace MQTT
{public partial class Form1: Form{private IManagedMqttClient mqttClient;private bool conFlag = false;private int timeout = 0;public Form1(){InitializeComponent();}private async void button1_Click(object sender, EventArgs e){var mqttclientOptions = new MqttClientOptionsBuilder().WithClientId("mushike").WithTcpServer("39.105.165.228", 1883).WithCredentials("admin", "admin");var options = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(5)).WithClientOptions(mqttclientOptions.Build()).Build();//开启await mqttClient.StartAsync(options);timer1.Enabled = true;timeout = 0;}private async void button2_Click(object sender, EventArgs e){if (mqttClient != null){if (mqttClient.IsStarted){await mqttClient.StopAsync();}timer1.Enabled = false;button1.BackColor = SystemColors.Control;}}private void Form1_Load(object sender, EventArgs e){var factory = new MqttFactory();mqttClient = factory.CreateManagedMqttClient();//创建客户端对象//绑定断开事件mqttClient.UseDisconnectedHandler(async ee =>{ // 等待 5s 时间await Task.Delay(TimeSpan.FromMilliseconds(500));WriteLog("\r\n与服务器之间的连接断开");conFlag = false;});//绑定接收事件mqttClient.UseApplicationMessageReceivedHandler(aa =>{try{string msg = aa.ApplicationMessage.ConvertPayloadToString();WriteLog("\r\n>> 收到主题:" + aa.ApplicationMessage.Topic + ",\r\n内容为:" + msg);//WriteLog(">>> 消息:" + msg + ",QoS =" + aa.ApplicationMessage.QualityOfServiceLevel + ",客户端=" + aa.ClientId + ",主题:" + aa.ApplicationMessage.Topic);}catch (Exception ex){WriteLog($"\r\n+ 消息 = " + ex.Message);}});//绑定连接事件mqttClient.UseConnectedHandler(ee =>{WriteLog("\r\n>> 连接到服务器成功");conFlag = true;});}private void WriteLog(string message){if(textBox1.InvokeRequired){textBox1.Invoke(new Action(() =>{textBox1.AppendText(message);}));}else{textBox1.AppendText(message);}}private void button3_Click(object sender, EventArgs e){if (conFlag == false)return;string topic = textBox2.Text;string message = textBox3.Text;mqtt_publish(topic, message);}private async void button4_Click(object sender, EventArgs e){if (conFlag == false)return;string topic = textBox4.Text;if (string.IsNullOrWhiteSpace(topic)){WriteLog("\r\n>> 请输入主题");return;}await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic).WithAtMostOnceQoS().Build());//最多一次, QoS 级别0WriteLog($"\r\n>> 成功订阅");}private async void mqtt_publish(string topic,string message){if (conFlag == false)return;if (string.IsNullOrWhiteSpace(topic)){WriteLog("\r\n>> 请输入主题");return;}var result = await mqttClient.PublishAsync(topic,message,MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);//恰好一次, QoS 级别1 WriteLog($"\r\n>> 主题:{topic},\r\n消息:{message},\r\n结果: {result.ReasonCode}");}private void textBox1_MouseDoubleClick(object sender, MouseEventArgs e){this.textBox1.Text = "";}private void timer1_Tick(object sender, EventArgs e){timeout++;if (conFlag == true){button1.BackColor = Color.Green;timer1.Enabled = false;}else{if (timeout > 30){timeout = 0;timer1.Enabled = false;WriteLog("\r\n>> 连接服务器失败");}}}private void button11_Click(object sender, EventArgs e){string topic = "test111";string message = "#01R00\r";mqtt_publish(topic, message);}private void button10_Click(object sender, EventArgs e){string topic = "test111";string message = "#01R01\r";mqtt_publish(topic, message);}private void button5_MouseDown(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000100000000E4";mqtt_publish(topic, message);}private void button5_MouseUp(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000000000E5";mqtt_publish(topic, message);}private void button6_MouseDown(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000200000000E3";mqtt_publish(topic, message);}private void button6_MouseUp(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000000000E5";mqtt_publish(topic, message);}private void button8_MouseDown(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000020000E3";mqtt_publish(topic, message);}private void button8_MouseUp(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000000000E5";mqtt_publish(topic, message);}private void button7_MouseDown(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000040000E1";mqtt_publish(topic, message);}private void button7_MouseUp(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000000000E5";mqtt_publish(topic, message);}private void button9_MouseDown(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000020000000C5";mqtt_publish(topic, message);}private void button9_MouseUp(object sender, MouseEventArgs e){string topic = "test333";string message = "F10209100000000000000000E5";mqtt_publish(topic, message);}}
}
本次参照 C#MQTT编程06--MQTT服务器和客户端(winform版)_c#mqttserver-CSDN博客 编写MQTT相关的代码时,报了一堆错,本质原因还是版本不一致导致,比如使用参考博客的MQTTNet V3.0.15就用不了。因此需要特别注意,本次使用的环境为VS2015+.Net 4.6+MQTTNet V3.0.0。