ASP.NET Core 实现 MQTT通讯协议 Demo(开源库:MQTTnet)

摘要:
由于上述轻量级特性,它是智能家居的首选传输协议。与XMPP相比,它更轻量化,占用的宽带更少。简单地说,HQTT是一种通信协议,必须遵循该协议才能实现发布/订阅=“PASS”){p.ReasonCode=MqttConnectReasonCode.BadUserNameOrPassword;}})};//设置端口号选项。DefaultEndpointOptions。端口=8031//创建Mqtt服务器mqttServer=newMqttFactory()。CreateMqttServer()//启动订阅事件mqttServer ClientSubscriptedTopicHandler=newMqttServerClientSubscribedHandlerDelegate;//取消订阅事件mqttServer ClientUnsubscribedTopicHandler=newMqttServerClientUnsubscriptedTopicHandlerDelegate;//客户端消息事件mqttServer。UseApplicationMessageReceivedHandler//客户端连接事件mqttServer。UseClientConnectedHandler//客户端断开连接事件mqttServer。UseClientDisconnectedHandler//启动服务器awaitmqttServer。启动异步;安慰WriteLine(“服务器成功启动!

1、什么是MQTT

  MQTT(message queuing telemetry transport)是IBM开发的即时通讯协议,是一种发布/订阅极其轻量级的消息传输协议,专门为网络受限设备、低宽带以及高延迟和不可靠的网络而设计的。由于以上轻量级的特点,是实现智能家居的首选传输协议,相比于XMPP,更加轻量级而且占用宽带低。简单来说HQTT是一种通信协议,要实现发布/订阅就必须遵循这个协议。

2、实现MQTT通讯协议.NET开源库有哪些?

  MQTTnet、MqttDotNet、nMQTT、M2MQTT等,这里我们使用MQTTnet(但MQTTnet搜到的教程基本都是2.7及以下版本的,我们使用的是3.0.9版本)

3、展示MQTT实现效果图

  ASP.NET Core 实现 MQTT通讯协议 Demo(开源库:MQTTnet)第1张

  例:客户端1只要订阅了positon主题,客户端2、客户端3、客户端4.....同样订阅了position主题则他们之间就能共享position主题的所发的内容了

  如果客户端1订阅了position主题,客户端2订阅了beautiful主题,1发给消息2是收不到的。

4、创建.NETCore项目(Server和Client)

  ASP.NET Core 实现 MQTT通讯协议 Demo(开源库:MQTTnet)第2张

5、服务器

  添加Nuget包:安装MQTTnet

  ASP.NET Core 实现 MQTT通讯协议 Demo(开源库:MQTTnet)第3张

