.net core 使用MQTTNET搭建MQTT 服务以及客户端例子
2023-10-11 17:33 古兆洋 阅读(1351) 评论(0) 编辑 收藏 举报转自:https://blog.csdn.net/u011540323/article/details/103694675/
最近项目可能用到MQTT协议故而稍作研究了一下,MQTT协议,基于TCP封装的发布订阅的消息传递机制,理论详情可查看MQTT--入门_liefyuan的博客-CSDN博客_mqtt 这位老兄的总结,废话不多说,先上效果图。
采用.NET体系用的较多的MQTTNET 3.0版本实现,服务端代码如下
try
{
var options = new MqttServerOptions
{
//连接验证
ConnectionValidator = new MqttServerConnectionValidatorDelegate(p =>
{
if (p.ClientId == "SpecialClient")
{
if (p.Username != "USER" || p.Password != "PASS")
{
p.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
}
}
}),
// 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 =>
{
Console.WriteLine(
$"'{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.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(MqttServer_SubscribedTopic);
mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(MqttServer_UnSubscribedTopic);
//客户端连接事件
mqttServer.UseClientConnectedHandler( MqttServer_ClientConnected);
//客户端断开事件
mqttServer.UseClientDisconnectedHandler(MqttServer_ClientDisConnected);
await mqttServer.StartAsync(options);
Console.WriteLine("服务启动成功,输入任意内容并回车停止服务");
Console.ReadLine();
await mqttServer.StopAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
客户端代码如下:
1 // Create a new MQTT client. 2 var factory = new MqttFactory(); 3 mqttClient = factory.CreateMqttClient(); 4 // Create TCP based options using the builder. 5 var options = new MqttClientOptionsBuilder() 6 .WithClientId(clientId) 7 .WithCredentials(user, pwd)//用户名 密码 8 .WithCleanSession() 9 .WithTcpServer("127.0.0.1", 1883) // Port is optional TCP 服务 10 // .WithTls( 11 //new MqttClientOptionsBuilderTlsParameters 12 //{ 13 // UseTls = true, 14 // CertificateValidationCallback = (X509Certificate x, X509Chain y, SslPolicyErrors z, IMqttClientOptions o) => 15 // { 16 // // TODO: Check conditions of certificate by using above parameters. 17 // return true; 18 // }, 19 20 //})//类型 TCPS 21 .Build(); 22 23 //重连机制 24 mqttClient.UseDisconnectedHandler(async e => 25 { 26 Console.WriteLine("### DISCONNECTED FROM SERVER ###"); 27 await Task.Delay(TimeSpan.FromSeconds(3)); 28 29 try 30 { 31 await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with CancellationToken 32 } 33 catch 34 { 35 Console.WriteLine("### RECONNECTING FAILED ###"); 36 } 37 }); 38 39 //消费消息 40 mqttClient.UseApplicationMessageReceivedHandler(e => 41 { 42 Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###"); 43 Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");//主题 44 Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");//页面信息 45 Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");//消息等级 46 Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");//是否保留 47 Console.WriteLine(); 48 49 // Task.Run(() => mqttClient.PublishAsync("hello/world")); 50 }); 51 52 53 54 //连接成功触发订阅主题 55 mqttClient.UseConnectedHandler(async e => 56 { 57 Console.WriteLine($"### 成功连接 ###"); 58 59 // Subscribe to a topic 60 //await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("my/topic").Build()); 61 62 63 //Console.WriteLine("### SUBSCRIBED ###"); 64 }); 65 66 try 67 { 68 69 await mqttClient.ConnectAsync(options, CancellationToken.None); 70 bool isExit = false; 71 while (!isExit) 72 { 73 Console.WriteLine(@"请输入 74 1.订阅主题 75 2.取消订阅 76 3.发送消息 77 4.退出输入exit"); 78 var input = Console.ReadLine(); 79 switch (input) 80 { 81 case "1": 82 Console.WriteLine(@"请输入主题名称:"); 83 var topicName = Console.ReadLine(); 84 await SubscribedTopic(topicName); 85 break; 86 case "2": 87 Console.WriteLine(@"请输入需要取消订阅主题名称:"); 88 topicName = Console.ReadLine(); 89 await UnsubscribedTopic(topicName); 90 break; 91 case "3": 92 Console.WriteLine("请输入需要发送的主题名称"); 93 topicName = Console.ReadLine(); 94 Console.WriteLine("请输入需要发送的消息"); 95 var message = Console.ReadLine(); 96 97 await PublishMessageAsync(new MQTTMessageModel() { Payload = message, Topic = topicName, Retain = true }); 98 break; 99 case "exit": 100 isExit = true; 101 break; 102 default: 103 Console.WriteLine("请输入正确指令!"); 104 break; 105 } 106 } 107 } 108 catch (Exception ex) 109 { 110 Console.WriteLine(ex.ToString()); 111 Console.ReadLine(); 112 }
服务端以及客户端都是core 3.1需要的小伙伴可以下载完整例子参考。
https://download.csdn.net/download/u011540323/12050633
————————————————
版权声明:本文为CSDN博主「11eleven」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011540323/article/details/103694675/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了