MqttNet作為.Net平台下的一個基於MQTT通信的開源庫, Github地址: https://github.com/chkr1011/MQTTnet。
本章內容主要介紹MQTT服務器與客戶端之間如何通信, 創建實例等相關內容。
點擊視頻教程
添加MQTT包
- 創建基於NetCore平台的WPF項目,通過NuGet安裝Mqttnet
1.方式一(Package Manager): Install-Package MQTTnet -Version 3.0.8
2.方式二(Net CLI[Common Language Infrastructure]): dotnet add package MQTTnet --version 3.0.8
3...
等: 手動方式添加NuGet包, 搜索:MqttNet進行安裝。截止2020-03-25最新版本為3.0.8
創建MQTT服務端:
IMqttServer server;
List<UserInstance> instances;
/// <summary>
/// 創建MQTT服務端
/// </summary>
private async void Init()
{
var optionBuilder = new MqttServerOptionsBuilder().
//設置默認IP: 127.0.0.1 ,端口1883,啟用連接驗證器
WithDefaultEndpoint().WithDefaultEndpointPort(1883).WithConnectionValidator(
c =>
{
//此處忽略驗證,做簡單為空驗證處理進行測試
var flag = (c.Username != "" && c.Password != "") ? true : false;
if (!flag)
{
//返回錯誤碼
c.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
return;
}
//設置代碼為 Success
c.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.Success;
instances.Add(new UserInstance() //緩存到內存的List集合當中
{
clientId = c.ClientId,
userName = c.Username,
passWord = c.Password
});
Showlog($"{DateTime.Now}:賬號:{c.Username}已訂閱!\r\n");
}).WithSubscriptionInterceptor(c =>
{
//消息攔截器
if (c == null) return;
c.AcceptSubscription = true;
Showlog($"{DateTime.Now}:訂閱者{c.ClientId}\r\n");
}).WithApplicationMessageInterceptor(c =>
{
//應用程序消息攔截器
if (c == null) return;
c.AcceptPublish = true;
string str = c.ApplicationMessage?.Payload == null ? null : Encoding.UTF8.GetString(c.ApplicationMessage?.Payload) + "\r\n";
Showlog($"{DateTime.Now}:{str}\r\n");
})
;
//創建MQTT服務端
server = new MqttFactory().CreateMqttServer();
//用戶斷開通知
server.UseClientDisconnectedHandler(c =>
{
var use = instances.FirstOrDefault(t => t.clientId == c.ClientId);
if (use != null)
{
instances.Remove(use);
Showlog($"{DateTime.Now}:訂閱者{use.userName}已退出\r\n");
}
});
//啟動服務
await server.StartAsync(optionBuilder.Build());
}
- 下代碼為實體類對象, 用於緩存用戶信息
public class UserInstance
{
public string clientId { get; set; }
public string userName { get; set; }
public string passWord { get; set; }
}
- 服務端發送消息至客戶端方法
server.PublishAsync(new MqttApplicationMessage()
{
Topic = arg.clientId, //client id
QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce, //只發送一次
Retain = false,
Payload = Encoding.UTF8.GetBytes($"{DateTime.Now}:服務器:明天都不要來上班了!") //測試內容
}); ;
創建MQTT客戶端
- 定義clienId 用於模擬緩存用戶的clientId,
IMqttClient client;
string clientId = "";
/// <summary>
/// 啟動MQTT客戶端
/// </summary>
private async void Init()
{
//模擬唯一ID
clientId = Guid.NewGuid().ToString();
//本地TCP連接, 127.0.0.1 端口 1883 , 測試情況下賬號密碼固定 admin 123
var options = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", 1883)
.WithClientId(clientId).WithCredentials("admin", "123").Build();
//創建MQTT實例
client = new MqttFactory().CreateMqttClient();
//注冊連接成功時間
client.UseConnectedHandler(async c =>
{
//訂閱服務端消息
await client.SubscribeAsync(new TopicFilterBuilder().WithTopic(clientId).Build());
}).UseDisconnectedHandler(c => //注冊斷開事件
{
Showlog(c.Exception.Message);
}).UseApplicationMessageReceivedHandler(c => //接受消息事件
{
string str = Encoding.UTF8.GetString(c.ApplicationMessage.Payload);
Showlog(str);
});
//啟動客戶端
await client.ConnectAsync(options);
}
- 客戶端給服務端發送消息
var msg = new MqttApplicationMessageBuilder().
WithTopic(clientId). // client Id
WithPayload($"{DateTime.Now}:Hello World") //測試消息內容
.WithExactlyOnceQoS(). //消息模式
WithRetainFlag().
Build();;
client.PublishAsync(msg); //發送消息
private void Showlog(string str)
{
this.Dispatcher.Invoke(() =>
{
txtResult.Text += str;
});
}
程序運行效果
MqttNet 官方文檔以及介紹
Demo示例 :https://github.com/chkr1011/MQTTnet/wiki
接口文檔: https://github.com/chkr1011/MQTTnet/wiki/Server-and-client-method-documentation