class Program
    {
        public static IMqttServer mqttServer;
        static void Main(string[] args)
        {
            StartMqttServer();
        }

        //启动Mqtt服务器
        private static async void StartMqttServer()
        {
            try
            {
                //验证客户端信息
                var options = new MqttServerOptions
                {
                    //连接验证
                    ConnectionValidator = new MqttServerConnectionValidatorDelegate(p =>
                    {
                        if (p.ClientId == "SpecialClient")
                        {
                            if (p.Username != "USER" || p.Password != "PASS")
                            {
                                p.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                            }
                        }
                    })
                };

                //设置端口号
                options.DefaultEndpointOptions.Port = 8031;

                //创建Mqtt服务器
                mqttServer = new MqttFactory().CreateMqttServer();

                //开启订阅事件
                mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(MqttNetServer_SubscribedTopic);

                //取消订阅事件
                mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(MqttNetServer_UnSubscribedTopic);

                //客户端消息事件
                mqttServer.UseApplicationMessageReceivedHandler(MqttServe_ApplicationMessageReceived);

                //客户端连接事件
                mqttServer.UseClientConnectedHandler(MqttNetServer_ClientConnected);

                //客户端断开事件
                mqttServer.UseClientDisconnectedHandler(MqttNetServer_ClientDisConnected);

                //启动服务器
                await mqttServer.StartAsync(options);

                Console.WriteLine("服务器启动成功!输入任意内容并回车停止服务!");
                Console.ReadLine();

                await mqttServer.StopAsync();
            }
            catch (Exception e)
            {
                Console.Write($"服务器启动失败 Msg:{e}");
            }

        }

        /// <summary>
        /// 客户订阅
        /// </summary>
        private static void MqttNetServer_SubscribedTopic(MqttServerClientSubscribedTopicEventArgs e)
        {
            //客户端Id
            var ClientId = e.ClientId;
            var Topic = e.TopicFilter.Topic;
            Console.WriteLine($"客户端[{ClientId}]已订阅主题:{Topic}");
        }

        /// <summary>
        /// 客户取消订阅
        /// </summary>
        private static void MqttNetServer_UnSubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs e)
        {
            //客户端Id
            var ClientId = e.ClientId;
            var Topic = e.TopicFilter;
            Console.WriteLine($"客户端[{ClientId}]已取消订阅主题:{Topic}");
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        private static void MqttServe_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            var ClientId = e.ClientId;
            var Topic = e.ApplicationMessage.Topic;
            var Payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
            var Qos = e.ApplicationMessage.QualityOfServiceLevel;
            var Retain = e.ApplicationMessage.Retain;
            Console.WriteLine($"客户端[{ClientId}]>> 主题:[{Topic}] 负载:[{Payload}] Qos:[{Qos}] 保留:[{Retain}]");
        }

        /// <summary>
        /// 客户连接
        /// </summary>
        private static void MqttNetServer_ClientConnected(MqttServerClientConnectedEventArgs e)
        {
            var ClientId = e.ClientId;
            Console.WriteLine($"客户端[{ClientId}]已连接");
        }

        /// <summary>
        /// 客户连接断开
        /// </summary>
        private static void MqttNetServer_ClientDisConnected(MqttServerClientDisconnectedEventArgs e)
        {
            var ClientId = e.ClientId;
            Console.WriteLine($"客户端[{ClientId}]已断开连接");
        }
    }

