• MQTTnet 3.1.2使用Demo


    MQTT消息使用场景广泛,在本地做了个小demo。服务器使用的MQTTnet 3.1.2版本,最新4.1.0版本服务器权限认证网上没找到,所以就使用3.1.2版本了。

    一、服务端

    引用MQTTnet 3.1.2版本

    using MQTT;
    using MQTTnet.Client;
    using MQTTnet.Protocol;
    using MQTTnet;
    using MQTTnet.Server;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using MQTTnet.Client.Receiving;
    
    namespace MQTT
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                MqttServerClass serverClass = new MqttServerClass();
                serverClass.StartMqttServer().Wait();
                Console.ReadLine();
            }
        }
        public static class Config
        {
            public static int Port { get; set; } = 1883;
            public static string UserName { get; set; } = "cyw";
            public static string Password { get; set; } = "123456";
    
        }
        public class UserInstance
        {
            public string ClientId { get; set; }
            public string UserName { get; set; }
            public string Password { get; set; }
        }
        public class MqttServerClass
        {
            private IMqttServer mqttServer;
            private List<MqttApplicationMessage> messages = new List<MqttApplicationMessage>();
            public async Task StartMqttServer()
            {
                try
                {
                    if (mqttServer == null)
                    {
                        var optionsBuilder = new MqttServerOptionsBuilder()
                            .WithDefaultEndpoint()
                            .WithDefaultEndpointPort(Config.Port)
                            .WithConnectionValidator(
                             c =>
                             {
                                 var flag = c.Username == Config.UserName && c.Password == Config.Password;
                                 if (!flag)
                                 {
                                     c.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                                     return;
                                 }
                                 //设置代码为 Success
                                 c.ReasonCode = MqttConnectReasonCode.Success;
                                 //instances.Add(new UserInstance()  //缓存到内存的List集合当中
                                 //{
                                 //    ClientId = c.ClientId,
                                 //    UserName = c.Username,
                                 //    Password = c.Password
                                 //});
                             })
                            //订阅拦截器
                            .WithSubscriptionInterceptor(
                                            c =>
                                            {
                                                if (c == null) return;
                                                c.AcceptSubscription = true;
                                            })
                            //应用程序消息拦截器
                            .WithApplicationMessageInterceptor(
                                            c =>
                                            {
                                                if (c == null) return;
                                                c.AcceptPublish = true;
                                            })
                            //clean sesison是否生效
                            .WithPersistentSessions();
                        mqttServer = new MqttFactory().CreateMqttServer();
    
                        //客户端断开连接拦截器
                        //mqttServer.UseClientDisconnectedHandler(c =>
                        //{
                        //    //var user = instances.FirstOrDefault(t => t.ClientId == c.ClientId);
                        //    //if (user != null)
                        //    //{
                        //    //    instances.Remove(user);
                        //    //}
                        //});
    
                        //服务开始
                        mqttServer.StartedHandler = new MqttServerStartedHandlerDelegate(OnMqttServerStarted);
                        //服务停止
                        mqttServer.StoppedHandler = new MqttServerStoppedHandlerDelegate(OnMqttServerStopped);
                        //客户端连接
                        mqttServer.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(OnMqttServerClientConnected);
                        //客户端断开连接(此事件会覆盖拦截器)
                        mqttServer.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(OnMqttServerClientDisconnected);
                        //客户端订阅
                        mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedTopicHandlerDelegate(OnMqttServerClientSubscribedTopic);
                        //客户端取消订阅
                        mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(OnMqttServerClientUnsubscribedTopic);
                        //服务端收到消息
                        mqttServer.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnMqttServerApplicationMessageReceived);
    
                        await mqttServer.StartAsync(optionsBuilder.Build());
    
                        //主动发送消息到客户端
                        //await mqttServer.PublishAsync(new
                        //     MqttApplicationMessage
                        //{
                        //    Topic = "testtopic",
                        //    Payload = Encoding.UTF8.GetBytes("dsdsd")
                        //});
                        //mqttServer.GetClientStatusAsync();
                        //mqttServer.GetRetainedApplicationMessagesAsync();
                        //mqttServer.GetSessionStatusAsync();
    
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"MQTT Server start fail.>{ex.Message}");
                }
            }
            private void OnMqttServerStarted(EventArgs e)
            {
                if (mqttServer.IsStarted)
                {
                    Console.WriteLine("MQTT服务启动完成!");
                }
            }
            private void OnMqttServerStopped(EventArgs e)
            {
                if (!mqttServer.IsStarted)
                {
                    Console.WriteLine("MQTT服务停止完成!");
                }
            }
            private void OnMqttServerClientConnected(MqttServerClientConnectedEventArgs e)
            {
                Console.WriteLine($"客户端[{e.ClientId}]已连接");
            }
            private void OnMqttServerClientDisconnected(MqttServerClientDisconnectedEventArgs e)
            {
                Console.WriteLine($"客户端[{e.ClientId}]已断开连接!");
            }
            private void OnMqttServerClientSubscribedTopic(MqttServerClientSubscribedTopicEventArgs e)
            {
                Console.WriteLine($"客户端[{e.ClientId}]已成功订阅主题[{e.TopicFilter}]!");
            }
            private void OnMqttServerClientUnsubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs e)
            {
                Console.WriteLine($"客户端[{e.ClientId}]已成功取消订阅主题[{e.TopicFilter}]!");
            }
            private void OnMqttServerApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
            {
                messages.Add(e.ApplicationMessage);
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
                Console.WriteLine($"客户端[{e.ClientId}]>> Topic[{e.ApplicationMessage.Topic}] Payload[{Encoding.UTF8.GetString(e.ApplicationMessage.Payload ?? new byte[] { })}] Qos[{e.ApplicationMessage.QualityOfServiceLevel}] Retain[{e.ApplicationMessage.Retain}]");
            }
        }
    }
    View Code

    二、订阅消息

    引用的MQTTnet最新4.1.0版本,新增MqttClientService类,实例化client。然后连接到服务端后订阅topic。

    using MQTTnet;
    using MQTTnet.Client;
    using MQTTnet.Protocol;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MQTTClient
    {
        public class MqttClientService
        {
            public static IMqttClient _mqttClient;
            public IMqttClient MqttClientStart(string ip, int port, string username, string pwd, string clientId)
            {
                var optionsBuilder = new MqttClientOptionsBuilder()
                    .WithTcpServer(ip, port) // 要访问的mqtt服务端的 ip 和 端口号
                    .WithCredentials(username, pwd) // 要访问的mqtt服务端的用户名和密码
                    .WithClientId(clientId) // 设置客户端id
                    .WithCleanSession()
                    .WithTls(new MqttClientOptionsBuilderTlsParameters
                    {
                        UseTls = false  // 是否使用 tls加密
                    });
    
                var clientOptions = optionsBuilder.Build();
                _mqttClient = new MqttFactory().CreateMqttClient();
    
                //_mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync; // 客户端连接成功事件
                //_mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync; // 客户端连接关闭事件
                //_mqttClient.ApplicationMessageReceivedAsync += _mqttClient_ApplicationMessageReceivedAsync; // 收到消息事件
    
                _mqttClient.ConnectAsync(clientOptions);
                return _mqttClient;
    
            }
        }
    }
    View Code
    using MQTTnet.Client;
    using MQTTnet.Protocol;
    using System;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MQTTClient
    {
        internal class Program
        {
            private static IMqttClient client;
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
    
                client = new MqttClientService().MqttClientStart("127.0.0.1", 1883, "cyw", "123456", "cyw");
    
                client.ConnectedAsync += Client_ConnectedAsync;
                client.ApplicationMessageReceivedAsync += Client_ApplicationMessageReceivedAsync;
                client.DisconnectedAsync += Client_DisconnectedAsync;
                Console.ReadLine();
            }
    
            private static Task Client_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
            {
                Console.WriteLine("Client_DisconnectedAsync");
                return Task.CompletedTask;
            }
    
            private static Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
            {
                Console.WriteLine($"ApplicationMessageReceivedAsync:客户端ID=【{arg.ClientId}】接收到消息。 Topic主题=【{arg.ApplicationMessage.Topic}】 消息=【{Encoding.UTF8.GetString(arg.ApplicationMessage.Payload)}】 qos等级=【{arg.ApplicationMessage.QualityOfServiceLevel}】");
                return Task.CompletedTask;
            }
    
            private static System.Threading.Tasks.Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
            {
                client.SubscribeAsync("test", MqttQualityOfServiceLevel.AtLeastOnce);
                Console.WriteLine("Client_ConnectedAsync");
                return Task.CompletedTask;
            }
        }
    }
    View Code

    三、发送消息

    引用的MQTTnet最新4.1.0版本,新增MqttClientService类,实例化client。然后连接到服务端后向指定topic发送消息。

    using MQTTnet;
    using MQTTnet.Client;
    using MQTTnet.Protocol;
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MQTTPublish
    {
        public class MqttClientService
        {
            public static IMqttClient _mqttClient;
            public IMqttClient MqttClientStart(string ip, int port, string username, string pwd, string clientId)
            {
                var optionsBuilder = new MqttClientOptionsBuilder()
                    .WithTcpServer(ip, port) // 要访问的mqtt服务端的 ip 和 端口号
                    .WithCredentials(username, pwd) // 要访问的mqtt服务端的用户名和密码
                    .WithClientId(clientId) // 设置客户端id
                    .WithCleanSession()
                    .WithTls(new MqttClientOptionsBuilderTlsParameters
                    {
                        UseTls = false  // 是否使用 tls加密
                    });
    
                var clientOptions = optionsBuilder.Build();
                _mqttClient = new MqttFactory().CreateMqttClient();
    
                //_mqttClient.ConnectedAsync += _mqttClient_ConnectedAsync; // 客户端连接成功事件
                //_mqttClient.DisconnectedAsync += _mqttClient_DisconnectedAsync; // 客户端连接关闭事件
                //_mqttClient.ApplicationMessageReceivedAsync += _mqttClient_ApplicationMessageReceivedAsync; // 收到消息事件
    
                _mqttClient.ConnectAsync(clientOptions);
                return _mqttClient;
    
            }
        }
    }
    View Code
    using MQTTnet;
    using MQTTnet.Client;
    using MQTTnet.Protocol;
    using MQTTnet.Server;
    using System;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MQTTPublish
    {
        internal class Program
        {
            private static IMqttClient client;
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                client = new MqttClientService().MqttClientStart("127.0.0.1", 1883, "cyw", "123456", "cywcyw");
                client.ConnectedAsync += Client_ConnectedAsync;
    
    
                Console.ReadLine();
            }
    
            private static System.Threading.Tasks.Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
            {
                Console.WriteLine("Client_ConnectedAsync");
                var message = new MqttApplicationMessage
                {
                    Topic = "test",
                    Payload = Encoding.Default.GetBytes("cyw-123456"),
                    QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
                    Retain = true  // 服务端是否保留消息。true为保留,如果有新的订阅者连接,就会立马收到该消息。
                };
                Console.WriteLine("PublishAsync topic:"+ message.Topic+ " Payload:"+ Encoding.UTF8.GetString(message.Payload));
                client.PublishAsync(message);
                return Task.CompletedTask;
            }
        }
    }
    View Code

    四、测试

    依次启动服务端,订阅消息客户端和发送消息客户端。

     

     demo地址

    MQTTDemo.rar
  • 相关阅读:
    测试产品
    三年回顾
    测试服务输出业务价值
    慎用重载_2
    慎用重载_1
    ByteBuffer和String的互相转换
    线程较为深的度剖析1
    线程同步的故事描述
    Java线程同步
    TCP关闭过程
  • 原文地址:https://www.cnblogs.com/5ishare/p/16740199.html
Copyright © 2020-2023  润新知