主要参考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 级别0
WriteLog($"\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。