From 40b0df237e8e88be972cb07abb16d88dfaf3e103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?liming=20=E8=94=A1?= Date: Mon, 20 Jul 2026 14:16:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0mqtt=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=8D=95=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + JY.Inspection/Common/MqttSingleton.cs | 176 ++++++++++++++++++++++++++ JY.Inspection/JY.Inspection.csproj | 4 + JY.Inspection/Mes/MESDataCombin.cs | 2 +- JY.Inspection/packages.config | 1 + 5 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 JY.Inspection/Common/MqttSingleton.cs diff --git a/.gitignore b/.gitignore index 511e45d..9fe4edf 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ bld/ [Ll]ogs/ /JY.DAL/obj/Release/JY.DAL.csproj.AssemblyReference.cache /JY.Inspection/obj/Debug/JY.Inspection.csproj.AssemblyReference.cache +/JY.Inspection/.vs/JY.Inspection.csproj.dtbcache.json diff --git a/JY.Inspection/Common/MqttSingleton.cs b/JY.Inspection/Common/MqttSingleton.cs new file mode 100644 index 0000000..4a74686 --- /dev/null +++ b/JY.Inspection/Common/MqttSingleton.cs @@ -0,0 +1,176 @@ +using MQTTnet; +using MQTTnet.Client; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MQTTnet; +using MQTTnet.Client; +using MQTTnet.Protocol; + +namespace JY.Inspection.Common +{ + public class MqttSingleton + { + // 单例实例 + private static readonly Lazy _instance = + new Lazy(() => new MqttSingleton()); + + public static MqttSingleton Instance => _instance.Value; + + // 内部成员 + private IMqttClient _client; + private MqttClientOptions _options; + private bool _isInitialized = false; + + // 事件:收到消息时触发 + public event Action MessageReceived; + + // 私有构造函数 + private MqttSingleton() { } + + /// + /// 初始化 MQTT 客户端(只需调用一次) + /// + /// MQTT 服务端地址 + /// 端口,默认1883 + /// 客户端ID,为空则自动生成 + /// 用户名(可选) + /// 密码(可选) + /// 是否启用TLS加密 + public async Task InitializeAsync( + string brokerHost, + int port = 1883, + string clientId = null, + string username = null, + string password = null, + bool useTls = false) + { + if (_isInitialized) return; + + // 创建客户端 + var factory = new MqttFactory(); + _client = factory.CreateMqttClient(); + + // 构建连接选项 + var optionsBuilder = new MqttClientOptionsBuilder() + .WithTcpServer(brokerHost, port) + .WithClientId(string.IsNullOrEmpty(clientId) ? $"WinForm_{Guid.NewGuid()}" : clientId) + .WithCleanSession(); + + if (!string.IsNullOrEmpty(username)) + { + optionsBuilder.WithCredentials(username, password); + } + + if (useTls) + { + optionsBuilder.WithTls(); + } + + _options = optionsBuilder.Build(); + + // 绑定事件 + _client.ConnectedAsync += async e => + { + Console.WriteLine("MQTT 已连接"); + }; + + _client.DisconnectedAsync += async e => + { + Console.WriteLine("MQTT 已断开,尝试重连..."); + // 自动重连 + await Task.Delay(3000).ContinueWith(_ => ConnectAsync()); + }; + + _client.ApplicationMessageReceivedAsync += async e => + { + var topic = e.ApplicationMessage.Topic; + var payload = e.ApplicationMessage.PayloadSegment == null + ? null + : Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment.Array); + + MessageReceived?.Invoke(topic, payload); + }; + + // 连接 + await ConnectAsync(); + _isInitialized = true; + } + + /// + /// 连接MQTT服务端 + /// + private async Task ConnectAsync() + { + try + { + if (!_client.IsConnected) + { + await _client.ConnectAsync(_options, System.Threading.CancellationToken.None); + } + } + catch (Exception ex) + { + Console.WriteLine($"MQTT连接失败: {ex.Message}"); + } + } + + /// + /// 发送消息 + /// + /// 主题 + /// 消息内容 + /// QoS等级,默认1 + public async Task SendAsync(string topic, string payload, int qos = 1) + { + if (!_client.IsConnected) + { + await ConnectAsync(); + } + + if (_client.IsConnected) + { + var message = new MqttApplicationMessageBuilder() + .WithTopic(topic) + .WithPayload(payload) + .WithQualityOfServiceLevel((MqttQualityOfServiceLevel)qos) + .WithRetainFlag(false) + .Build(); + + await _client.PublishAsync(message, System.Threading.CancellationToken.None); + } + } + + /// + /// 订阅主题 + /// + public async Task SubscribeAsync(string topic) + { + if (_client.IsConnected) + { + await _client.SubscribeAsync(new MqttTopicFilterBuilder() + .WithTopic(topic) + .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce) + .Build()); + } + } + + /// + /// 断开连接 + /// + public async Task DisconnectAsync() + { + if (_client != null && _client.IsConnected) + { + await _client.DisconnectAsync(); + } + } + + /// + /// 当前是否已连接 + /// + public bool IsConnected => _client?.IsConnected ?? false; + } +} diff --git a/JY.Inspection/JY.Inspection.csproj b/JY.Inspection/JY.Inspection.csproj index e421252..385c97e 100644 --- a/JY.Inspection/JY.Inspection.csproj +++ b/JY.Inspection/JY.Inspection.csproj @@ -96,6 +96,9 @@ ..\packages\MiniExcel.1.36.1\lib\net45\MiniExcel.dll + + ..\packages\MQTTnet.4.3.7.1207\lib\net48\MQTTnet.dll + ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll @@ -182,6 +185,7 @@ + diff --git a/JY.Inspection/Mes/MESDataCombin.cs b/JY.Inspection/Mes/MESDataCombin.cs index 411f2e3..1d5d6b5 100644 --- a/JY.Inspection/Mes/MESDataCombin.cs +++ b/JY.Inspection/Mes/MESDataCombin.cs @@ -344,7 +344,7 @@ namespace JY.Inspection.Mes throw new ArgumentNullException("MES员工登录请求信息为空"); } - // TODO MES登录请求地址 + // MES登录请求地址 DateTime currentTime = DateTime.Now; string reqUrl = Global.systemConfig.LoginMesUrl; MesCallResult resp = new MesCallResult(); diff --git a/JY.Inspection/packages.config b/JY.Inspection/packages.config index 6b0d21a..0f4b4ee 100644 --- a/JY.Inspection/packages.config +++ b/JY.Inspection/packages.config @@ -15,6 +15,7 @@ +