private void CompareAndAssert(string topic, string filter, bool expectedResult) { Assert.AreEqual(expectedResult, MqttTopicFilterComparer.IsMatch(topic, filter)); }
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(); }
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; } } }
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); }
public bool IsFilterMatch(string topic) { return(MqttTopicFilterComparer.IsMatch(topic, TopicFilter)); }
private static bool IsMatch(MqttTopicFilter topicFilter, IMqttRequestContext request) => MqttTopicFilterComparer.IsMatch(request.Topic, topicFilter.Topic) && request.QualityOfServiceLevel == topicFilter.QualityOfServiceLevel;
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(); }
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(); }
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; } } }