Demo界面展示与实际效果
写这玩意的原因
主要是因为MQTTnet
这个库升级之后旧的API无法使用了,导致之前在网上找到的例子只能用旧的库。对于有升级强迫症的作者有些无法接受。所以花点时间写了一下这个C#的MQTT客户端Demo。
相关资料收集与参考
MQTTnet
这个C#库的Github地址为chkr1011/MQTTnet,在这个代码仓库的README.md
描述文件中,说明了他的文档在wiki里面。
在他右侧Client栏中的文档,有这个库最新的API调用示例。
但是我尝试拿他Client的示例写了个程序,最后发现他示例中的Topic,没法在mqtt建立连接之后再进行订阅,只能在建立连接之前就订阅好。这样就有些局限,查询了资料也没有查到啥解决方案。比如这里mqttnet client not getting subscribed topics
回答中也没有给出好的解决方案。
最后在这里找到了一个例子,虽然是.net core 3.1
的代码案例,但是也能够使用。
下载这个例子的时候还遇到了visual studio无法打开项目的问题,说是没有找到.net core 3.1的SDK,最后直接直接用文本文件看了他的Form1.cs
的代码。
主要代码
这个方法主要用于生成一个MQTT的Client,用来处理消息事件,发送消息等。
private async Task SubscriberStart()
{
var tcpServer = tbx_mqtt_server.Text;
var tcpPort = int.Parse(tbx_mqtt_port.Text.Trim());
var mqttUser = tbx_user_name.Text.Trim();
var mqttPassword = tbx_pwd.Text.Trim();
var mqttFactory = new MqttFactory();
this.options = new MqttClientOptions
{
ClientId = "ClientSubscriber",
ProtocolVersion = MqttProtocolVersion.V311,
ChannelOptions = new MqttClientTcpOptions
{
Server = tcpServer,
Port = tcpPort
}
};
if (options.ChannelOptions == null)
{
throw new InvalidOperationException();
}
if(!string.IsNullOrEmpty(mqttUser))
{
options.Credentials = new MqttClientCredentials
{
Username = mqttUser,
Password = Encoding.UTF8.GetBytes(mqttPassword)
};
}
options.CleanSession = true;
options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
this.mqttClient = mqttFactory.CreateManagedMqttClient();
this.mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);
this.mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);
this.mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscriberMessageReceived);
await this.mqttClient.StartAsync(
new ManagedMqttClientOptions
{
ClientOptions = options
});
}
处理消息的方法
private void OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs x)
{
var payloadString = x.ApplicationMessage.ConvertPayloadToString();
payloadString = ConvertJsonString(payloadString);
var item = $"{Environment.NewLine}Topic: {x.ApplicationMessage.Topic}{Environment.NewLine}Payload: {payloadString} {Environment.NewLine}QoS: {x.ApplicationMessage.QualityOfServiceLevel}";
this.BeginInvoke((MethodInvoker)delegate
{
AppendReceiveMsg(item);
});
}
发送消息的方法
private async void btn_send_msg_Click(object sender, EventArgs e)
{
var publish_topic = tbx_publish_topic.Text.Trim();
var publish_msg = tbx_send_msg.Text;
var message = new MqttApplicationMessageBuilder()
.WithTopic(publish_topic)
.WithPayload(publish_msg)
.WithExactlyOnceQoS()
.Build();
if (this.mqttClient != null)
{
await this.mqttClient.PublishAsync(message);
}
}
本文Demo的下载地址
MQTT客户端Demo源码下载(20210904更新)