6、客户端

  也要添加Nuget包:安装MQTTnet

 public static IMqttClient mqttClient;

        static void Main(string[] args)
        {
            ConnectMqttServerAsync();
            ImportData();
        }
        private static async void ConnectMqttServerAsync()
        {
            try
            {

                var factory = new MqttFactory();

                mqttClient = factory.CreateMqttClient();

                var options = new MqttClientOptionsBuilder()
                    .WithTcpServer("127.0.0.1", 8031)
                    .WithCredentials("test", "test")
                    .WithClientId(Guid.NewGuid().ToString().Substring(0, 5))
                    .Build();

                //消息
                mqttClient.UseApplicationMessageReceivedHandler(e =>
                {
                    Console.WriteLine("### 收到的信息 ###");
                    Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");//主题
                    Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");//页面信息
                    Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");//消息等级
                    Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");//是否保留
                    Console.WriteLine();
                });

                //重连机制
                mqttClient.UseDisconnectedHandler(async e =>
                {
                    Console.WriteLine("与服务器断开连接!");
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    try
                    {
                        await mqttClient.ConnectAsync(options);
                    }
                    catch (Exception exp)
                    {
                        Console.Write($"重新连接服务器失败 Msg:{exp}");
                    }
                });

               await mqttClient.ConnectAsync(options);

               Console.Write("连接服务器成功!输入任意内容并回车进入菜单页面!");
            }
            catch (Exception exp)
            {
                Console.Write($"连接服务器失败 Msg:{exp}");
            }
        }

        private static void ImportData()
        {
            Console.ReadLine();
            bool isExit = false;
            while (!isExit)
            {
                Console.WriteLine(@"请输入
                    1.订阅主题
                    2.取消订阅
                    3.发送消息
                    4.退出");
                var input = Console.ReadLine();

                switch (input)
                {
                    case "1":
                        Console.WriteLine(@"请输入主题名称:");
                        var topicName = Console.ReadLine();
                        Subscribe(topicName);
                        break;
                    case "2":
                        Console.WriteLine(@"请输入需要取消订阅主题名称:");
                        topicName = Console.ReadLine();
                        Unsubscribe(topicName);
                        break;
                    case "3":
                        Console.WriteLine("请输入需要发送的主题名称");
                        topicName = Console.ReadLine();
                        Console.WriteLine("请输入需要发送的消息");
                        var message = Console.ReadLine();
                        Publish(topicName, message);
                        break;
                    case "4":
                        isExit = true;
                        break;
                    default:
                        Console.WriteLine("请输入正确指令!");
                        break;
                }
            }
        }

        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="topicName"></param>
        private static async void Subscribe(string topicName)
        {
            string topic = topicName.Trim();
            if (string.IsNullOrEmpty(topic))
            {
                Console.Write("订阅主题不能为空!");
                return;
            }

            if (!mqttClient.IsConnected)
            {
                Console.Write("MQTT客户端尚未连接!");
                return;
            }
            await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic).Build());
        }

        /// <summary>
        /// 取消订阅
        /// </summary>
        /// <param name="topicName"></param>
        private static async void Unsubscribe(string topicName)
        {
            string topic = topicName.Trim();
            if (string.IsNullOrEmpty(topic))
            {
                Console.Write("订阅主题不能为空!");
                return;
            }

            if (!mqttClient.IsConnected)
            {
                Console.Write("MQTT客户端尚未连接!");
                return;
            }
            await mqttClient.UnsubscribeAsync(topic);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        private static async void Publish(string topicName, string message)
        {
            string topic = topicName.Trim();
            string msg = message.Trim();

            if (string.IsNullOrEmpty(topic))
            {
                Console.Write("主题不能为空!");
                return;
            }
            if (!mqttClient.IsConnected)
            {
                Console.Write("MQTT客户端尚未连接!");
                return;
            }

            var MessageBuilder = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(msg)
                .WithExactlyOnceQoS()
                .WithRetainFlag()
                .Build();

            await mqttClient.PublishAsync(MessageBuilder);

        }

  源代码:

  链接:https://pan.baidu.com/s/1rxTBZHHAmkDVcO6XmJPXng
  提取码:05qr
  后续会陆续更新其他资料,喜欢请关注哦!

免责声明:文章转载自《ASP.NET Core 实现 MQTT通讯协议 Demo(开源库:MQTTnet)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JavaScript 清空SessionSQL Server 执行计划缓存下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

安卓中的线程

 1. Android进程    在了解Android线程之前得先了解一下Android的进程。当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默认的情况下,所有该程序的组件都将在该进程和线程中运行。同时,Android会为每个应用程序分配一个单独的LINUX用户。Android会尽量保留一个正在运行进程,只在内存资源出现...

.NET操作Excel笔记

如果你新建一个项目的话,首先要添加Microsoft.Office.Core 与Microsoft.Office.Interop.Exce这两个应用,然后就能很方便的操作了,示例代码(只实现了简单的读写):   1 privateExcel._Application excelApp;  2 privateWorkbook wbclass; ...

微信退款和支付宝退款接口调用(java版)

项目中需要使用到微信和支付宝的退款功能,在这两天研究了一下这两个平台的退款,有很多坑,在开发中需要留意 1、微信退款接口相对来说我感觉微信的退款接口还是比较好调用的,直接发送httppost请求即可; /** * * @方法名称:payRefund * @内容摘要: <退款> *@param transactio...

关于HTTP协议头域详解

HTTP1.1  请求头:消息头   Accept:text/html,image/*  告诉服务器,客户机支持的数据类型 Accept-Charset:ISO-8859-1  告诉服务器,客户机采用的编码   Accept-EnCoding:gzip,compress 告诉服务器,客户机支持的数据压缩格式 Accept-Language:en   客户机...

ASP.NET中进行消息处理(MSMQ) 二

      在我上一篇文章《ASP.NET中进行消息处理(MSMQ)一》里对MSMQ做了个通俗的介绍,最后以发送普通文本消息和复杂的对象消息为例介绍了消息队列的使用。 本文在此基础上继续介绍MSMQ的相关知识点,最后还是通过一个示例程序来分析MSMQ在实际项目开发中的应用。 建议:如果你对MSMQ不够了解,在你阅读本文前请先阅读第一部分:《ASP.NET中...

PHP教程:PHPUnit学习笔记(四)断言详解

断言(Assertions)是PHPUnit提供的一系列对程序执行结果测试的方法。通俗的讲,就是断言执行程序结果为我们期待的值,如果不是则 测试失败,下面是断言方法的详细介绍,内容全部来翻译自PHPUnit的官方文档,部分方法官方介绍的很模糊,我根据官方的源码注释增加了说明和注释 assertArrayHasKey(mixed $key, array $a...