C#如何MQTTnet实现MQTT协议操作设备

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Receiving;

namespace Base
{
    /// <summary>
    /// level 0:最多一次的传输
    /// level 1:至少一次的传输
    /// level 2: 只有一次的传输
    /// </summary>
    public class MQTTClient
    {
        private MqttClient mqttClient = null;
        public delegate void StrMsgHandler(string msg, string destIP);
        public event StrMsgHandler OnMessage = null;
        public event StrMsgHandler OnError = null;
        public delegate void CommandHandler(MQTTClient sender, DateTime time, string jsonStrCmd);
        public event CommandHandler OnCommand = null;
        public bool TransDataFlag = false;
        private string Server = "127.0.0.1";
        private int Port = 1883;
        public bool IsConnected
        {
            get
            {
                return mqttClient.IsConnected;
            }
        }

        public MQTTClient(string server, int port)
        {
            connect(server, port);
            Server = server;
            Port = port;
        }

        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="server"></param>
        /// <param name="port"></param>
        private void connect(string server, int port)
        {
            if (mqttClient == null)
            {
                mqttClient = new MqttFactory().CreateMqttClient() as MqttClient;
            }
            //定义遗嘱消息
            var will = new MqttApplicationMessageBuilder()
                .WithTopic("Code/status")
                .WithPayload(System.Text.Encoding.UTF8.GetBytes("offline"))
                .WithAtLeastOnceQoS()//至少一次
                .WithRetainFlag()
                .Build();
            //var will2 = new MqttApplicationMessage(){ Topic = "PLC/status", Payload = System.Text.Encoding.UTF8.GetBytes("offline") };//定义遗嘱消息
            var options = new MqttClientOptionsBuilder()
                .WithTcpServer(server, port) // Port is optional
                .WithClientId("Code")
                .WithWillMessage(will)
                .Build();
            mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken

            mqttClient.UseConnectedHandler(async e =>
            {
                // Subscribe to a topic
                var topicFilterBulder = new MqttTopicFilterBuilder().WithTopic("Code/write").WithAtMostOnceQoS().Build();
                await mqttClient.SubscribeAsync(topicFilterBulder);

                // 连接MQTT时发送online
                byte[] payload = ASCIIEncoding.UTF8.GetBytes("online");
                var sendmessage = new MqttApplicationMessageBuilder()
                    .WithTopic("Code/status")
                    .WithPayload(payload)
                    .WithAtLeastOnceQoS()//至少一次
                    .WithRetainFlag()
                    .Build();
                await mqttClient.PublishAsync(sendmessage, CancellationToken.None);
            });

            mqttClient.UseDisconnectedHandler(async e =>
            {// Reconnect
                await Task.Delay(TimeSpan.FromSeconds(10));

                try
                {
                    connect(server, port);
                }
                catch (Exception ex)
                {
                    ShowError(ex.Message, "");
                }
            });

            Func<MqttApplicationMessageReceivedEventArgs, Task> func = MqttApplicationMessageReceived;
            mqttClient.UseApplicationMessageReceivedHandler(func);

            //mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(new Func<MqttClientConnectedEventArgs, Task>(Connected));
            //mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(new Func<MqttClientDisconnectedEventArgs, Task>(Disconnected));
            //mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(new Func<MqttApplicationMessageReceivedEventArgs>(MqttApplicationMessageReceived));
        }

        //private async Task Connected(MqttClientConnectedEventArgs e)
        //{
        //    try
        //    {
        //        //List<TopicFilter> listTopic = new List<TopicFilter>();
        //        //if (listTopic.Count() <= 0)
        //        //{
        //        //    var topicFilterBulder = new TopicFilterBuilder().WithTopic("PLC/write").WithAtMostOnceQoS().Build();
        //        //    listTopic.Add(topicFilterBulder);
        //        //    //Console.WriteLine("Connected >>Subscribe " + Topic);
        //        //}
        //        //await mqttClient.SubscribeAsync(listTopic.ToArray());
        //        //Console.WriteLine("Connected >>Subscribe Success");
        //        var topicFilterBulder = new TopicFilterBuilder().WithTopic("PLC/write").WithAtMostOnceQoS().Build();
        //        await mqttClient.SubscribeAsync(topicFilterBulder);
        //    }
        //    catch (Exception ex)
        //    {
        //        ShowError(ex.Message, "");
        //    }
        //}

        //private async Task Disconnected(MqttClientDisconnectedEventArgs e)
        //{
        //    try
        //    {
        //        Console.WriteLine("Disconnected >>Disconnected Server");
        //        await Task.Delay(TimeSpan.FromSeconds(10));
        //        try
        //        {
        //            connect(Server,Port);
        //        }
        //        catch (Exception exp)
        //        {
        //            Console.WriteLine("Disconnected >>Exception " + exp.Message);
        //        }
        //    }
        //    catch (Exception exp)
        //    {
        //        Console.WriteLine(exp.Message);
        //    }
        //}

        private Task MqttApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs arg)
        {
            try
            {
                byte[] data = arg.ApplicationMessage.Payload;
                DateTime time = DateTime.Now;
                string jsonStr = ASCIIEncoding.ASCII.GetString(data, 0, data.Length);
                HandleCommand(this, time, jsonStr);//处理数据
            }
            catch (Exception ex)
            {
                ShowError(ex.Message, "");
            }
            //throw new NotImplementedException();
            return Task.FromResult(0);
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="payload"></param>
        public void publish(string topic, string jsonStr)
        {
            byte[] payload = ASCIIEncoding.UTF8.GetBytes(jsonStr);
            var sendmessage = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(payload)
                .WithAtMostOnceQoS()
                .WithRetainFlag()
                .Build();
            mqttClient.PublishAsync(sendmessage, CancellationToken.None); // Since 3.0.5 with CancellationToken
        }

        internal void ShowMessage(string msg, string destIP)
        {
            try
            {
                if (OnMessage != null)
                    OnMessage(msg, destIP);
            }
            catch { }
        }

        internal void ShowError(string msg, string destIP)
        {
            try
            {
                if (OnError != null)
                    OnError(msg, destIP);
            }
            catch { }
        }

        internal void HandleCommand(MQTTClient sender, DateTime time, string jsonStrCmd)
        {
            if (OnCommand != null)
            {
                OnCommand(sender, time, jsonStrCmd);
            }
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

!chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值