private void CompareAndAssert(string topic, string filter, bool expectedResult)
 {
     Assert.AreEqual(expectedResult, MqttTopicFilterComparer.IsMatch(topic, filter));
 }
示例#2
0
        public static async Task RunAsync()
        {
            try
            {
                var options = new MqttServerOptions
                {
                    ConnectionValidator = new MqttServerConnectionValidatorDelegate(p =>
                    {
                        if (p.ClientId == "SpecialClient")
                        {
                            if (p.Username != "USER" || p.Password != "PASS")
                            {
                                p.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                            }
                        }
                    }),

                    Storage = new RetainedMessageHandler(),

                    ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(context =>
                    {
                        if (MqttTopicFilterComparer.IsMatch(context.ApplicationMessage.Topic, "/myTopic/WithTimestamp/#"))
                        {
                            // Replace the payload with the timestamp. But also extending a JSON
                            // based payload with the timestamp is a suitable use case.
                            context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                        }

                        if (context.ApplicationMessage.Topic == "not_allowed_topic")
                        {
                            context.AcceptPublish   = false;
                            context.CloseConnection = true;
                        }
                    }),

                    SubscriptionInterceptor = new MqttServerSubscriptionInterceptorDelegate(context =>
                    {
                        if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
                        {
                            context.AcceptSubscription = false;
                        }

                        if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
                        {
                            context.AcceptSubscription = false;
                            context.CloseConnection    = true;
                        }
                    })
                };

                // Extend the timestamp for all messages from clients.
                // Protect several topics from being subscribed from every client.

                //var certificate = new X509Certificate(@"C:\certs\test\test.cer", "");
                //options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Cert);
                //options.ConnectionBacklog = 5;
                //options.DefaultEndpointOptions.IsEnabled = true;
                //options.TlsEndpointOptions.IsEnabled = false;

                var mqttServer = new MqttFactory().CreateMqttServer();

                mqttServer.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(e =>
                {
                    MqttNetConsoleLogger.PrintToConsole(
                        $"'{e.ClientId}' reported '{e.ApplicationMessage.Topic}' > '{Encoding.UTF8.GetString(e.ApplicationMessage.Payload ?? new byte[0])}'",
                        ConsoleColor.Magenta);
                });

                //options.ApplicationMessageInterceptor = c =>
                //{
                //    if (c.ApplicationMessage.Payload == null || c.ApplicationMessage.Payload.Length == 0)
                //    {
                //        return;
                //    }

                //    try
                //    {
                //        var content = JObject.Parse(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
                //        var timestampProperty = content.Property("timestamp");
                //        if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null)
                //        {
                //            timestampProperty.Value = DateTime.Now.ToString("O");
                //            c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(content.ToString());
                //        }
                //    }
                //    catch (Exception)
                //    {
                //    }
                //};

                mqttServer.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(e =>
                {
                    Console.Write("Client disconnected event fired.");
                });

                await mqttServer.StartAsync(options);

                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();

                await mqttServer.StopAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }
示例#3
0
        public static async Task StartMqttServerAsync()
        {
            if (mqttServer == null)
            {
                try
                {
                    var options = new MqttServerOptionsBuilder().WithConnectionValidator(context =>
                    {
                        //验证MQTT客户端
                        if (!string.IsNullOrEmpty(context.ClientId))
                        {
                            //if (context.Username != "u001" || context.Password != "p001")
                            //{
                            //    context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                            //}
                            context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
                        }
                        else
                        {
                            context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
                        }
                    })
                                  .WithConnectionBacklog(2000)               //设置连接数
                                  .WithDefaultEndpointPort(1883)             //默认监听端口是1883 这里设置成1884
                                  .WithPersistentSessions()                  //使用持续会话
                                                                             //  .WithEncryptionSslProtocol(SslProtocols.Tls12)
                                  .WithStorage(new RetainedMessageHandler()) //存储的实现,保留的应用程序消息
                                                                             //拦截消息,扩展来自客户端的所有消息的时间戳
                                  .WithApplicationMessageInterceptor(context =>
                    {
                        if (MqttTopicFilterComparer.IsMatch(context.ApplicationMessage.Topic, "/myTopic/WithTimestamp/#"))
                        {
                            context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                            Console.WriteLine("此消息被被处理");
                        }
                    })

                                  //拦截订阅
                                  .WithSubscriptionInterceptor(context =>
                    {
                        if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
                        {
                            context.AcceptSubscription = false;
                        }

                        if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
                        {
                            context.AcceptSubscription = false;
                            context.CloseConnection    = true;
                        }
                    })
                                  .Build();

                    //使用证书
                    //var certificate = new X509Certificate2(@"C:\certs\test\test.cer", "", X509KeyStorageFlags.Exportable);
                    //options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Pfx);
                    //options.TlsEndpointOptions.IsEnabled = true;

                    mqttServer = new MqttFactory().CreateMqttServer();

                    mqttServer.UseClientConnectedHandler(async e => {
                        Console.WriteLine($"客户端[{e.ClientId}]已连接............");
                        await Task.FromResult(1);
                    });

                    //mqttServer.ApplicationMessageReceived += MqttServer_ApplicationMessageReceived;
                    ////mqttServer.ClientSubscribedTopic += MqttServer_ClientSubscribedTopic;//订阅事件
                    ////mqttServer.ClientUnsubscribedTopic += MqttServer_ClientUnsubscribedTopic;//取消订阅事件

                    //mqttServer..ClientConnected += MqttServer_ClientConnected;
                    //mqttServer.ClientDisconnected += MqttServer_ClientDisconnected;
                    //await Task.Run(async () => { await mqttServer.StartAsync(options); });

                    mqttServer.StartAsync(options).Wait();
                    Console.WriteLine("MQTT服务启动成功!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return;
                }
            }
        }
示例#4
0
        public static void CreateMqttServer()
        {
            mqttServer = new MqttFactory().CreateMqttServer();
            IMqttServerOptions option = new MqttServerOptionsBuilder()
                                        //客户端验证
                                        .WithConnectionValidator(c =>
            {
                if (c.ClientId.Length < 10)
                {
                    c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
                    return;
                }
                if (c.Username != "mySecretUser")
                {
                    c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                    return;
                }
                if (c.Password != "mySecretPassword")
                {
                    c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                    return;
                }
                c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
            })
                                        //拦截应用消息
                                        .WithApplicationMessageInterceptor((c) =>
            {
                if (MqttTopicFilterComparer.IsMatch(c.ApplicationMessage.Topic, "/myTopic/WithTimes"))
                {
                    c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                }
            })
                                        //拦截订阅
                                        .WithSubscriptionInterceptor((c) =>
            {
                if (c.TopicFilter.Topic.StartsWith("admin/foo/bar") && c.ClientId != "theAdmin")
                {
                    c.AcceptSubscription = false;
                }
                if (c.TopicFilter.Topic.StartsWith("the/secret/stuff") && c.ClientId != "Imperator")
                {
                    c.AcceptSubscription = false;
                    c.CloseConnection    = true;
                }
            })
                                        .WithDefaultEndpointPort(1884)
                                        .WithDefaultEndpointBoundIPAddress(new System.Net.IPAddress(Encoding.Default.GetBytes("127.0.0.1")))
                                        .WithDefaultCommunicationTimeout(new TimeSpan(0, 10, 0))
                                        .WithConnectionBacklog(100).Build();

            option.ClientMessageQueueInterceptor = c =>
            {
                Console.WriteLine(c.ReceiverClientId + "," + c.ApplicationMessage.Topic + "," + c.ApplicationMessage.Payload + "," + c.SenderClientId);
            };
            mqttServer.ApplicationMessageReceived += (s, e) => {
                Console.WriteLine(e.ApplicationMessage.Topic + e.ApplicationMessage.Retain + e.ApplicationMessage.QualityOfServiceLevel + e.ApplicationMessage.Payload);
            };
            mqttServer.ClientConnected += (s, e) =>
            {
                Console.WriteLine("客户端" + e.ClientId + "已连接,协议版本:" + e.ClientId);
            };
            mqttServer.ClientSubscribedTopic += (s, e) =>
            {
                Console.WriteLine("客户端" + e.ClientId + "订阅消息:" + e.TopicFilter.Topic);
            };
            mqttServer.ClientUnsubscribedTopic += (s, e) =>
            {
                Console.WriteLine("客户端" + e.ClientId + "取消订阅消息:" + e.TopicFilter);
            };
            mqttServer.ClientDisconnected += (s, e) =>
            {
                Console.WriteLine("客户端" + e.ClientId + "断开连接!");
            };
            mqttServer.StartAsync(option);
        }
示例#5
0
 public bool IsFilterMatch(string topic)
 {
     return(MqttTopicFilterComparer.IsMatch(topic, TopicFilter));
 }
示例#6
0
 private static bool IsMatch(MqttTopicFilter topicFilter, IMqttRequestContext request)
 => MqttTopicFilterComparer.IsMatch(request.Topic, topicFilter.Topic) &&
 request.QualityOfServiceLevel == topicFilter.QualityOfServiceLevel;
示例#7
0
        public static async Task RunAsync()
        {
            try
            {
                MqttNetConsoleLogger.ForwardToConsole();

                var options = new MqttServerOptions
                {
                    ConnectionValidator = p =>
                    {
                        if (p.ClientId == "SpecialClient")
                        {
                            if (p.Username != "USER" || p.Password != "PASS")
                            {
                                return(MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword);
                            }
                        }

                        return(MqttConnectReturnCode.ConnectionAccepted);
                    },

                    Storage = new RetainedMessageHandler(),
                    ApplicationMessageInterceptor = context =>
                    {
                        if (MqttTopicFilterComparer.IsMatch(context.ApplicationMessage.Topic, "/myTopic/WithTimestamp/#"))
                        {
                            // Replace the payload with the timestamp. But also extending a JSON
                            // based payload with the timestamp is a suitable use case.
                            context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                        }
                    },
                    SubscriptionInterceptor = context =>
                    {
                        if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
                        {
                            context.AcceptSubscription = false;
                        }

                        if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
                        {
                            context.AcceptSubscription = false;
                            context.CloseConnection    = true;
                        }
                    }
                };

                // Extend the timestamp for all messages from clients.
                // Protect several topics from being subscribed from every client.

                //var certificate = new X509Certificate(@"C:\certs\test\test.cer", "");
                //options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Cert);
                //options.ConnectionBacklog = 5;
                //options.DefaultEndpointOptions.IsEnabled = true;
                //options.TlsEndpointOptions.IsEnabled = false;

                var mqttServer = new MqttFactory().CreateMqttServer();
                mqttServer.ClientDisconnected += (s, e) =>
                {
                    Console.Write("Client disconnected event fired.");
                };

                await mqttServer.StartAsync(options);

                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();

                await mqttServer.StopAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }
示例#8
0
        public static async Task RunAsync()
        {
            try
            {
                var options = new MqttServerOptions();

                // Extend the timestamp for all messages from clients.
                // Protect several topics from being subscribed from every client.

                //var certificate = new X509Certificate(@"C:\certs\test\test.cer", "");
                //options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Cert);
                //options.ConnectionBacklog = 5;
                //options.DefaultEndpointOptions.IsEnabled = true;
                //options.TlsEndpointOptions.IsEnabled = false;

                var mqttServer = new MqttFactory().CreateMqttServer(options);

                const string Filename = "C:\\MQTT\\RetainedMessages.json";

                mqttServer.RetainedMessageChangedAsync += e =>
                {
                    var directory = Path.GetDirectoryName(Filename);
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }

                    File.WriteAllText(Filename, JsonConvert.SerializeObject(e.StoredRetainedMessages));
                    return(Task.FromResult(0));
                };

                mqttServer.RetainedMessagesClearedAsync += e =>
                {
                    File.Delete(Filename);
                    return(Task.FromResult(0));
                };

                mqttServer.LoadingRetainedMessageAsync += e =>
                {
                    List <MqttApplicationMessage> retainedMessages;
                    if (File.Exists(Filename))
                    {
                        var json = File.ReadAllText(Filename);
                        retainedMessages = JsonConvert.DeserializeObject <List <MqttApplicationMessage> >(json);
                    }
                    else
                    {
                        retainedMessages = new List <MqttApplicationMessage>();
                    }

                    e.LoadedRetainedMessages = retainedMessages;

                    return(Task.FromResult(0));
                };

                mqttServer.InterceptingPublishAsync += e =>
                {
                    if (MqttTopicFilterComparer.Compare(e.ApplicationMessage.Topic, "/myTopic/WithTimestamp/#") == MqttTopicFilterCompareResult.IsMatch)
                    {
                        // Replace the payload with the timestamp. But also extending a JSON
                        // based payload with the timestamp is a suitable use case.
                        e.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                    }

                    if (e.ApplicationMessage.Topic == "not_allowed_topic")
                    {
                        e.ProcessPublish  = false;
                        e.CloseConnection = true;
                    }

                    return(PlatformAbstractionLayer.CompletedTask);
                };

                mqttServer.ValidatingConnectionAsync += e =>
                {
                    if (e.ClientId == "SpecialClient")
                    {
                        if (e.UserName != "USER" || e.Password != "PASS")
                        {
                            e.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
                        }
                    }

                    return(PlatformAbstractionLayer.CompletedTask);
                };

                mqttServer.InterceptingSubscriptionAsync += e =>
                {
                    if (e.TopicFilter.Topic.StartsWith("admin/foo/bar") && e.ClientId != "theAdmin")
                    {
                        e.Response.ReasonCode = MqttSubscribeReasonCode.ImplementationSpecificError;
                    }

                    if (e.TopicFilter.Topic.StartsWith("the/secret/stuff") && e.ClientId != "Imperator")
                    {
                        e.Response.ReasonCode = MqttSubscribeReasonCode.ImplementationSpecificError;
                        e.CloseConnection     = true;
                    }

                    return(PlatformAbstractionLayer.CompletedTask);
                };

                mqttServer.InterceptingPublishAsync += e =>
                {
                    MqttNetConsoleLogger.PrintToConsole(
                        $"'{e.ClientId}' reported '{e.ApplicationMessage.Topic}' > '{Encoding.UTF8.GetString(e.ApplicationMessage.Payload ?? new byte[0])}'",
                        ConsoleColor.Magenta);

                    return(PlatformAbstractionLayer.CompletedTask);
                };

                //options.ApplicationMessageInterceptor = c =>
                //{
                //    if (c.ApplicationMessage.Payload == null || c.ApplicationMessage.Payload.Length == 0)
                //    {
                //        return;
                //    }

                //    try
                //    {
                //        var content = JObject.Parse(Encoding.UTF8.GetString(c.ApplicationMessage.Payload));
                //        var timestampProperty = content.Property("timestamp");
                //        if (timestampProperty != null && timestampProperty.Value.Type == JTokenType.Null)
                //        {
                //            timestampProperty.Value = DateTime.Now.ToString("O");
                //            c.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(content.ToString());
                //        }
                //    }
                //    catch (Exception)
                //    {
                //    }
                //};

                mqttServer.ClientConnectedAsync += e =>
                {
                    Console.Write("Client disconnected event fired.");
                    return(PlatformAbstractionLayer.CompletedTask);
                };

                await mqttServer.StartAsync();

                Console.WriteLine("Press any key to exit.");
                Console.ReadLine();

                await mqttServer.StopAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }
示例#9
0
        public async Task StartServer()
        {
            if (mqttServer == null)
            {
                try
                {
                    #region 初始化MqttServer

                    var options = new MqttServerOptionsBuilder().WithConnectionValidator(context =>
                    {
                        //验证MQTT客户端
                        if (!string.IsNullOrEmpty(context.ClientId))
                        {
                            Console.WriteLine(context.Username);
                            Console.WriteLine(context.Password);
                            if (context.Username != UserName || context.Password != Password)
                            {
                                context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                            }
                            else
                            {
                                context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
                            }
                        }
                        else
                        {
                            context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
                        }
                    })
                                  .WithConnectionBacklog(ConnctionCount)     //设置连接数
                                  .WithDefaultEndpointPort(PortNum)          //默认监听端口是1883 这里设置成1884
                                  .WithPersistentSessions()                  //使用持续会话
                                  .WithEncryptionSslProtocol(SslProtocols.Tls12)
                                  .WithStorage(new RetainedMessageHandler()) //存储的实现,保留的应用程序消息
                                                                             //拦截消息,扩展来自客户端的所有消息的时间戳
                                  .WithApplicationMessageInterceptor(context =>
                    {
                        if (MqttTopicFilterComparer.IsMatch(context.ApplicationMessage.Topic, MessageInterceptorFilter))
                        {
                            context.ApplicationMessage.Payload = Encoding.UTF8.GetBytes(DateTime.Now.ToString("O"));
                            Console.WriteLine("此消息被被处理");
                        }
                    })

                                  //拦截订阅
                                  .WithSubscriptionInterceptor(context =>
                    {
                        if (context.TopicFilter.Topic.StartsWith("admin/foo/bar") && context.ClientId != "theAdmin")
                        {
                            context.AcceptSubscription = false;
                        }

                        if (context.TopicFilter.Topic.StartsWith("the/secret/stuff") && context.ClientId != "Imperator")
                        {
                            context.AcceptSubscription = false;
                            context.CloseConnection    = true;
                        }
                    })
                                  .Build();

                    //使用证书
                    if (IsUseCert)
                    {
                        var certificate = new X509Certificate2(@"C:\certs\test\test.cer", "", X509KeyStorageFlags.Exportable);
                        options.TlsEndpointOptions.Certificate = certificate.Export(X509ContentType.Pfx);
                        options.TlsEndpointOptions.IsEnabled   = true;
                    }
                    mqttServer = new MqttFactory().CreateMqttServer();

                    #endregion

                    #region 注册监听事件

                    //mqttServer.ApplicationMessageReceived += MqttServer_ApplicationMessageReceived;//收到消息事件
                    //mqttServer.ClientSubscribedTopic += MqttServer_ClientSubscribedTopic;//订阅事件
                    //mqttServer.ClientUnsubscribedTopic += MqttServer_ClientUnsubscribedTopic;//取消订阅事件
                    //mqttServer.ClientConnected += MqttServer_ClientConnected;//客户端连接事件
                    //mqttServer.ClientDisconnected += MqttServer_ClientDisconnected;//客户端断开连接事件
                    //mqttServer.Started += MqttServer_Started;//启动事件
                    //mqttServer.Stopped += MqttServer_Stopped;//停止事件
                    #endregion

                    await Task.Run(async() => await mqttServer.StartAsync(options));
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }