转自https://www.cnblogs.com/gzy2016Blog/p/17789358.html
本文,我们将使用 MQTTnet 来实现,它的官方地址为 https://github.com/chkr1011/MQTTnet
范例环境
本人所使用的环境,为 .NET Core 5.0
和 MQTTnet 3.1.0
,并且从一个 命令行应用程序模板 开始。
创建项目添加依赖
打开你的 Visual Studio 或 Visual Studio Code 创建一个名为 mqttdemo
的 命令行应用程序 项目。或者运行下面的命令行创建
dotnet new console --name mqttdemo
MQTTnet 的 NuGet
页面地址为 NuGet Gallery | MQTTnet 4.3.6.1152 你可以点击链接访问并查看如何安装
然后打开 NutGet
搜索 MQTTnet
添加 MQTTnet
依赖。 如果你使用 Package Manager
工具,也可以运行下面的命令添加
Install-Package MQTTnet -Version 3.1.0
如果你和我一样习惯使用命令行,那么可以运行下面的命令添加
dotnet add package MQTTnet --version 3.1.0
编写服务器端实现
MQTTnet 在 MQTTnet.Server
命名空间内实现了服务器相关的逻辑。而其中最重要的类和接口就是 IMqttServer
和 MqttFactory
。
private static async void StartServer()
{
try
{
// 1. 创建 MQTT 连接验证,用于连接鉴权
MqttServerConnectionValidatorDelegate connectionValidatorDelegate = new MqttServerConnectionValidatorDelegate(
p =>
{
// p 表示正在发起的一个链接的上下文
// 客户端 id 验证
// 大部分情况下,我们应该使用设备识别号来验证
if ( p.ClientId == "twle_client")
{
// 用户名和密码验证
// 大部分情况下,我们应该使用客户端加密 token 验证,也就是可客户端 ID 对应的密钥加密后的 token
if ( p.Username != "yufei" && p.Password != "123456")
{
// 验证失败,告诉客户端,鉴权失败
p.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
}
}
}
);
// 2. 创建 MqttServerOptions 的实例,用来定制 MQTT 的各种参数
MqttServerOptions options = new MqttServerOptions();
// 3. 设置各种选项
// 客户端鉴权
options.ConnectionValidator = connectionValidatorDelegate;
// 设置服务器端地址和端口号
options.DefaultEndpointOptions.Port = 8001;
// 4. 创建 MqttServer 实例
mqttServer = new MqttFactory().CreateMqttServer();
// 5. 设置 MqttServer 的属性
// 设置消息订阅通知
mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedTopicHandlerDelegate(SubScribedTopic);
// 设置消息退订通知
mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(UnScribedTopic);
// 设置消息处理程序
mqttServer.UseApplicationMessageReceivedHandler(MessageReceived);
// 设置客户端连接成功后的处理程序
mqttServer.UseClientConnectedHandler(ClientConnected);
// 设置客户端断开后的处理程序
mqttServer.UseClientDisconnectedHandler(ClientDisConnected);
// 启动服务器
await mqttServer.StartAsync(options);
Console.WriteLine("服务器启动成功!直接按回车停止服务");
Console.ReadLine();
} catch(Exception ex)
{
Console.Write($"服务器启动失败:{ex}");
}
}
// 客户端发起订阅主题通知
private static void SubScribedTopic(MqttServerClientSubscribedTopicEventArgs args)
{
// 获取客户端识别码
string clientId = args.ClientId;
// 获取客户端发起的订阅主题
string topic = args.TopicFilter.Topic;
Console.WriteLine($"客户端[{clientId}]已订阅主题:{topic}");
}
// 客户端取消主题订阅通知
private static void UnScribedTopic(MqttServerClientUnsubscribedTopicEventArgs args)
{
// 获取客户端识别码
string clientId = args.ClientId;
// 获取客户端发起的订阅主题
string topic = args.TopicFilter;
Console.WriteLine($"客户端[{clientId}]已退订主题:{topic}");
}
// 接收客户端发送的消息
private static void MessageReceived(MqttApplicationMessageReceivedEventArgs args)
{
// 获取消息的客户端识别码
string clientId = args.ClientId;
// 获取消息的主题
string topic = args.ApplicationMessage.Topic;
// 获取发送的消息内容
string payload = Encoding.UTF8.GetString(args.ApplicationMessage.Payload);
// 获取消息的发送级别(Qos)
var qos = args.ApplicationMessage.QualityOfServiceLevel;
// 获取消息的保持形式
bool retain = args.ApplicationMessage.Retain;
Console.WriteLine($"客户端[{clientId}] >> 主题: [{topic}] 内容: [{payload}] Qos: [{qos}] Retain:[{retain}]");
}
// 客户端连接成功后的的处理通知
private static void ClientConnected(Mqt