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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章