You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
5.2 KiB
C#

2 months ago
using System;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using MQTTnet.Client;
using System.Security.Authentication;
using MQTTnet;
using Microsoft.Extensions.Logging;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* LAPTOP-E0N2L34V
* SlnMesnac.Mqtt
* 496f8d2b-70e3-4a05-ae18-a9b0fcd06b82
*
* WenJY
* wenjy@mesnac.com
* 2024-03-27 21:58:35
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.Mqtt
{
/// <summary>
/// MQTT客户端
/// </summary>
public class MqttClient
{
private ILogger<MqttClient> _logger;
private IMqttClient _client;
public MqttClient(ILogger<MqttClient> logger)
{
_logger = logger;
}
/// <summary>
/// 链接服务器
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <param name="clientId"></param>
/// <param name="username"></param>
/// <param name="password"></param>
public async void Connect(string ip, int port, string clientId, string username, string password)
{
try
{
MqttClientOptions options = new MqttClientOptionsBuilder()
.WithTcpServer(ip, port)
.WithClientId(clientId)
.WithCredentials(username, password)
.WithTls(o => //开启ssl
{
o.CertificateValidationHandler = _ => true;
o.SslProtocol = SslProtocols.Tls12;
})
.Build();
_client = new MqttFactory().CreateMqttClient();
_client.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceived;
MqttClientConnectResult result = await _client.ConnectAsync(options);
if (result != null)
{
if (result.ResultCode == MQTTnet.Client.MqttClientConnectResultCode.Success)
{
_logger.LogInformation($"连接服务器成功{ip}:{port}");
}
else
{
_logger.LogInformation($"连接服务器失败");
}
}
}
catch (Exception ex)
{
_logger.LogError("连接服务器异常",ex);
}
}
/// <summary>
/// 断开链接
/// </summary>
public void DisConnect()
{
_client.DisconnectAsync();
_logger.LogInformation($"断开连接");
}
/// <summary>
/// 订阅主题
/// </summary>
/// <param name="topic"></param>
public async void SubscriptionAsync(string topic)
{
try
{
var mqttFactory = new MqttFactory();
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(
f =>
{
f.WithTopic(topic);
})
.Build();
MqttClientSubscribeResult result = await _client.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
_logger.LogInformation($"订阅主题:{topic}");
}
catch (Exception ex)
{
_logger.LogError("订阅主题异常",ex);
}
}
/// <summary>
/// 取消订阅
/// </summary>
/// <param name="topic"></param>
public void Unsubscribe(string topic)
{
_client.UnsubscribeAsync(topic);
_logger.LogInformation($"取消订阅,主题:{topic}");
}
/// <summary>
/// 推送消息
/// </summary>
/// <param name="topic"></param>
/// <param name="message"></param>
public void Publish(string topic, string message)
{
try
{
var msg = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(message)
.Build();
_client.PublishAsync(msg, CancellationToken.None);
_logger.LogInformation($"向服务端推送成功,主题:{topic};内容:{message}");
}
catch (Exception ex)
{
_logger.LogError("向服务端推送消息异常",ex);
}
}
private async Task MqttClient_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs eventArgs)
{
var info = $"接收到主题:{eventArgs.ApplicationMessage.Topic}的消息,内容:{Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload)}";
_logger.LogInformation(info);
}
}
}