自己动手写一个基于MQTTnet库的C#MQTT客户端Demo

Demo界面展示与实际效果

自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第1张图片
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第2张图片

写这玩意的原因

主要是因为MQTTnet这个库升级之后旧的API无法使用了,导致之前在网上找到的例子只能用旧的库。对于有升级强迫症的作者有些无法接受。所以花点时间写了一下这个C#的MQTT客户端Demo。

相关资料收集与参考

MQTTnet这个C#库的Github地址为chkr1011/MQTTnet,在这个代码仓库的README.md描述文件中,说明了他的文档在wiki里面。在这里插入图片描述
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第3张图片
在他右侧Client栏中的文档,有这个库最新的API调用示例。
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第4张图片
但是我尝试拿他Client的示例写了个程序,最后发现他示例中的Topic,没法在mqtt建立连接之后再进行订阅,只能在建立连接之前就订阅好。这样就有些局限,查询了资料也没有查到啥解决方案。比如这里mqttnet client not getting subscribed topics
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第5张图片
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第6张图片
回答中也没有给出好的解决方案。
最后在这里找到了一个例子,虽然是.net core 3.1的代码案例,但是也能够使用。
自己动手写一个基于MQTTnet库的C#MQTT客户端Demo_第7张图片
下载这个例子的时候还遇到了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源码下载

MQTT服务器的相关资料

EMQ X 消息服务器简介

你可能感兴趣的:(MQTT)