diff --git a/SlnMesnac.Business/Class1.cs b/SlnMesnac.Business/Class1.cs new file mode 100644 index 0000000..8124245 --- /dev/null +++ b/SlnMesnac.Business/Class1.cs @@ -0,0 +1,9 @@ +using System; + +namespace SlnMesnac.Business +{ + public class Class1 + { + //业务逻辑类 + } +} diff --git a/SlnMesnac.Business/SlnMesnac.Business.csproj b/SlnMesnac.Business/SlnMesnac.Business.csproj new file mode 100644 index 0000000..8ef8970 --- /dev/null +++ b/SlnMesnac.Business/SlnMesnac.Business.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.1 + enable + + + diff --git a/SlnMesnac.Mqtt/MqttClient.cs b/SlnMesnac.Mqtt/MqttClient.cs new file mode 100644 index 0000000..92bd2d0 --- /dev/null +++ b/SlnMesnac.Mqtt/MqttClient.cs @@ -0,0 +1,146 @@ +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; + +namespace SlnMesnac.Mqtt +{ + /// + /// MQTT客户端 + /// + public class MqttClient + { + private ILogger _logger; + + private IMqttClient _client; + + public MqttClient(ILogger logger) + { + _logger = logger; + } + + /// + /// 链接服务器 + /// + /// + /// + /// + /// + /// + 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); + } + } + + /// + /// 断开链接 + /// + public void DisConnect() + { + _client.DisconnectAsync(); + _logger.LogInformation($"断开连接"); + } + + /// + /// 订阅主题 + /// + /// + 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); + } + } + + /// + /// 取消订阅 + /// + /// + public void Unsubscribe(string topic) + { + _client.UnsubscribeAsync(topic); + _logger.LogInformation($"取消订阅,主题:{topic}"); + } + + /// + /// 推送消息 + /// + /// + /// + 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); + } + + } +} diff --git a/SlnMesnac.Mqtt/MqttSetup.cs b/SlnMesnac.Mqtt/MqttSetup.cs new file mode 100644 index 0000000..447175a --- /dev/null +++ b/SlnMesnac.Mqtt/MqttSetup.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; + +namespace SlnMesnac.Mqtt +{ + public static class MqttSetup + { + public static void AddMqttSetup(this IServiceCollection services) + { + services.AddSingleton(); + } + } +} diff --git a/SlnMesnac.Mqtt/SlnMesnac.Mqtt.csproj b/SlnMesnac.Mqtt/SlnMesnac.Mqtt.csproj new file mode 100644 index 0000000..659191d --- /dev/null +++ b/SlnMesnac.Mqtt/SlnMesnac.Mqtt.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.1 + enable + + + + + + + + + + + + diff --git a/SlnMesnac.Rfid/Class1.cs b/SlnMesnac.Rfid/Class1.cs new file mode 100644 index 0000000..dbbddb9 --- /dev/null +++ b/SlnMesnac.Rfid/Class1.cs @@ -0,0 +1,9 @@ +using System; + +namespace SlnMesnac.Rfid +{ + public class Class1 + { + + } +} diff --git a/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj b/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj new file mode 100644 index 0000000..8ef8970 --- /dev/null +++ b/SlnMesnac.Rfid/SlnMesnac.Rfid.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.1 + enable + + + diff --git a/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj b/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj new file mode 100644 index 0000000..6943480 --- /dev/null +++ b/SlnMesnac.TouchSocket/SlnMesnac.TouchSocket.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.1 + enable + + + + + + + + + + + diff --git a/SlnMesnac.TouchSocket/TcpServer.cs b/SlnMesnac.TouchSocket/TcpServer.cs new file mode 100644 index 0000000..799fce5 --- /dev/null +++ b/SlnMesnac.TouchSocket/TcpServer.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Text; +using TouchSocket.Core; +using TouchSocket.Sockets; + +namespace SlnMesnac.TouchSocket +{ + public class TcpServer + { + private ILogger _logger; + private readonly TcpService _service; + + public TcpServer(ILogger logger,TcpService tcpService) + { + _logger = logger; + _service = tcpService; + } + + public void Init(int serverPort) + { + try + { + _service.Connecting = (client, e) => { //有客户端正在连接 + _logger.LogInformation($"客户端{client.IP}正在接入服务"); + }; + _service.Connected = (client, e) => { //有客户端成功连接 + _logger.LogInformation($"客户端{client.IP}接入服务成功,Id:{client.ID}"); + }; + _service.Disconnected = (client, e) => { //有客户端断开连接 + _logger.LogInformation($"客户端{client.IP}断开连接,Id:{client.ID}"); + }; + _service.Received = (client, byteBlock, requestInfo) => + { + //if (requestInfo is MyFixedHeaderRequestInfo myRequestInfo) + //{ + // string body = Encoding.UTF8.GetString(myRequestInfo.Body, 0, myRequestInfo.Body.Length); + //} + }; + + _service.Setup(new TouchSocketConfig()//载入配置 + .SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:{serverPort}") }) + //.SetDataHandlingAdapter(() => { return new MyFixedHeaderCustomDataHandlingAdapter(); })//配置适配器 + .ConfigureContainer(a =>//容器的配置顺序应该在最前面 + { + a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用) + }) + .ConfigurePlugins(a => + { + //a.Add().SetDuration(new TimeSpan(0, 0, 0, 5, 0)); + })) + .Start();//启动 + _logger.LogInformation($"TcpServer启动成功,监听端口:{serverPort}"); + } + catch (Exception ex) + { + _logger.LogError($"采集服务启动异常:{ex}"); + throw new Exception(ex.Message); + } + + } + } +} diff --git a/SlnMesnac.TouchSocket/TouchSocketSetup.cs b/SlnMesnac.TouchSocket/TouchSocketSetup.cs new file mode 100644 index 0000000..588bd9d --- /dev/null +++ b/SlnMesnac.TouchSocket/TouchSocketSetup.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; +using TouchSocket.Sockets; + +namespace SlnMesnac.TouchSocket +{ + /// + /// 注册服务 + /// + public static class TouchSocketSetup + { + public static void AddTouchSocketSetup(this IServiceCollection services) + { + services.AddSingleton();//注册TouchSocket的服务 + services.AddSingleton(); + } + } +} diff --git a/SlnMesnac.WPF/SlnMesnac.WPF.csproj b/SlnMesnac.WPF/SlnMesnac.WPF.csproj index f8dc1a1..79a3beb 100644 --- a/SlnMesnac.WPF/SlnMesnac.WPF.csproj +++ b/SlnMesnac.WPF/SlnMesnac.WPF.csproj @@ -1,7 +1,7 @@  - WinExe + Exe net6.0-windows enable true @@ -22,10 +22,12 @@ + + diff --git a/SlnMesnac.WPF/Startup.cs b/SlnMesnac.WPF/Startup.cs index 9b91b65..aee9a3a 100644 --- a/SlnMesnac.WPF/Startup.cs +++ b/SlnMesnac.WPF/Startup.cs @@ -14,6 +14,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Configuration; +using SlnMesnac.Mqtt; +using SlnMesnac.TouchSocket; namespace SlnMesnac.WPF { @@ -31,7 +33,7 @@ namespace SlnMesnac.WPF { services.AddControllers(); - //注册配置类 + //注册AppConfig services.AddSingleton(provider => { var configuration = provider.GetService(); @@ -42,17 +44,23 @@ namespace SlnMesnac.WPF //注册通用类 services.AddCommonSetup(); - //注册SqlSugar + //注册ROM services.AddSqlSugarSetup(); - //注册服务 + //注册Service services.AddServices(); - //注册任务调度 + //注册Quartz services.AddQuartzSetUp(); //注册PLC services.AddPlcSetup(); + + //注册MQTT + services.AddMqttSetup(); + + //注册TouchSocket + services.AddTouchSocketSetup(); } /// diff --git a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs index 99e12d1..57a6d3c 100644 --- a/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs +++ b/SlnMesnac.WPF/ViewModel/MainWindowViewModel.cs @@ -1,13 +1,17 @@ using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; +using HslCommunication.Enthernet; using Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Logging; +using SlnMesnac.Mqtt; +using SlnMesnac.TouchSocket; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -15,7 +19,6 @@ namespace SlnMesnac.WPF.ViewModel { public class MainWindowViewModel: ViewModelBase { - private readonly ILogger _logger; #region 参数定义 @@ -86,6 +89,7 @@ namespace SlnMesnac.WPF.ViewModel ControlOnClickCommand = new RelayCommand(obj => ControlOnClick(obj)); FormControlCommand = new RelayCommand(x => FormControl(x)); + } /// @@ -148,5 +152,6 @@ namespace SlnMesnac.WPF.ViewModel _logger.LogError("界面跳转逻辑异常", ex); } } + } } diff --git a/SlnMesnac.sln b/SlnMesnac.sln index 6bd8d16..c23e46f 100644 --- a/SlnMesnac.sln +++ b/SlnMesnac.sln @@ -19,7 +19,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Serilog", "SlnMes EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.Plc", "SlnMesnac.Plc\SlnMesnac.Plc.csproj", "{D17E9024-9D25-4CE4-8E98-8A6C859CE436}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.WPF", "SlnMesnac.WPF\SlnMesnac.WPF.csproj", "{B986555B-86D1-457A-95F5-B9135B9FBC55}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlnMesnac.WPF", "SlnMesnac.WPF\SlnMesnac.WPF.csproj", "{B986555B-86D1-457A-95F5-B9135B9FBC55}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Business", "SlnMesnac.Business\SlnMesnac.Business.csproj", "{90296C1E-932E-4CD3-9B11-4376746C4C87}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.TouchSocket", "SlnMesnac.TouchSocket\SlnMesnac.TouchSocket.csproj", "{3700E2BB-09C4-43C0-A9DC-C18137B76591}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Rfid", "SlnMesnac.Rfid\SlnMesnac.Rfid.csproj", "{3D25CB20-2DF9-4D35-8803-3DC765B2D54A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SlnMesnac.Mqtt", "SlnMesnac.Mqtt\SlnMesnac.Mqtt.csproj", "{7D908FF5-88AE-42AB-A193-F2896EF44AB1}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -63,6 +71,22 @@ Global {B986555B-86D1-457A-95F5-B9135B9FBC55}.Debug|Any CPU.Build.0 = Debug|Any CPU {B986555B-86D1-457A-95F5-B9135B9FBC55}.Release|Any CPU.ActiveCfg = Release|Any CPU {B986555B-86D1-457A-95F5-B9135B9FBC55}.Release|Any CPU.Build.0 = Release|Any CPU + {90296C1E-932E-4CD3-9B11-4376746C4C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90296C1E-932E-4CD3-9B11-4376746C4C87}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90296C1E-932E-4CD3-9B11-4376746C4C87}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90296C1E-932E-4CD3-9B11-4376746C4C87}.Release|Any CPU.Build.0 = Release|Any CPU + {3700E2BB-09C4-43C0-A9DC-C18137B76591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3700E2BB-09C4-43C0-A9DC-C18137B76591}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3700E2BB-09C4-43C0-A9DC-C18137B76591}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3700E2BB-09C4-43C0-A9DC-C18137B76591}.Release|Any CPU.Build.0 = Release|Any CPU + {3D25CB20-2DF9-4D35-8803-3DC765B2D54A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D25CB20-2DF9-4D35-8803-3DC765B2D54A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D25CB20-2DF9-4D35-8803-3DC765B2D54A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D25CB20-2DF9-4D35-8803-3DC765B2D54A}.Release|Any CPU.Build.0 = Release|Any CPU + {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D908FF5-88AE-42AB-A193-F2896EF44AB1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE