Compare commits
	
		
			23 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | f32ff92b0b | ||
|   | 88d71e271e | ||
|   | fd9c14612a | ||
|   | e26e5a160f | ||
|   | b836bfed22 | ||
|   | a4b598c6d0 | ||
|   | c9ab755839 | ||
|   | 9920edba53 | ||
|   | 12bd7280d1 | ||
|   | d30ea7f63b | ||
|   | ebd3390db6 | ||
|   | 9a374a9ebc | ||
|   | b1bc22cb08 | ||
|   | 4930d53890 | ||
|   | c31327b5bc | ||
|   | 3f2aa1f1e1 | ||
|   | 6e78c00a96 | ||
|   | c27dde085e | ||
|   | d26cc308c0 | ||
|   | fb1efdf290 | ||
|   | 3c99f2a472 | ||
|   | affe9a44e0 | ||
|   | 43730fa519 | 
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.20</Version> | ||||
| 		<Version>3.0.0.24</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Authors>Diego</Authors> | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -26,7 +26,7 @@ public partial class MainLayout | ||||
| [ | ||||
|   { | ||||
|     "Href": "/index", | ||||
|     "Title": "<EFBFBD><EFBFBD>ҳ" | ||||
|     "Title": "首页" | ||||
|   }, | ||||
|   { | ||||
|     "Title": "Modbus", | ||||
|   | ||||
| @@ -56,10 +56,10 @@ | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\MqttRpcNameVaueWithId.cs" Link="Pages\Mqtt\MqttRpcNameVaueWithId.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor.cs" Link="Pages\Mqtt\MqttClientDebugPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor.cs" Link="Pages\Mqtt\MqttClientPage.razor.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\PrivateLogger.cs" Link="Pages\Mqtt\PrivateLogger.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClient.cs" Link="Pages\Mqtt\MqttRpcClient.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClientExtensions.cs" Link="Pages\Mqtt\MqttRpcClientExtensions.cs" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcTopicPair.cs" Link="Pages\Mqtt\MqttRpcTopicPair.cs" /> | ||||
| 		<Compile Include="..\..\Web\ThingsGateway.Gateway.Application\Workers\ManageGateway\MqttLoggerExtensions.cs" Link="Pages\Mqtt\MqttLoggerExtensions.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor" Link="Pages\DLT645\DLT645_2007DebugPage.razor" /> | ||||
| 		<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor" /> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.20</Version> | ||||
| 		<Version>3.0.0.24</Version> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks> | ||||
|   | ||||
| @@ -101,9 +101,17 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     EasyLock easyLock = new(); | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|  | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -158,6 +166,12 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|             } | ||||
|             return new OperResult<byte[]>("功能码错误"); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
| @@ -173,9 +187,13 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|         SerialSession.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -211,11 +229,21 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|             } | ||||
|             return new OperResult("功能码错误"); | ||||
|  | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -254,6 +282,13 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|                     return (OperResult.CreateSuccessResult()); | ||||
|             } | ||||
|             return new OperResult("功能码错误"); | ||||
|  | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|   | ||||
| @@ -186,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
|                 var item = commandResult.Content; | ||||
|                 if (FrameTime != 0) | ||||
|                     Thread.Sleep(FrameTime); | ||||
|                 var WaitingClientEx = client.CreateWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var WaitingClientEx = client.CreateWaitingClient(new() { }); | ||||
|                 var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
| @@ -213,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
|  | ||||
|                 var item = commandResult.Content; | ||||
|                 await Task.Delay(FrameTime, cancellationToken); | ||||
|                 var WaitingClientEx = client.CreateWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var WaitingClientEx = client.CreateWaitingClient(new() { }); | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|   | ||||
| @@ -104,9 +104,16 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|         return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     EasyLock easyLock = new(); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|  | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -161,6 +168,12 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|             } | ||||
|             return new OperResult<byte[]>("功能码错误"); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken = default) | ||||
| @@ -193,6 +206,9 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -228,11 +244,21 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|             } | ||||
|             return new OperResult("功能码错误"); | ||||
|  | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             easyLock.Wait(); | ||||
|             ModbusAddress mAddress; | ||||
|             try | ||||
|             { | ||||
| @@ -271,6 +297,13 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|                     return (OperResult.CreateSuccessResult()); | ||||
|             } | ||||
|             return new OperResult("功能码错误"); | ||||
|  | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|  | ||||
|             easyLock.Release(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| #endregion | ||||
|  | ||||
| using Newtonsoft.Json.Linq; | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| #region copyright | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| @@ -9,7 +8,6 @@ | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| #endregion | ||||
|  | ||||
| using Opc.Ua; | ||||
|   | ||||
| @@ -123,34 +123,7 @@ namespace ThingsGateway.Foundation.Adapter.Siemens | ||||
|         #region 设置 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 远程TSAP,需重新连接 | ||||
|         /// </summary> | ||||
|         public int DestTSAP | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 return | ||||
|                     _currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart ? | ||||
|                     (ISO_CR[17] * 256) + ISO_CR[18] : | ||||
|                     (ISO_CR[20] * 256) + ISO_CR[21]; | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 if (_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart) | ||||
|                 { | ||||
|                     ISO_CR[17] = BitConverter.GetBytes(value)[1]; | ||||
|                     ISO_CR[18] = BitConverter.GetBytes(value)[0]; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ISO_CR[20] = BitConverter.GetBytes(value)[1]; | ||||
|                     ISO_CR[21] = BitConverter.GetBytes(value)[0]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 本地TSAP,需重新连接 | ||||
|         /// 本地TSAP | ||||
|         /// </summary> | ||||
|         public int LocalTSAP | ||||
|         { | ||||
|   | ||||
| @@ -24,7 +24,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     public ReadWriteDevicesSerialSessionBase(SerialSession serialSession) | ||||
|     { | ||||
|         SerialSession = serialSession; | ||||
|         WaitingClientEx = SerialSession.CreateWaitingClient(new() { ThrowBreakException = true }); | ||||
|         WaitingClientEx = SerialSession.CreateWaitingClient(new() { }); | ||||
|         SerialSession.Received -= Received; | ||||
|         SerialSession.Connecting -= Connecting; | ||||
|         SerialSession.Connected -= Connected; | ||||
| @@ -96,7 +96,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = SerialSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
| @@ -111,7 +111,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = await SerialSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|   | ||||
| @@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     public ReadWriteDevicesTcpClientBase(TcpClient tcpClient) | ||||
|     { | ||||
|         TcpClient = tcpClient; | ||||
|         WaitingClientEx = TcpClient.CreateWaitingClient(new() { ThrowBreakException = true }); | ||||
|         WaitingClientEx = TcpClient.CreateWaitingClient(new() { }); | ||||
|         TcpClient.Connecting -= Connecting; | ||||
|         TcpClient.Connected -= Connected; | ||||
|         TcpClient.Disconnecting -= Disconnecting; | ||||
| @@ -86,7 +86,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = TcpClient.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
| @@ -101,7 +101,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = await TcpClient.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|   | ||||
| @@ -22,7 +22,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         UdpSession = udpSession; | ||||
|         SetDataAdapter(); | ||||
|         WaitingClientEx = UdpSession.CreateWaitingClient(new() { ThrowBreakException = true }); | ||||
|         WaitingClientEx = UdpSession.CreateWaitingClient(new() { }); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -64,7 +64,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = UdpSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
| @@ -79,7 +79,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             waitingOptions ??= new WaitingOptions { }; | ||||
|             ResponsedData result = await UdpSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|   | ||||
| @@ -51,10 +51,10 @@ public sealed class EasyLock | ||||
|     /// <summary> | ||||
|     /// 进入锁 | ||||
|     /// </summary> | ||||
|     public void Wait() | ||||
|     public void Wait(CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         Interlocked.Increment(ref lockWaitCount); | ||||
|         m_waiterLock.Wait(); | ||||
|         m_waiterLock.Wait(cancellationToken); | ||||
|         Interlocked.Decrement(ref lockWaitCount); | ||||
|     } | ||||
|     /// <summary> | ||||
| @@ -71,10 +71,10 @@ public sealed class EasyLock | ||||
|     /// <summary> | ||||
|     /// 进入锁 | ||||
|     /// </summary> | ||||
|     public async Task WaitAsync() | ||||
|     public async Task WaitAsync(CancellationToken cancellationToken = default) | ||||
|     { | ||||
|         Interlocked.Increment(ref lockWaitCount); | ||||
|         await m_waiterLock.WaitAsync(); | ||||
|         await m_waiterLock.WaitAsync(cancellationToken); | ||||
|         Interlocked.Decrement(ref lockWaitCount); | ||||
|     } | ||||
|     /// <summary> | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Globalization; | ||||
| using System.Net; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| @@ -114,17 +115,47 @@ public static class StringExtensions | ||||
|         else if (propertyType == typeof(sbyte)) | ||||
|             _value = sbyte.Parse(value); | ||||
|         else if (propertyType == typeof(short)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = short.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = short.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(ushort)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = ushort.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = ushort.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(int)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = int.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = int.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(uint)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = uint.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = uint.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(long)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = long.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = long.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(ulong)) | ||||
|         { | ||||
|             if (value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) | ||||
|                 _value = ulong.Parse(value.Substring(2), NumberStyles.HexNumber); | ||||
|             else | ||||
|                 _value = ulong.Parse(value); | ||||
|         } | ||||
|         else if (propertyType == typeof(float)) | ||||
|             _value = float.Parse(value); | ||||
|         else if (propertyType == typeof(double)) | ||||
| @@ -142,7 +173,6 @@ public static class StringExtensions | ||||
|         else if (propertyType.IsEnum) | ||||
|             _value = Enum.Parse(propertyType, value); | ||||
|         return _value; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,8 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| using System.Runtime.CompilerServices; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Core | ||||
| { | ||||
|     /// <summary> | ||||
| @@ -49,5 +51,27 @@ namespace ThingsGateway.Foundation.Core | ||||
|         { | ||||
|             task.ConfigureAwait(false).GetAwaiter().GetResult(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 配置ConfigureAwait为false。 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="task"></param> | ||||
|         /// <returns></returns> | ||||
|         public static ConfiguredTaskAwaitable<T> ConfigureFalseAwait<T>(this Task<T> task) | ||||
|         { | ||||
|             return task.ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 配置ConfigureAwait为false。 | ||||
|         /// </summary> | ||||
|         /// <param name="task"></param> | ||||
|         public static ConfiguredTaskAwaitable ConfigureFalseAwait(this Task task) | ||||
|         { | ||||
|             return task.ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -27,43 +27,48 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <summary> | ||||
|         /// 请求关闭 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, string> OnClose { get; set; } | ||||
|         public Func<DmtpActor, string, Task> Closed { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当创建通道时 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, CreateChannelEventArgs> OnCreateChannel { get; set; } | ||||
|         public Func<DmtpActor, CreateChannelEventArgs, Task> CreatedChannel { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 查找其他IDmtpActor | ||||
|         /// </summary> | ||||
|         public Func<string, IDmtpActor> OnFindDmtpActor { get; set; } | ||||
|         public Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaked { get; set; } | ||||
|         public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaked { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 握手 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaking { get; set; } | ||||
|         public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaking { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 重设Id | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, WaitSetId> OnResetId { get; set; } | ||||
|         public Func<DmtpActor, IdChangedEventArgs, Task> IdChanged { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当需要路由的时候 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, PackageRouterEventArgs> OnRouting { get; set; } | ||||
|         public Func<DmtpActor, PackageRouterEventArgs, Task> Routing { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据接口 | ||||
|         /// </summary> | ||||
|         public Action<DmtpActor, ArraySegment<byte>[]> OutputSend { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 异步发送数据接口 | ||||
|         /// </summary> | ||||
|         public Func<DmtpActor, ArraySegment<byte>[], Task> OutputSendAsync { get; set; } | ||||
|  | ||||
|         #endregion 委托 | ||||
|  | ||||
|         #region 属性 | ||||
| @@ -118,32 +123,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual void Close(bool sendClose, string message) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (this.IsHandshaked) | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         if (sendClose) | ||||
|                         { | ||||
|                             this.SendString(0, message); | ||||
|                         } | ||||
|                     } | ||||
|                     catch | ||||
|                     { | ||||
|                     } | ||||
|                     this.IsHandshaked = false; | ||||
|                     this.WaitHandlePool.CancelAll(); | ||||
|                     this.OnClose?.Invoke(this, message); | ||||
|                 } | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 建立对点 | ||||
| @@ -165,7 +144,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 Metadata = metadata | ||||
|             }; | ||||
|  | ||||
|             this.OnHandshaking?.Invoke(this, args); | ||||
|             this.OnHandshaking(args).GetFalseAwaitResult(); | ||||
|  | ||||
|             var waitVerify = new WaitVerify() | ||||
|             { | ||||
| @@ -189,7 +168,8 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             { | ||||
|                                 this.Id = verifyResult.Id; | ||||
|                                 this.IsHandshaked = true; | ||||
|                                 this.PrivateHandshaked(new DmtpVerifyEventArgs() | ||||
|  | ||||
|                                 Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs() | ||||
|                                 { | ||||
|                                     Id = verifyResult.Id, | ||||
|                                     Metadata = verifyResult.Metadata, | ||||
| @@ -201,18 +181,15 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             else | ||||
|                             { | ||||
|                                 verifyResult.Handle = true; | ||||
|                                 this.Close(false, verifyResult.Message); | ||||
|                                 throw new TokenVerifyException(verifyResult.Message); | ||||
|                             } | ||||
|                         } | ||||
|                     case WaitDataStatus.Overtime: | ||||
|                         this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription()); | ||||
|                         throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription()); | ||||
|                     case WaitDataStatus.Canceled: | ||||
|                     case WaitDataStatus.Disposed: | ||||
|                     default: | ||||
|                         this.Close(false, null); | ||||
|                         return; | ||||
|                         throw new OperationCanceledException(); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
| @@ -240,7 +217,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 Metadata = metadata | ||||
|             }; | ||||
|  | ||||
|             this.OnHandshaking?.Invoke(this, args); | ||||
|             await this.OnHandshaking(args).ConfigureFalseAwait(); | ||||
|  | ||||
|             var waitVerify = new WaitVerify() | ||||
|             { | ||||
| @@ -253,8 +230,8 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 this.SendJsonObject(P1_Handshake_Request, waitVerify); | ||||
|                 switch (await waitData.WaitAsync(timeout)) | ||||
|                 await this.SendJsonObjectAsync(P1_Handshake_Request, waitVerify).ConfigureFalseAwait(); | ||||
|                 switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait()) | ||||
|                 { | ||||
|                     case WaitDataStatus.SetRunning: | ||||
|                         { | ||||
| @@ -263,7 +240,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             { | ||||
|                                 this.Id = verifyResult.Id; | ||||
|                                 this.IsHandshaked = true; | ||||
|                                 this.PrivateHandshaked(new DmtpVerifyEventArgs() | ||||
|                                 _ = Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs() | ||||
|                                 { | ||||
|                                     Id = verifyResult.Id, | ||||
|                                     Metadata = verifyResult.Metadata, | ||||
| @@ -275,18 +252,15 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             else | ||||
|                             { | ||||
|                                 verifyResult.Handle = true; | ||||
|                                 this.Close(false, verifyResult.Message); | ||||
|                                 throw new TokenVerifyException(verifyResult.Message); | ||||
|                             } | ||||
|                         } | ||||
|                     case WaitDataStatus.Overtime: | ||||
|                         this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription()); | ||||
|                         throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription()); | ||||
|                     case WaitDataStatus.Canceled: | ||||
|                     case WaitDataStatus.Disposed: | ||||
|                     default: | ||||
|                         this.Close(false, null); | ||||
|                         return; | ||||
|                         throw new OperationCanceledException(); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
| @@ -295,6 +269,100 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #region 委托触发 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当关闭后 | ||||
|         /// </summary> | ||||
|         /// <param name="manual"></param> | ||||
|         /// <param name="msg"></param> | ||||
|         protected virtual Task OnClosed(bool manual, string msg) | ||||
|         { | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.IsHandshaked = false; | ||||
|                 this.WaitHandlePool.CancelAll(); | ||||
|             } | ||||
|  | ||||
|             if (manual) | ||||
|             { | ||||
|                 return EasyTask.CompletedTask; | ||||
|             } | ||||
|             if (this.Closed != null) | ||||
|             { | ||||
|                 return this.Closed.Invoke(this, msg); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 正在握手连接 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (this.Handshaking != null) | ||||
|             { | ||||
|                 return this.Handshaking.Invoke(this, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 握手连接完成 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (this.Handshaked != null) | ||||
|             { | ||||
|                 return this.Handshaked.Invoke(this, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当Id修改时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual Task OnIdChanged(IdChangedEventArgs e) | ||||
|         { | ||||
|             if (this.IdChanged != null) | ||||
|             { | ||||
|                 return this.IdChanged.Invoke(this, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当完成创建通道时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual Task OnCreatedChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (this.CreatedChannel != null) | ||||
|             { | ||||
|                 return this.CreatedChannel.Invoke(this, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void PrivateOnHandshaked(object obj) | ||||
|         { | ||||
|             this.OnHandshaked((DmtpVerifyEventArgs)obj); | ||||
|         } | ||||
|  | ||||
|         private void PrivateOnCreatedChannel(object obj) | ||||
|         { | ||||
|             this.OnCreatedChannel((CreateChannelEventArgs)obj); | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         #region const | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -368,7 +436,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// </summary> | ||||
|         /// <param name="message"></param> | ||||
|         /// <returns></returns> | ||||
|         public virtual bool InputReceivedData(DmtpMessage message) | ||||
|         public virtual async Task<bool> InputReceivedData(DmtpMessage message) | ||||
|         { | ||||
|             this.LastActiveTime = DateTime.Now; | ||||
|             var byteBlock = message.BodyByteBlock; | ||||
| @@ -376,7 +444,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             { | ||||
|                 case P0_Close: | ||||
|                     { | ||||
|                         this.Close(false, message.GetBodyString()); | ||||
|                         _ = this.OnClosed(false, message.GetBodyString()); | ||||
|                         return true; | ||||
|                     } | ||||
|                 case P1_Handshake_Request: | ||||
| @@ -391,11 +459,11 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                 Metadata = waitVerify.Metadata, | ||||
|                                 Id = waitVerify.Id, | ||||
|                             }; | ||||
|                             this.OnHandshaking?.Invoke(this, args); | ||||
|                             await this.OnHandshaking(args).ConfigureFalseAwait(); | ||||
|  | ||||
|                             if (args.Id.HasValue()) | ||||
|                             { | ||||
|                                 this.OnResetId?.Invoke(this, new WaitSetId(this.Id, args.Id)); | ||||
|                                 await this.OnIdChanged(new IdChangedEventArgs(this.Id, args.Id)).ConfigureFalseAwait(); | ||||
|                                 this.Id = args.Id; | ||||
|                             } | ||||
|  | ||||
| @@ -403,24 +471,23 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             { | ||||
|                                 waitVerify.Id = this.Id; | ||||
|                                 waitVerify.Status = 1; | ||||
|                                 this.SendJsonObject(P2_Handshake_Response, waitVerify); | ||||
|                                 await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait(); | ||||
|                                 this.IsHandshaked = true; | ||||
|                                 args.Message = "Success"; | ||||
|  | ||||
|                                 Task.Factory.StartNew(this.PrivateHandshaked, args); | ||||
|                                 _ = Task.Factory.StartNew(this.PrivateOnHandshaked, args); | ||||
|                             } | ||||
|                             else//不允许连接 | ||||
|                             { | ||||
|                                 waitVerify.Status = 2; | ||||
|                                 waitVerify.Message = args.Message; | ||||
|                                 this.SendJsonObject(P2_Handshake_Response, waitVerify); | ||||
|                                 this.Close(false, args.Message); | ||||
|                                 await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait(); | ||||
|                                 _ = this.OnClosed(false, args.Message); | ||||
|                             } | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
|                             this.Logger.Error(this, $"在protocol={message.ProtocolFlags}中发生错误。信息:{ex.Message}"); | ||||
|                             this.Close(false, ex.Message); | ||||
|                             _ = this.OnClosed(false, ex.Message); | ||||
|                         } | ||||
|                         return true; | ||||
|                     } | ||||
| @@ -449,7 +516,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             var waitSetId = this.ResolveJsonObject<WaitSetId>(message.GetBodyString()); | ||||
|                             try | ||||
|                             { | ||||
|                                 this.OnResetId?.Invoke(this, waitSetId); | ||||
|                                 await this.OnIdChanged(new IdChangedEventArgs(waitSetId.OldId, waitSetId.NewId)).ConfigureFalseAwait(); | ||||
|                                 this.Id = waitSetId.NewId; | ||||
|                                 waitSetId.Status = 1; | ||||
|                             } | ||||
| @@ -458,7 +525,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                 waitSetId.Status = 2; | ||||
|                                 waitSetId.Message = ex.Message; | ||||
|                             } | ||||
|                             this.SendJsonObject(P4_ResetId_Response, waitSetId); | ||||
|                             await this.SendJsonObjectAsync(P4_ResetId_Response, waitSetId).ConfigureFalseAwait(); | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
| @@ -486,11 +553,12 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|                             if (this.AllowRoute && waitPing.Route) | ||||
|                             { | ||||
|                                 if (this.TryRoute(RouteType.Ping, waitPing)) | ||||
|  | ||||
|                                 if (await this.TryRoute(new PackageRouterEventArgs(RouteType.Ping, waitPing)).ConfigureFalseAwait()) | ||||
|                                 { | ||||
|                                     if (this.TryFindDmtpActor(waitPing.TargetId, out var actor)) | ||||
|                                     if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                                     { | ||||
|                                         actor.Send(P5_Ping_Request, byteBlock); | ||||
|                                         await actor.SendAsync(P5_Ping_Request, byteBlock).ConfigureFalseAwait(); | ||||
|                                         return true; | ||||
|                                     } | ||||
|                                     else | ||||
| @@ -508,7 +576,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                 waitPing.Status = TouchSocketDmtpStatus.Success.ToValue(); | ||||
|                             } | ||||
|                             waitPing.SwitchId(); | ||||
|                             this.SendJsonObject(P6_Ping_Response, waitPing); | ||||
|                             await this.SendJsonObjectAsync(P6_Ping_Response, waitPing).ConfigureFalseAwait(); | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
| @@ -524,9 +592,9 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|                             if (this.AllowRoute && waitPing.Route) | ||||
|                             { | ||||
|                                 if (this.TryFindDmtpActor(waitPing.TargetId, out var actor)) | ||||
|                                 if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                                 { | ||||
|                                     actor.Send(P6_Ping_Response, byteBlock); | ||||
|                                     await actor.SendAsync(P6_Ping_Response, byteBlock).ConfigureFalseAwait(); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
| @@ -548,11 +616,11 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             waitCreateChannel.UnpackageRouter(byteBlock); | ||||
|                             if (this.AllowRoute && waitCreateChannel.Route) | ||||
|                             { | ||||
|                                 if (this.TryRoute(RouteType.CreateChannel, waitCreateChannel)) | ||||
|                                 if (await this.TryRoute(new PackageRouterEventArgs(RouteType.CreateChannel, waitCreateChannel)).ConfigureFalseAwait()) | ||||
|                                 { | ||||
|                                     if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor)) | ||||
|                                     if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                                     { | ||||
|                                         actor.Send(P7_CreateChannel_Request, byteBlock); | ||||
|                                         await actor.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait(); | ||||
|                                         return true; | ||||
|                                     } | ||||
|                                     else | ||||
| @@ -593,7 +661,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             waitCreateChannel.SwitchId(); | ||||
|                             byteBlock.Reset(); | ||||
|                             waitCreateChannel.Package(byteBlock); | ||||
|                             this.Send(P8_CreateChannel_Response, byteBlock); | ||||
|                             await this.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait(); | ||||
|                         } | ||||
|                         catch (Exception ex) | ||||
|                         { | ||||
| @@ -609,9 +677,9 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             waitCreateChannel.UnpackageRouter(byteBlock); | ||||
|                             if (this.AllowRoute && waitCreateChannel.Route) | ||||
|                             { | ||||
|                                 if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor)) | ||||
|                                 if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                                 { | ||||
|                                     actor.Send(P8_CreateChannel_Response, byteBlock); | ||||
|                                     await actor.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait(); | ||||
|                                     return true; | ||||
|                                 } | ||||
|                             } | ||||
| @@ -635,9 +703,9 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                             channelPackage.UnpackageRouter(byteBlock); | ||||
|                             if (this.AllowRoute && channelPackage.Route) | ||||
|                             { | ||||
|                                 if (this.TryFindDmtpActor(channelPackage.TargetId, out var actor)) | ||||
|                                 if (await this.TryFindDmtpActor(channelPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                                 { | ||||
|                                     actor.Send(P9_ChannelPackage, byteBlock); | ||||
|                                     await actor.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait(); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
| @@ -648,7 +716,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                     channelPackage.DataType = ChannelDataType.DisposeOrder; | ||||
|                                     byteBlock.Reset(); | ||||
|                                     channelPackage.Package(byteBlock); | ||||
|                                     this.Send(P9_ChannelPackage, byteBlock); | ||||
|                                     await this.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait(); | ||||
|                                 } | ||||
|                             } | ||||
|                             else | ||||
| @@ -683,7 +751,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <inheritdoc/> | ||||
|         public virtual bool Ping(string targetId, int timeout = 5000) | ||||
|         { | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.Ping(timeout); | ||||
|             } | ||||
| @@ -697,15 +765,15 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual Task<bool> PingAsync(string targetId, int timeout = 5000) | ||||
|         public virtual async Task<bool> PingAsync(string targetId, int timeout = 5000) | ||||
|         { | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.PingAsync(timeout); | ||||
|                 return await actor.PingAsync(timeout).ConfigureFalseAwait(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return this.PrivatePingAsync(targetId, timeout); | ||||
|                 return await this.PrivatePingAsync(targetId, timeout).ConfigureFalseAwait(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -724,7 +792,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     { | ||||
|                         if (waitData.WaitResult.Status == 1) | ||||
|                         { | ||||
|                             this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id)); | ||||
|                             this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).GetFalseAwaitResult(); | ||||
|                             this.Id = id; | ||||
|                         } | ||||
|                         else | ||||
| @@ -754,13 +822,13 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|             this.SendJsonObject(P3_ResetId_Request, waitSetId); | ||||
|  | ||||
|             switch (await waitData.WaitAsync(5000)) | ||||
|             switch (await waitData.WaitAsync(5000).ConfigureFalseAwait()) | ||||
|             { | ||||
|                 case WaitDataStatus.SetRunning: | ||||
|                     { | ||||
|                         if (waitData.WaitResult.Status == 1) | ||||
|                         { | ||||
|                             this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id)); | ||||
|                             await this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).ConfigureFalseAwait(); | ||||
|                             this.Id = id; | ||||
|                         } | ||||
|                         else | ||||
| @@ -801,6 +869,17 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             this.Send(protocol, bytes, 0, bytes.Length); | ||||
|         } | ||||
|  | ||||
|         private Task SendJsonObjectAsync<T>(ushort protocol, in T obj) | ||||
|         { | ||||
| #if NET6_0_OR_GREATER | ||||
|             var bytes = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj, typeof(T), TouchSokcetDmtpSourceGenerationContext.Default); | ||||
| #else | ||||
|             var bytes = SerializeConvert.JsonSerializeToBytes(obj); | ||||
| #endif | ||||
|  | ||||
|             return this.SendAsync(protocol, bytes, 0, bytes.Length); | ||||
|         } | ||||
|  | ||||
|         private T ResolveJsonObject<T>(string json) | ||||
|         { | ||||
| #if NET6_0_OR_GREATER | ||||
| @@ -836,31 +915,34 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual bool TryFindDmtpActor(string targetId, out DmtpActor actor) | ||||
|         public virtual async Task<DmtpActor> TryFindDmtpActor(string targetId) | ||||
|         { | ||||
|             if (targetId == this.Id) | ||||
|             { | ||||
|                 actor = this; | ||||
|                 return true; | ||||
|                 return this; | ||||
|             } | ||||
|             if (this.OnFindDmtpActor?.Invoke(targetId) is DmtpActor newActor) | ||||
|             if (this.FindDmtpActor != null) | ||||
|             { | ||||
|                 actor = newActor; | ||||
|                 return true; | ||||
|                 if (await this.FindDmtpActor.Invoke(targetId).ConfigureFalseAwait() is DmtpActor newActor) | ||||
|                 { | ||||
|                     return newActor; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             actor = default; | ||||
|             return false; | ||||
|             return default; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual bool TryRoute(RouteType routerType, RouterPackage routerPackage) | ||||
|         public virtual async Task<bool> TryRoute(PackageRouterEventArgs e) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var args = new PackageRouterEventArgs(routerType, routerPackage); | ||||
|                 this.OnRouting?.Invoke(this, args); | ||||
|                 return args.IsPermitOperation; | ||||
|                 if (this.Routing != null) | ||||
|                 { | ||||
|                     await this.Routing.Invoke(this, e).ConfigureFalseAwait(); | ||||
|                     return e.IsPermitOperation; | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
| @@ -868,27 +950,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var args = new PackageRouterEventArgs(routerType, routerPackage); | ||||
|                 this.OnRouting?.Invoke(this, args); | ||||
|                 routerPackage.Message = args.Message; | ||||
|                 return args.IsPermitOperation; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void PrivateHandshaked(object obj) | ||||
|         { | ||||
|             this.OnHandshaked?.Invoke(this, (DmtpVerifyEventArgs)obj); | ||||
|         } | ||||
|  | ||||
|         private bool PrivatePing(string targetId, int timeout) | ||||
|         { | ||||
|             var waitPing = new WaitPing | ||||
| @@ -942,7 +1003,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             try | ||||
|             { | ||||
|                 this.SendJsonObject(P5_Ping_Request, waitPing); | ||||
|                 switch (await waitData.WaitAsync(timeout)) | ||||
|                 switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait()) | ||||
|                 { | ||||
|                     case WaitDataStatus.SetRunning: | ||||
|                         { | ||||
| @@ -971,7 +1032,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #region 重写 | ||||
|         #region 断开 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
| @@ -979,19 +1040,36 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <param name="disposing"></param> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.OnClose = null; | ||||
|             this.OnRouting = null; | ||||
|             this.OnFindDmtpActor = null; | ||||
|             this.OnHandshaked = null; | ||||
|             this.OnHandshaking = null; | ||||
|             this.OnResetId = null; | ||||
|  | ||||
|             this.Closed = null; | ||||
|             this.Routing = null; | ||||
|             this.FindDmtpActor = null; | ||||
|             this.Handshaked = null; | ||||
|             this.Handshaking = null; | ||||
|             this.IdChanged = null; | ||||
|             this.OutputSend = null; | ||||
|             this.OnClosed(true, nameof(Dispose)); | ||||
|             this.WaitHandlePool.SafeDispose(); | ||||
|             this.Close(false, nameof(Dispose)); | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|         /// <inheritdoc/> | ||||
|         public void Close(string msg) | ||||
|         { | ||||
|             this.OnClosed(true, msg); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public bool SendClose(string msg) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 this.SendString(0, msg); | ||||
|                 return true; | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         #endregion 重写 | ||||
|  | ||||
|         #region 协议同步发送 | ||||
| @@ -1005,7 +1083,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)), | ||||
|             new ArraySegment<byte>(buffer,offset,length) | ||||
|            }; | ||||
|             this.OutputSend?.Invoke(this, transferBytes); | ||||
|             this.OutputSend.Invoke(this, transferBytes); | ||||
|             this.LastActiveTime = DateTime.Now; | ||||
|         } | ||||
|  | ||||
| @@ -1022,10 +1100,20 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <inheritdoc/> | ||||
|         public virtual Task SendAsync(ushort protocol, byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return Task.Run(() => | ||||
|             var transferBytes = new ArraySegment<byte>[] | ||||
|             { | ||||
|                 this.Send(protocol, buffer, offset, length); | ||||
|             }); | ||||
|             new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)), | ||||
|             new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)), | ||||
|             new ArraySegment<byte>(buffer,offset,length) | ||||
|             }; | ||||
|             this.LastActiveTime = DateTime.Now; | ||||
|             return this.OutputSendAsync.Invoke(this, transferBytes); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual Task SendAsync(ushort protocol, ByteBlock byteBlock) | ||||
|         { | ||||
|             return this.SendAsync(protocol, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|         } | ||||
|  | ||||
|         #endregion 协议异步发送 | ||||
| @@ -1059,7 +1147,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             { | ||||
|                 throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId)); | ||||
|             } | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.CreateChannel(id, metadata); | ||||
|             } | ||||
| @@ -1077,7 +1165,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId)); | ||||
|             } | ||||
|  | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.CreateChannel(metadata); | ||||
|             } | ||||
| @@ -1100,37 +1188,37 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default) | ||||
|         public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default) | ||||
|         { | ||||
|             if (string.IsNullOrEmpty(targetId)) | ||||
|             { | ||||
|                 throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId)); | ||||
|             } | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.CreateChannelAsync(id, metadata); | ||||
|                 return await actor.CreateChannelAsync(id, metadata).ConfigureFalseAwait(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return this.PrivateCreateChannelAsync(targetId, false, id, metadata); | ||||
|                 return await this.PrivateCreateChannelAsync(targetId, false, id, metadata).ConfigureFalseAwait(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default) | ||||
|         public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default) | ||||
|         { | ||||
|             if (string.IsNullOrEmpty(targetId)) | ||||
|             { | ||||
|                 throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId)); | ||||
|             } | ||||
|  | ||||
|             if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor)) | ||||
|             if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|             { | ||||
|                 return actor.CreateChannelAsync(metadata); | ||||
|                 return await actor.CreateChannelAsync(metadata).ConfigureFalseAwait(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return this.PrivateCreateChannelAsync(targetId, true, 0, metadata); | ||||
|                 return await this.PrivateCreateChannelAsync(targetId, true, 0, metadata).ConfigureFalseAwait(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -1208,9 +1296,14 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                         var channel = new InternalChannel(this, targetId, result.Metadata); | ||||
|                                         channel.SetId(result.ChannelId); | ||||
|                                         channel.SetUsing(); | ||||
|                                         return this.m_userChannels.TryAdd(result.ChannelId, channel) | ||||
|                                             ? (IDmtpChannel)channel | ||||
|                                             : throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription()); | ||||
|                                         if (this.m_userChannels.TryAdd(result.ChannelId, channel)) | ||||
|                                         { | ||||
|                                             return channel; | ||||
|                                         } | ||||
|                                         else | ||||
|                                         { | ||||
|                                             throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription()); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 case TouchSocketDmtpStatus.ClientNotFind: | ||||
|                                     { | ||||
| @@ -1269,8 +1362,8 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             try | ||||
|             { | ||||
|                 waitCreateChannel.Package(byteBlock); | ||||
|                 this.Send(P7_CreateChannel_Request, byteBlock); | ||||
|                 switch (await waitData.WaitAsync(10 * 1000)) | ||||
|                 await this.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait(); | ||||
|                 switch (await waitData.WaitAsync(10 * 1000).ConfigureFalseAwait()) | ||||
|                 { | ||||
|                     case WaitDataStatus.SetRunning: | ||||
|                         { | ||||
| @@ -1282,9 +1375,14 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                                         var channel = new InternalChannel(this, targetId, result.Metadata); | ||||
|                                         channel.SetId(result.ChannelId); | ||||
|                                         channel.SetUsing(); | ||||
|                                         return this.m_userChannels.TryAdd(result.ChannelId, channel) | ||||
|                                             ? (IDmtpChannel)channel | ||||
|                                             : throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription()); | ||||
|                                         if (this.m_userChannels.TryAdd(result.ChannelId, channel)) | ||||
|                                         { | ||||
|                                             return channel; | ||||
|                                         } | ||||
|                                         else | ||||
|                                         { | ||||
|                                             throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription()); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 case TouchSocketDmtpStatus.ClientNotFind: | ||||
|                                     { | ||||
| @@ -1333,7 +1431,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 channel.SetId(id); | ||||
|                 if (this.m_userChannels.TryAdd(id, channel)) | ||||
|                 { | ||||
|                     Task.Factory.StartNew(this.ThisRequestCreateChannel, new CreateChannelEventArgs(id, metadata)); | ||||
|                     Task.Factory.StartNew(this.PrivateOnCreatedChannel, new CreateChannelEventArgs(id, metadata)); | ||||
|                     return true; | ||||
|                 } | ||||
|                 else | ||||
| @@ -1344,16 +1442,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void ThisRequestCreateChannel(object state) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 this.OnCreateChannel?.Invoke(this, (CreateChannelEventArgs)state); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #endregion IDmtpChannel | ||||
|     } | ||||
|   | ||||
| @@ -152,9 +152,8 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <summary> | ||||
|         /// 关闭 | ||||
|         /// </summary> | ||||
|         /// <param name="sendClose">是否发送close报文</param> | ||||
|         /// <param name="message">传递消息</param> | ||||
|         void Close(bool sendClose, string message); | ||||
|         void Close(string message); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 向当前对点发送一个Ping报文,并且等待回应。 | ||||
| @@ -226,6 +225,14 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <param name="length"></param> | ||||
|         Task SendAsync(ushort protocol, byte[] buffer, int offset, int length); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 异步发送字节块 | ||||
|         /// </summary> | ||||
|         /// <param name="protocol"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <returns></returns> | ||||
|         Task SendAsync(ushort protocol, ByteBlock byteBlock); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 以Fast序列化,发送小(64K)对象。接收方需要使用ReadObject读取对象。 | ||||
|         /// </summary> | ||||
| @@ -260,25 +267,20 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 尝试获取指定Id的DmtpActor。一般此方法仅在Service下有效。 | ||||
|         /// </summary> | ||||
|         /// <param name="targetId"></param> | ||||
|         /// <param name="actor"></param> | ||||
|         /// <returns></returns> | ||||
|         bool TryFindDmtpActor(string targetId, out DmtpActor actor); | ||||
|         Task<DmtpActor> TryFindDmtpActor(string targetId); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 尝试请求路由,触发路由相关插件。 | ||||
|         /// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgPermitEventArgs.Message"/>中传递消息。 | ||||
|         /// </summary> | ||||
|         /// <param name="routerType"></param> | ||||
|         /// <param name="routerPackage"></param> | ||||
|         /// <returns></returns> | ||||
|         bool TryRoute(RouteType routerType, RouterPackage routerPackage); | ||||
|         Task<bool> TryRoute(PackageRouterEventArgs e); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgRouterPackage.Message"/>中传递消息。 | ||||
|         /// 发送Close请求 | ||||
|         /// </summary> | ||||
|         /// <param name="routerType"></param> | ||||
|         /// <param name="routerPackage"></param> | ||||
|         /// <returns></returns> | ||||
|         bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage); | ||||
|         /// <param name="msg"></param> | ||||
|         bool SendClose(string msg); | ||||
|  | ||||
|         #endregion 方法 | ||||
|     } | ||||
|   | ||||
| @@ -17,17 +17,22 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|     /// </summary> | ||||
|     public class TcpDmtpAdapter : CustomFixedHeaderByteBlockDataHandlingAdapter<DmtpMessage> | ||||
|     { | ||||
|         private SpinLock m_locker = new SpinLock(); | ||||
|         private readonly SemaphoreSlim m_locker = new SemaphoreSlim(1, 1); | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CanSendRequestInfo => true; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CanSplicingSend => false; | ||||
|         public override bool CanSplicingSend => true; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override int HeaderLength => 6; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 最大拼接 | ||||
|         /// </summary> | ||||
|         public const int MaxSplicing = 1024 * 64; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override DmtpMessage GetInstance() | ||||
|         { | ||||
| @@ -40,6 +45,25 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             request.SafeDispose(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             if (!(requestInfo is DmtpMessage message)) | ||||
|             { | ||||
|                 throw new Exception($"无法将{nameof(requestInfo)}转换为{nameof(DmtpMessage)}"); | ||||
|             } | ||||
|             if (message.BodyByteBlock != null && message.BodyByteBlock.Length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}"); | ||||
|             } | ||||
|             using (var byteBlock = new ByteBlock(message.GetLength())) | ||||
|             { | ||||
|                 message.Build(byteBlock); | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void PreviewSend(IRequestInfo requestInfo) | ||||
|         { | ||||
| @@ -58,6 +82,54 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             if (transferBytes.Count == 0) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             var length = 0; | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|  | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|  | ||||
|                     await this.m_locker.WaitAsync(); | ||||
|                     foreach (var item in transferBytes) | ||||
|                     { | ||||
|                         await this.GoSendAsync(item.Array, item.Offset, item.Count); | ||||
|                     } | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                     this.m_locker.Release(); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock(length)) | ||||
|                 { | ||||
|                     foreach (var item in transferBytes) | ||||
|                     { | ||||
|                         byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                     } | ||||
|                     await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void PreviewSend(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
| @@ -77,10 +149,12 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|  | ||||
|             var lockTaken = false; | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                 this.m_locker.Enter(ref lockTaken); | ||||
|  | ||||
|                     this.m_locker.Wait(); | ||||
|                     foreach (var item in transferBytes) | ||||
|                     { | ||||
|                         this.GoSend(item.Array, item.Offset, item.Count); | ||||
| @@ -88,9 +162,18 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                 if (lockTaken) | ||||
|                     this.m_locker.Release(); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                     this.m_locker.Exit(false); | ||||
|                 using (var byteBlock = new ByteBlock(length)) | ||||
|                 { | ||||
|                     foreach (var item in transferBytes) | ||||
|                     { | ||||
|                         byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                     } | ||||
|                     this.GoSend(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -33,19 +33,19 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         #region 字段 | ||||
|  | ||||
|         private bool m_allowRoute; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private DmtpActor m_smtpActor; | ||||
|         private Func<string, Task<IDmtpActor>> m_findDmtpActor; | ||||
|         private DmtpActor m_dmtpActor; | ||||
|         private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|         #endregion 字段 | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.Id"/> | ||||
|         public string Id => this.DmtpActor.Id; | ||||
|         public string Id => this.m_dmtpActor.Id; | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|         public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|         public IDmtpActor DmtpActor { get => this.m_dmtpActor; } | ||||
|  | ||||
|         #region 连接 | ||||
|  | ||||
| @@ -78,7 +78,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 if (response.StatusCode == 101) | ||||
|                 { | ||||
|                     this.SwitchProtocolToDmtp(); | ||||
|                     this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                         this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), | ||||
|                         timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None); | ||||
|                     return this; | ||||
| @@ -114,7 +114,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 if (response.StatusCode == 101) | ||||
|                 { | ||||
|                     this.SwitchProtocolToDmtp(); | ||||
|                     this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                         this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), | ||||
|                         timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token); | ||||
|                     return this; | ||||
| @@ -156,7 +156,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 if (response.StatusCode == 101) | ||||
|                 { | ||||
|                     this.SwitchProtocolToDmtp(); | ||||
|                     await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                          this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), | ||||
|                          timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None); | ||||
|                     return this; | ||||
| @@ -184,7 +184,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 if (!this.Online) | ||||
|                 { | ||||
|                     await base.ConnectAsync(timeout, token); | ||||
|                     await base.ConnectAsync(timeout); | ||||
|                 } | ||||
|  | ||||
|                 var request = new HttpRequest() | ||||
| @@ -197,7 +197,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 if (response.StatusCode == 101) | ||||
|                 { | ||||
|                     this.SwitchProtocolToDmtp(); | ||||
|                     await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                          this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), | ||||
|                          timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token); | ||||
|                     return this; | ||||
| @@ -215,19 +215,47 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|         #endregion 连接 | ||||
|  | ||||
|         #region 断开 | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.DmtpActor.SafeDispose(); | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.SafeDispose(); | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送<see cref="IDmtpActor"/>关闭消息。 | ||||
|         /// </summary> | ||||
|         /// <param name="msg"></param> | ||||
|         /// <returns></returns> | ||||
|         public override void Close(string msg = "") | ||||
|         { | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor.SendClose(msg); | ||||
|                 this.m_dmtpActor.Close(msg); | ||||
|             } | ||||
|             base.Close(msg); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.m_dmtpActor?.Close(e.Message); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         #endregion | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message) | ||||
|             { | ||||
|                 if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|                 if (!await this.m_dmtpActor.InputReceivedData(message)) | ||||
|                 { | ||||
|                     if (this.PluginsManager.Enable) | ||||
|                     { | ||||
| @@ -250,25 +278,19 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             await base.OnDisconnected(e); | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|         } | ||||
|  | ||||
|         #region ResetId | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetId(string)"/> | ||||
|         public void ResetId(string id) | ||||
|         { | ||||
|             this.m_smtpActor.ResetId(id); | ||||
|             this.m_dmtpActor.ResetId(id); | ||||
|         } | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/> | ||||
|         public Task ResetIdAsync(string newId) | ||||
|         { | ||||
|             return this.m_smtpActor.ResetIdAsync(newId); | ||||
|             return this.m_dmtpActor.ResetIdAsync(newId); | ||||
|         } | ||||
|  | ||||
|         #endregion ResetId | ||||
| @@ -277,72 +299,47 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         { | ||||
|             this.Protocol = DmtpUtility.DmtpProtocol; | ||||
|             this.SetDataHandlingAdapter(new TcpDmtpAdapter()); | ||||
|             this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute) | ||||
|             this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute) | ||||
|             { | ||||
|                 OutputSend = DmtpActorSend, | ||||
|                 OnRouting = OnDmtpActorRouting, | ||||
|                 OnHandshaking = this.OnDmtpActorHandshaking, | ||||
|                 OnHandshaked = OnDmtpActorHandshaked, | ||||
|                 OnClose = OnDmtpActorClose, | ||||
|                 OnCreateChannel = this.OnDmtpActorCreateChannel, | ||||
|                 OutputSend = this.DmtpActorSend, | ||||
|                 OutputSendAsync = this.DmtpActorSendAsync, | ||||
|                 Routing = this.OnDmtpActorRouting, | ||||
|                 Handshaking = this.OnDmtpActorHandshaking, | ||||
|                 Handshaked = this.OnDmtpActorHandshaked, | ||||
|                 Closed = this.OnDmtpActorClose, | ||||
|                 CreatedChannel = this.OnDmtpActorCreateChannel, | ||||
|                 Logger = this.Logger, | ||||
|                 Client = this, | ||||
|                 OnFindDmtpActor = this.m_findDmtpActor | ||||
|                 FindDmtpActor = this.m_findDmtpActor | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         private Task OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         { | ||||
|             base.Close(msg); | ||||
|             base.BreakOut(false, msg); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             this.OnCreateChannel(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             return this.OnCreateChannel(e); | ||||
|         } | ||||
|  | ||||
|             this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             return this.OnHandshaked(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaked(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnHandshaking(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaking(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             this.OnRouting(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
| @@ -350,6 +347,11 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             return base.SendAsync(transferBytes); | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
|  | ||||
|         #region 事件触发 | ||||
| @@ -358,32 +360,53 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 当创建通道 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnCreateChannel(CreateChannelEventArgs e) | ||||
|         protected virtual async Task OnCreateChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e">参数</param> | ||||
|         protected virtual void OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当需要转发路由包时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnRouting(PackageRouterEventArgs e) | ||||
|         protected virtual async Task OnRouting(PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e); | ||||
|         } | ||||
|  | ||||
|         #endregion 事件触发 | ||||
|   | ||||
| @@ -46,7 +46,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         #region 字段 | ||||
|  | ||||
|         private bool m_allowRoute; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private Func<string, Task<IDmtpActor>> m_findDmtpActor; | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
| @@ -68,17 +68,28 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             await base.OnConnected(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         private IDmtpActor OnServiceFindDmtpActor(string id) | ||||
|         { | ||||
|             return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null; | ||||
|         } | ||||
|  | ||||
|         private DmtpActor PrivateOnRpcActorInit() | ||||
|         { | ||||
|             return new SealedDmtpActor(this.m_allowRoute) | ||||
|             { | ||||
|                 OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null | ||||
|                 FindDmtpActor = this.FindDmtpActor | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         private async Task<IDmtpActor> FindDmtpActor(string id) | ||||
|         { | ||||
|             if (this.m_allowRoute) | ||||
|             { | ||||
|                 if (this.m_findDmtpActor != null) | ||||
|                 { | ||||
|                     return await this.m_findDmtpActor.Invoke(id); | ||||
|                 } | ||||
|                 return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -31,14 +31,14 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|     public class HttpDmtpSocketClient : HttpSocketClient, IHttpDmtpSocketClient | ||||
|     { | ||||
|         internal Func<DmtpActor> m_internalOnRpcActorInit; | ||||
|         private DmtpActor m_smtpActor; | ||||
|         private DmtpActor m_dmtpActor; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_dmtpActor; } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 验证超时时间,默认为3000ms | ||||
|         /// </summary> | ||||
| @@ -49,42 +49,18 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// </summary> | ||||
|         public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty); | ||||
|  | ||||
|         #region 断开 | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override void Close(string msg = "") | ||||
|         { | ||||
|             if (this.m_smtpActor == null) | ||||
|             if (this.m_dmtpActor != null) | ||||
|             { | ||||
|                 this.m_dmtpActor.SendClose(msg); | ||||
|                 this.m_dmtpActor.Close(msg); | ||||
|             } | ||||
|             base.Close(msg); | ||||
|                 return; | ||||
|         } | ||||
|             this.m_smtpActor.Close(true, msg); | ||||
|         } | ||||
|  | ||||
|         #region ResetId | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.ResetId(string)"/> | ||||
|         public override void ResetId(string newId) | ||||
|         { | ||||
|             if (this.m_smtpActor == null) | ||||
|             { | ||||
|                 base.ResetId(newId); | ||||
|                 return; | ||||
|             } | ||||
|             this.m_smtpActor.ResetId(newId); | ||||
|         } | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/> | ||||
|         public async Task ResetIdAsync(string newId) | ||||
|         { | ||||
|             if (this.m_smtpActor == null) | ||||
|             { | ||||
|                 base.ResetId(newId); | ||||
|                 return; | ||||
|             } | ||||
|             await this.m_smtpActor.ResetIdAsync(newId); | ||||
|         } | ||||
|  | ||||
|         #endregion ResetId | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
| @@ -92,54 +68,48 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <param name="disposing"></param> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.DmtpActor?.SafeDispose(); | ||||
|             this.m_dmtpActor?.SafeDispose(); | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         ///// <inheritdoc/> | ||||
|         //protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         //{ | ||||
|         //    if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message) | ||||
|         //    { | ||||
|         //        if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|         //        { | ||||
|         //            if (this.PluginsManager.Enable) | ||||
|         //            { | ||||
|         //                this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|         //            } | ||||
|         //        } | ||||
|  | ||||
|         //        return false; | ||||
|         //    } | ||||
|         //    else | ||||
|         //    { | ||||
|         //        return base.HandleReceivedData(byteBlock, requestInfo); | ||||
|         //    } | ||||
|         //} | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message) | ||||
|             { | ||||
|                 if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|                 { | ||||
|                     await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|             } | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.DmtpActor?.Close(false, e.Message); | ||||
|             this.m_dmtpActor?.Close(e.Message); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         #endregion 断开 | ||||
|  | ||||
|         #region ResetId | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.ResetId(string)"/> | ||||
|         public override void ResetId(string newId) | ||||
|         { | ||||
|             if (this.m_dmtpActor == null) | ||||
|             { | ||||
|                 base.ResetId(newId); | ||||
|                 return; | ||||
|             } | ||||
|             this.m_dmtpActor.ResetId(newId); | ||||
|         } | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/> | ||||
|         public async Task ResetIdAsync(string newId) | ||||
|         { | ||||
|             if (this.m_dmtpActor == null) | ||||
|             { | ||||
|                 base.ResetId(newId); | ||||
|                 return; | ||||
|             } | ||||
|             await this.m_dmtpActor.ResetIdAsync(newId); | ||||
|         } | ||||
|  | ||||
|         #endregion ResetId | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
| @@ -158,66 +128,73 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             await base.OnReceivedHttpRequest(request); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message) | ||||
|             { | ||||
|                 if (!await this.m_dmtpActor.InputReceivedData(message)) | ||||
|                 { | ||||
|                     await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|             } | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         private Task OnDmtpIdChanged(DmtpActor actor, IdChangedEventArgs e) | ||||
|         { | ||||
|             this.DirectResetId(e.NewId); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void SetRpcActor(DmtpActor actor) | ||||
|         { | ||||
|             actor.Id = this.Id; | ||||
|             actor.OnResetId = this.ThisOnResetId; | ||||
|             actor.IdChanged = this.OnDmtpIdChanged; | ||||
|             actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync; | ||||
|             actor.OutputSend = this.ThisDmtpActorOutputSend; | ||||
|             actor.Client = this; | ||||
|             actor.OnClose = this.OnDmtpActorClose; | ||||
|             actor.OnRouting = this.OnDmtpActorRouting; | ||||
|             actor.OnHandshaked = this.OnDmtpActorHandshaked; | ||||
|             actor.OnHandshaking = this.OnDmtpActorHandshaking; | ||||
|             actor.OnCreateChannel = this.OnDmtpActorCreateChannel; | ||||
|             actor.Closed = this.OnDmtpActorClose; | ||||
|             actor.Routing = this.OnDmtpActorRouting; | ||||
|             actor.Handshaked = this.OnDmtpActorHandshaked; | ||||
|             actor.Handshaking = this.OnDmtpActorHandshaking; | ||||
|             actor.CreatedChannel = this.OnDmtpActorCreatedChannel; | ||||
|             actor.Logger = this.Logger; | ||||
|             this.m_smtpActor = actor; | ||||
|             this.m_dmtpActor = actor; | ||||
|  | ||||
|             this.Protocol = DmtpUtility.DmtpProtocol; | ||||
|             this.SetDataHandlingAdapter(new TcpDmtpAdapter()); | ||||
|         } | ||||
|  | ||||
|         private void ThisOnResetId(DmtpActor actor, WaitSetId waitSetId) | ||||
|         { | ||||
|             this.DirectResetId(waitSetId.NewId); | ||||
|         } | ||||
|  | ||||
|         private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             return base.SendAsync(transferBytes); | ||||
|         } | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         private Task OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         { | ||||
|             base.Close(msg); | ||||
|             base.BreakOut(false, msg); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             this.OnCreateChannel(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             return this.OnCreatedChannel(e); | ||||
|         } | ||||
|  | ||||
|             this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             return this.OnHandshaked(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaked(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Token == this.VerifyToken) | ||||
|             { | ||||
| @@ -228,25 +205,12 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 e.Message = "Token不受理"; | ||||
|             } | ||||
|  | ||||
|             this.OnHandshaking(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|             return this.OnHandshaking(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             this.OnRouting(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
| @@ -257,32 +221,53 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 当创建通道 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnCreateChannel(CreateChannelEventArgs e) | ||||
|         protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在验证Token时 | ||||
|         /// </summary> | ||||
|         /// <param name="e">参数</param> | ||||
|         protected virtual void OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在需要转发路由包时。 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnRouting(PackageRouterEventArgs e) | ||||
|         protected virtual async Task OnRouting(PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e); | ||||
|         } | ||||
|  | ||||
|         #endregion 事件 | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Dmtp | ||||
| { | ||||
|     /// <summary> | ||||
|   | ||||
| @@ -39,22 +39,24 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|         public IDmtpActor DmtpActor { get => this.m_dmtpActor; } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.Id"/> | ||||
|         public string Id => this.DmtpActor.Id; | ||||
|         public string Id => this.m_dmtpActor.Id; | ||||
|  | ||||
|         #region 字段 | ||||
|  | ||||
|         private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|         private bool m_allowRoute; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private SealedDmtpActor m_smtpActor; | ||||
|         private SealedDmtpActor m_dmtpActor; | ||||
|         private Func<string, Task<IDmtpActor>> m_findDmtpActor; | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|         public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked; | ||||
|  | ||||
|         #region 断开 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送<see cref="IDmtpActor"/>关闭消息。 | ||||
| @@ -63,10 +65,33 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <returns></returns> | ||||
|         public override void Close(string msg = "") | ||||
|         { | ||||
|             this.DmtpActor.Close(true, msg); | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.SendClose(msg); | ||||
|                 this.m_dmtpActor?.Close(msg); | ||||
|             } | ||||
|             base.Close(msg); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.SafeDispose(); | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.m_dmtpActor?.Close(e.Message); | ||||
|             await base.OnDisconnected(e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         #endregion 断开 | ||||
|  | ||||
|         #region 连接 | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -87,7 +112,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     base.Connect(timeout); | ||||
|                 } | ||||
|  | ||||
|                 this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                 this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None); | ||||
|                 return this; | ||||
|             } | ||||
| @@ -107,7 +132,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     base.Connect(timeout); | ||||
|                 } | ||||
|  | ||||
|                 this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                 this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token); | ||||
|                 return this; | ||||
|             } | ||||
| @@ -129,11 +154,10 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 if (!this.Online) | ||||
|                 { | ||||
|                     await base.ConnectAsync(timeout); | ||||
|                     await base.ConnectAsync(timeout).ConfigureFalseAwait(); | ||||
|                 } | ||||
|  | ||||
|                 await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                      this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None); | ||||
|                 await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None).ConfigureFalseAwait(); | ||||
|                 return this; | ||||
|             } | ||||
|             finally | ||||
| @@ -154,11 +178,10 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 if (!this.Online) | ||||
|                 { | ||||
|                     await base.ConnectAsync(timeout, token); | ||||
|                     await base.ConnectAsync(timeout).ConfigureFalseAwait(); | ||||
|                 } | ||||
|  | ||||
|                 await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                      this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token); | ||||
|                 await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token).ConfigureFalseAwait(); | ||||
|                 return this; | ||||
|             } | ||||
|             finally | ||||
| @@ -174,13 +197,13 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetId(string)"/> | ||||
|         public void ResetId(string id) | ||||
|         { | ||||
|             this.m_smtpActor.ResetId(id); | ||||
|             this.m_dmtpActor.ResetId(id); | ||||
|         } | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/> | ||||
|         public Task ResetIdAsync(string newId) | ||||
|         { | ||||
|             return this.m_smtpActor.ResetIdAsync(newId); | ||||
|             return this.m_dmtpActor.ResetIdAsync(newId); | ||||
|         } | ||||
|  | ||||
|         #endregion ResetId | ||||
| @@ -229,13 +252,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|         #endregion 发送 | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.DmtpActor.SafeDispose(); | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void LoadConfig(TouchSocketConfig config) | ||||
|         { | ||||
| @@ -246,37 +262,31 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 this.m_allowRoute = true; | ||||
|                 this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor; | ||||
|             } | ||||
|             this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute) | ||||
|             this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute) | ||||
|             { | ||||
|                 OutputSend = this.DmtpActorSend, | ||||
|                 OnRouting = this.OnDmtpActorRouting, | ||||
|                 OnHandshaking = this.OnDmtpActorHandshaking, | ||||
|                 OnHandshaked = this.OnDmtpActorHandshaked, | ||||
|                 OnClose = this.OnDmtpActorClose, | ||||
|                 OutputSendAsync = this.DmtpActorSendAsync, | ||||
|                 Routing = this.OnDmtpActorRouting, | ||||
|                 Handshaking = this.OnDmtpActorHandshaking, | ||||
|                 Handshaked = this.OnDmtpActorHandshaked, | ||||
|                 Closed = this.OnDmtpActorClose, | ||||
|                 Logger = this.Logger, | ||||
|                 Client = this, | ||||
|                 OnFindDmtpActor = this.m_findDmtpActor, | ||||
|                 OnCreateChannel = this.OnDmtpActorCreateChannel | ||||
|                 FindDmtpActor = this.m_findDmtpActor, | ||||
|                 CreatedChannel = this.OnDmtpActorCreateChannel | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             await base.OnDisconnected(e); | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             var message = (DmtpMessage)e.RequestInfo; | ||||
|             if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|             if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait()) | ||||
|             { | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait(); | ||||
|             } | ||||
|  | ||||
|             await base.ReceivedData(e); | ||||
|             await base.ReceivedData(e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
| @@ -286,52 +296,35 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             base.Close(msg); | ||||
|             return base.SendAsync(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         { | ||||
|             this.OnCreateChannel(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             this.BreakOut(false, msg); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|             this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             return this.OnCreatedChannel(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaked(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnHandshaked(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaking(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|             return this.OnHandshaking(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.OnRouting(e); | ||||
|             return this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
| @@ -342,32 +335,53 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 当创建通道 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnCreateChannel(CreateChannelEventArgs e) | ||||
|         protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e">参数</param> | ||||
|         protected virtual void OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当需要转发路由包时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnRouting(PackageRouterEventArgs e) | ||||
|         protected virtual async Task OnRouting(PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         #endregion 事件触发 | ||||
|   | ||||
| @@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         #region 字段 | ||||
|  | ||||
|         private bool m_allowRoute; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private Func<string, Task<IDmtpActor>> m_findDmtpActor; | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
| @@ -73,14 +73,25 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             socketClient.SetDmtpActor(new SealedDmtpActor(this.m_allowRoute) | ||||
|             { | ||||
|                 Id = e.Id, | ||||
|                 OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null | ||||
|                 FindDmtpActor = this.FindDmtpActor | ||||
|             }); | ||||
|             await base.OnConnecting(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         private IDmtpActor OnServiceFindDmtpActor(string id) | ||||
|         private async Task<IDmtpActor> FindDmtpActor(string id) | ||||
|         { | ||||
|             if (this.m_allowRoute) | ||||
|             { | ||||
|                 if (this.m_findDmtpActor != null) | ||||
|                 { | ||||
|                     return await this.m_findDmtpActor.Invoke(id); | ||||
|                 } | ||||
|                 return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -30,7 +30,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|     /// </summary> | ||||
|     public partial class TcpDmtpSocketClient : SocketClient, ITcpDmtpSocketClient | ||||
|     { | ||||
|         private DmtpActor m_smtpActor; | ||||
|         private DmtpActor m_dmtpActor; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// TcpDmtpSocketClient | ||||
| @@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|         public IDmtpActor DmtpActor { get => this.m_dmtpActor; } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
| @@ -58,36 +58,23 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         private Task OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         { | ||||
|             base.Close(msg); | ||||
|             base.BreakOut(false, msg); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             this.OnCreateChannel(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             return this.OnCreateChannel(e); | ||||
|         } | ||||
|  | ||||
|             this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             return this.OnHandshaked(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaked(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private async Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Token == this.VerifyToken) | ||||
|             { | ||||
| @@ -98,25 +85,12 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 e.Message = "Token不受理"; | ||||
|             } | ||||
|  | ||||
|             this.OnHandshaking(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|             await this.OnHandshaking(e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             this.OnRouting(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
| @@ -127,99 +101,147 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 当创建通道 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnCreateChannel(CreateChannelEventArgs e) | ||||
|         protected virtual async Task OnCreateChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在验证Token时 | ||||
|         /// </summary> | ||||
|         /// <param name="e">参数</param> | ||||
|         protected virtual void OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在需要转发路由包时。 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnRouting(PackageRouterEventArgs e) | ||||
|         protected virtual async Task OnRouting(PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e); | ||||
|         } | ||||
|  | ||||
|         #endregion 事件 | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         #region 断开 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送<see cref="IDmtpActor"/>关闭消息。 | ||||
|         /// </summary> | ||||
|         /// <param name="msg"></param> | ||||
|         /// <returns></returns> | ||||
|         public override void Close(string msg = "") | ||||
|         { | ||||
|             this.m_smtpActor.Close(true, msg); | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.SendClose(msg); | ||||
|                 this.m_dmtpActor?.Close(msg); | ||||
|             } | ||||
|             base.Close(msg); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.SafeDispose(); | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             if (this.IsHandshaked) | ||||
|             { | ||||
|                 this.m_dmtpActor?.Close(e.Message); | ||||
|             } | ||||
|             await base.OnDisconnected(e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         #endregion 断开 | ||||
|  | ||||
|         #region ResetId | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetId(string)"/> | ||||
|         public override void ResetId(string id) | ||||
|         { | ||||
|             this.m_smtpActor.ResetId(id); | ||||
|             this.m_dmtpActor.ResetId(id); | ||||
|         } | ||||
|  | ||||
|         ///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/> | ||||
|         public Task ResetIdAsync(string newId) | ||||
|         { | ||||
|             return this.m_smtpActor.ResetIdAsync(newId); | ||||
|             return this.m_dmtpActor.ResetIdAsync(newId); | ||||
|         } | ||||
|  | ||||
|         #endregion ResetId | ||||
|  | ||||
|         internal void SetDmtpActor(DmtpActor actor) | ||||
|         { | ||||
|             actor.OnResetId = this.ThisOnResetId; | ||||
|             actor.IdChanged = this.ThisOnResetId; | ||||
|             actor.OutputSend = this.ThisDmtpActorOutputSend; | ||||
|             actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync; | ||||
|             actor.Client = this; | ||||
|             actor.OnClose = this.OnDmtpActorClose; | ||||
|             actor.OnRouting = this.OnDmtpActorRouting; | ||||
|             actor.OnHandshaked = this.OnDmtpActorHandshaked; | ||||
|             actor.OnHandshaking = this.OnDmtpActorHandshaking; | ||||
|             actor.OnCreateChannel = this.OnDmtpActorCreateChannel; | ||||
|             actor.Closed = this.OnDmtpActorClose; | ||||
|             actor.Routing = this.OnDmtpActorRouting; | ||||
|             actor.Handshaked = this.OnDmtpActorHandshaked; | ||||
|             actor.Handshaking = this.OnDmtpActorHandshaking; | ||||
|             actor.CreatedChannel = this.OnDmtpActorCreateChannel; | ||||
|             actor.Logger = this.Logger; | ||||
|             this.m_smtpActor = actor; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.DmtpActor.SafeDispose(); | ||||
|             base.Dispose(disposing); | ||||
|             this.m_dmtpActor = actor; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             var message = (DmtpMessage)e.RequestInfo; | ||||
|             if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|             if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait()) | ||||
|             { | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait(); | ||||
|             } | ||||
|             await base.ReceivedData(e); | ||||
|             await base.ReceivedData(e).ConfigureFalseAwait(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnConnected(ConnectedEventArgs e) | ||||
|         { | ||||
|             this.m_smtpActor.Id = this.Id; | ||||
|             await base.OnConnected(e); | ||||
|             this.m_dmtpActor.Id = this.Id; | ||||
|             await base.OnConnected(e).ConfigureFalseAwait(); | ||||
|  | ||||
|             _ = Task.Run(async () => | ||||
|             { | ||||
|                 await Task.Delay(this.VerifyTimeout); | ||||
|                 await Task.Delay(this.VerifyTimeout).ConfigureFalseAwait(); | ||||
|                 if (!this.IsHandshaked) | ||||
|                 { | ||||
|                     this.TryShutdown(); | ||||
| @@ -228,21 +250,20 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private void ThisOnResetId(DmtpActor rpcActor, WaitSetId waitSetId) | ||||
|         private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             this.DirectResetId(waitSetId.NewId); | ||||
|             return base.SendAsync(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private Task ThisOnResetId(DmtpActor rpcActor, IdChangedEventArgs e) | ||||
|         { | ||||
|             this.DirectResetId(e.NewId); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         #region 发送 | ||||
|   | ||||
| @@ -84,7 +84,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             } | ||||
|  | ||||
|             var message = DmtpMessage.CreateFrom(e.ByteBlock); | ||||
|             if (!client.InputReceivedData(message)) | ||||
|             if (!await client.InputReceivedData(message)) | ||||
|             { | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|   | ||||
| @@ -45,16 +45,17 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         { | ||||
|             this.Id = endPoint.ToString(); | ||||
|             this.OutputSend = this.RpcActorSend; | ||||
|             this.OnCreateChannel = this.OnDmtpActorCreateChannel; | ||||
|             this.OutputSendAsync = this.RpcActorSendAsync; | ||||
|             this.CreatedChannel = this.OnDmtpActorCreatedChannel; | ||||
|             this.m_udpSession = udpSession; | ||||
|             this.m_endPoint = endPoint; | ||||
|             this.Logger = logger; | ||||
|             this.Client = this; | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             this.pluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|             return this.pluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         } | ||||
|  | ||||
|         public bool Created(IPluginsManager pluginsManager) | ||||
| @@ -117,5 +118,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         { | ||||
|             this.m_udpSession.Send(this.m_endPoint, transferBytes); | ||||
|         } | ||||
|  | ||||
|         private Task RpcActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             return this.m_udpSession.SendAsync(this.m_endPoint, transferBytes); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -50,15 +50,16 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|         #region 字段 | ||||
|  | ||||
|         private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|         private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1); | ||||
|         private readonly SemaphoreSlim m_semaphoreForSend = new SemaphoreSlim(1, 1); | ||||
|         private ClientWebSocket m_client; | ||||
|         private SealedDmtpActor m_dmtpActor; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private Func<string, Task<IDmtpActor>> m_findDmtpActor; | ||||
|         private int m_receiveBufferSize = 1024 * 10; | ||||
|         private ValueCounter m_receiveCounter; | ||||
|         private int m_sendBufferSize = 1024 * 10; | ||||
|         private ValueCounter m_sendCounter; | ||||
|         private TcpDmtpAdapter m_smtpAdapter; | ||||
|         private TcpDmtpAdapter m_dmtpAdapter; | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
| @@ -115,56 +116,15 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <returns></returns> | ||||
|         public void Close(string msg = "") | ||||
|         { | ||||
|             this.DmtpActor.Close(true, msg); | ||||
|             this.m_dmtpActor.SendClose(msg); | ||||
|             this.m_dmtpActor.Close(msg); | ||||
|             this.PrivateClose(msg); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public async Task ConnectAsync(int timeout = 5000) | ||||
|         public Task ConnectAsync(int timeout = 5000) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphore.WaitAsync(); | ||||
|                 if (this.IsHandshaked) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 if (this.m_client == null || this.m_client.State != WebSocketState.Open) | ||||
|                 { | ||||
|                     this.m_client.SafeDispose(); | ||||
|                     this.m_client = new ClientWebSocket(); | ||||
|                     await this.m_client.ConnectAsync(this.RemoteIPHost, default); | ||||
|  | ||||
|                     this.m_dmtpActor = new SealedDmtpActor(false) | ||||
|                     { | ||||
|                         OutputSend = this.OnDmtpActorSend, | ||||
|                         OnRouting = this.OnDmtpActorRouting, | ||||
|                         OnHandshaking = this.OnDmtpActorHandshaking, | ||||
|                         OnHandshaked = this.OnDmtpActorHandshaked, | ||||
|                         OnClose = this.OnDmtpActorClose, | ||||
|                         Logger = this.Logger, | ||||
|                         Client = this, | ||||
|                         OnFindDmtpActor = this.m_findDmtpActor, | ||||
|                         OnCreateChannel = this.OnDmtpActorCreateChannel | ||||
|                     }; | ||||
|  | ||||
|                     this.m_smtpAdapter = new TcpDmtpAdapter() | ||||
|                     { | ||||
|                         ReceivedCallBack = this.PrivateHandleReceivedData | ||||
|                     }; | ||||
|                     _ = this.BeginReceive(); | ||||
|                 } | ||||
|  | ||||
|                 this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
|                     this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), | ||||
|                     timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None); | ||||
|                 this.IsHandshaked = true; | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphore.Release(); | ||||
|             } | ||||
|             return this.ConnectAsync(CancellationToken.None, timeout); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
| @@ -172,7 +132,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphore.WaitAsync(); | ||||
|                 await this.m_semaphoreForConnect.WaitAsync(); | ||||
|                 if (this.IsHandshaked) | ||||
|                 { | ||||
|                     return; | ||||
| @@ -187,17 +147,18 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     this.m_dmtpActor = new SealedDmtpActor(false) | ||||
|                     { | ||||
|                         OutputSend = this.OnDmtpActorSend, | ||||
|                         OnRouting = this.OnDmtpActorRouting, | ||||
|                         OnHandshaking = this.OnDmtpActorHandshaking, | ||||
|                         OnHandshaked = this.OnDmtpActorHandshaked, | ||||
|                         OnClose = this.OnDmtpActorClose, | ||||
|                         OutputSendAsync = this.OnDmtpActorSendAsync, | ||||
|                         Routing = this.OnDmtpActorRouting, | ||||
|                         Handshaking = this.OnDmtpActorHandshaking, | ||||
|                         Handshaked = this.OnDmtpActorHandshaked, | ||||
|                         Closed = this.OnDmtpActorClose, | ||||
|                         Logger = this.Logger, | ||||
|                         Client = this, | ||||
|                         OnFindDmtpActor = this.m_findDmtpActor, | ||||
|                         OnCreateChannel = this.OnDmtpActorCreateChannel | ||||
|                     }; | ||||
|                         FindDmtpActor = this.m_findDmtpActor, | ||||
|                         CreatedChannel = this.OnDmtpActorCreateChannel | ||||
|                     }; ; | ||||
|  | ||||
|                     this.m_smtpAdapter = new TcpDmtpAdapter() | ||||
|                     this.m_dmtpAdapter = new TcpDmtpAdapter() | ||||
|                     { | ||||
|                         ReceivedCallBack = this.PrivateHandleReceivedData | ||||
|                     }; | ||||
| @@ -211,7 +172,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphore.Release(); | ||||
|                 this.m_semaphoreForConnect.Release(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -315,7 +276,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                         byteBlock.SetLength(result.Count); | ||||
|                         this.m_receiveCounter.Increment(result.Count); | ||||
|  | ||||
|                         this.m_smtpAdapter.ReceivedInput(byteBlock); | ||||
|                         this.m_dmtpAdapter.ReceivedInput(byteBlock); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -337,7 +298,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     this.m_client.CloseAsync(WebSocketCloseStatus.NormalClosure, msg, CancellationToken.None); | ||||
|                     this.m_client.SafeDispose(); | ||||
|                     this.DmtpActor.SafeDispose(); | ||||
|                     this.m_smtpAdapter.SafeDispose(); | ||||
|                     this.m_dmtpAdapter.SafeDispose(); | ||||
|                     this.OnDisconnected(new DisconnectEventArgs(manual, msg)); | ||||
|                 } | ||||
|             } | ||||
| @@ -403,7 +364,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         { | ||||
|             var message = (DmtpMessage)requestInfo; | ||||
|             if (!this.m_dmtpActor.InputReceivedData(message)) | ||||
|             if (!this.m_dmtpActor.InputReceivedData(message).GetFalseAwaitResult()) | ||||
|             { | ||||
|                 this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|             } | ||||
| @@ -411,56 +372,37 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string arg2) | ||||
|         private Task OnDmtpActorClose(DmtpActor actor, string arg2) | ||||
|         { | ||||
|             this.PrivateClose(arg2); | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e) | ||||
|         { | ||||
|             this.OnCreateChannel(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             return this.OnCreateChannel(e); | ||||
|         } | ||||
|  | ||||
|             this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             return this.OnHandshaked(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaked(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             return this.OnHandshaking(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e) | ||||
|         private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             this.OnHandshaking(e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             this.OnRouting(e); | ||||
|             return this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 this.m_semaphoreForSend.Wait(); | ||||
|                 for (var i = 0; i < transferBytes.Length; i++) | ||||
|                 { | ||||
|                     Task task; | ||||
| @@ -476,6 +418,36 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                     this.m_sendCounter.Increment(transferBytes[i].Count); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphoreForSend.Release(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task OnDmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphoreForSend.WaitAsync(); | ||||
|                 for (var i = 0; i < transferBytes.Length; i++) | ||||
|                 { | ||||
|                     if (i == transferBytes.Length - 1) | ||||
|                     { | ||||
|                         await this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, true, CancellationToken.None); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         await this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, false, CancellationToken.None); | ||||
|                     } | ||||
|                     this.m_sendCounter.Increment(transferBytes[i].Count); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphoreForSend.Release(); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
|  | ||||
| @@ -485,32 +457,53 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// 当创建通道 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnCreateChannel(CreateChannelEventArgs e) | ||||
|         protected virtual async Task OnCreateChannel(CreateChannelEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在完成握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将握手连接时 | ||||
|         /// </summary> | ||||
|         /// <param name="e">参数</param> | ||||
|         protected virtual void OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当需要转发路由包时 | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnRouting(PackageRouterEventArgs e) | ||||
|         protected virtual async Task OnRouting(PackageRouterEventArgs e) | ||||
|         { | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e); | ||||
|         } | ||||
|  | ||||
|         #endregion 事件触发 | ||||
|   | ||||
| @@ -10,6 +10,9 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Dmtp | ||||
| { | ||||
|     /// <summary> | ||||
|   | ||||
| @@ -22,10 +22,10 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|         /// <summary> | ||||
|         /// 创建一个<see cref="DmtpFileTransferActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         public DmtpFileTransferActor(IDmtpActor smtpActor) | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         public DmtpFileTransferActor(IDmtpActor dmtpActor) | ||||
|         { | ||||
|             this.DmtpActor = smtpActor; | ||||
|             this.DmtpActor = dmtpActor; | ||||
|         } | ||||
|  | ||||
|         #region 委托 | ||||
| @@ -61,12 +61,8 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 处理收到的消息 | ||||
|         /// </summary> | ||||
|         /// <param name="message"></param> | ||||
|         /// <returns></returns> | ||||
|         public bool InputReceivedData(DmtpMessage message) | ||||
|         /// <inheritdoc/> | ||||
|         public async Task<bool> InputReceivedData(DmtpMessage message) | ||||
|         { | ||||
|             var byteBlock = message.BodyByteBlock; | ||||
|             if (message.ProtocolFlags == this.m_pullFileResourceInfo_Request) | ||||
| @@ -77,11 +73,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileResource.UnpackageRouter(byteBlock); | ||||
|                     if (waitFileResource.Route && this.DmtpActor.AllowRoute) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource)) | ||||
|                         if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource))) | ||||
|                         { | ||||
|                             if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor)) | ||||
|                             if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor) | ||||
|                             { | ||||
|                                 actor.Send(this.m_pullFileResourceInfo_Request, byteBlock); | ||||
|                                 await actor.SendAsync(this.m_pullFileResourceInfo_Request, byteBlock); | ||||
|                                 return true; | ||||
|                             } | ||||
|                             else | ||||
| @@ -96,12 +92,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                         waitFileResource.SwitchId(); | ||||
|                         byteBlock.Reset(); | ||||
|                         waitFileResource.Package(byteBlock); | ||||
|                         this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                         await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         waitFileResource.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource); | ||||
|                         _ = this.RequestPullFileResourceInfo(waitFileResource); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -118,9 +114,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileResource.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileResource.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -143,9 +139,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileSection.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileSection.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pullFileSection_Request, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pullFileSection_Request, byteBlock); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
| @@ -153,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                             waitFileSection.SwitchId(); | ||||
|                             byteBlock.Reset(); | ||||
|                             waitFileSection.Package(byteBlock); | ||||
|                             this.DmtpActor.Send(this.m_pullFileSection_Response, byteBlock); | ||||
|                             await this.DmtpActor.SendAsync(this.m_pullFileSection_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -177,9 +173,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileSection.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileSection.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pullFileSection_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pullFileSection_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -202,11 +198,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileResource.UnpackageRouter(byteBlock); | ||||
|                     if (waitFileResource.Route && this.DmtpActor.AllowRoute) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource)) | ||||
|                         if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource))) | ||||
|                         { | ||||
|                             if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor)) | ||||
|                             if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor) | ||||
|                             { | ||||
|                                 actor.Send(this.m_pushFileResourceInfo_Request, byteBlock); | ||||
|                                 await actor.SendAsync(this.m_pushFileResourceInfo_Request, byteBlock); | ||||
|                                 return true; | ||||
|                             } | ||||
|                             else | ||||
| @@ -221,12 +217,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                         byteBlock.Reset(); | ||||
|                         waitFileResource.SwitchId(); | ||||
|                         waitFileResource.Package(byteBlock); | ||||
|                         this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                         await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         waitFileResource.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.RequestPushFileResourceInfo, waitFileResource); | ||||
|                         _ = this.RequestPushFileResourceInfo(waitFileResource); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -243,9 +239,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileResource.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileResource.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -268,9 +264,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileSection.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileSection.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pushFileSection_Request, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pushFileSection_Request, byteBlock); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
| @@ -278,7 +274,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                             waitFileSection.SwitchId(); | ||||
|                             byteBlock.Reset(); | ||||
|                             waitFileSection.Package(byteBlock); | ||||
|                             this.DmtpActor.Send(this.m_pushFileSection_Response, byteBlock); | ||||
|                             await this.DmtpActor.SendAsync(this.m_pushFileSection_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -303,9 +299,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileSection.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFileSection.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pushFileSection_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pushFileSection_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -328,9 +324,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFinishedPackage.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_finishedFileResourceInfo_Request, byteBlock); | ||||
|                             await actor.SendAsync(this.m_finishedFileResourceInfo_Request, byteBlock); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
| @@ -338,13 +334,13 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                             waitFinishedPackage.SwitchId(); | ||||
|                             byteBlock.Reset(); | ||||
|                             waitFinishedPackage.Package(byteBlock); | ||||
|                             this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                             await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         waitFinishedPackage.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.RequestFinishedFileResourceInfo, waitFinishedPackage); | ||||
|                         _ = this.RequestFinishedFileResourceInfo(waitFinishedPackage); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -361,9 +357,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFinishedPackage.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -386,11 +382,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitSmallFilePackage.UnpackageRouter(byteBlock); | ||||
|                     if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage)) | ||||
|                         if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage))) | ||||
|                         { | ||||
|                             if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor)) | ||||
|                             if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor) | ||||
|                             { | ||||
|                                 actor.Send(this.m_pullSmallFile_Request, byteBlock); | ||||
|                                 await actor.SendAsync(this.m_pullSmallFile_Request, byteBlock); | ||||
|                                 return true; | ||||
|                             } | ||||
|                             else | ||||
| @@ -405,12 +401,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                         byteBlock.Reset(); | ||||
|                         waitSmallFilePackage.SwitchId(); | ||||
|                         waitSmallFilePackage.Package(byteBlock); | ||||
|                         this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock); | ||||
|                         await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         waitSmallFilePackage.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage); | ||||
|                         _ = this.RequestPullSmallFile(waitSmallFilePackage); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -427,9 +423,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitSmallFilePackage.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pullSmallFile_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pullSmallFile_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -452,11 +448,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitSmallFilePackage.UnpackageRouter(byteBlock); | ||||
|                     if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage)) | ||||
|                         if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage))) | ||||
|                         { | ||||
|                             if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor)) | ||||
|                             if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor) | ||||
|                             { | ||||
|                                 actor.Send(this.m_pushSmallFile_Request, byteBlock); | ||||
|                                 await actor.SendAsync(this.m_pushSmallFile_Request, byteBlock); | ||||
|                                 return true; | ||||
|                             } | ||||
|                             else | ||||
| @@ -472,12 +468,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                         byteBlock.Reset(); | ||||
|                         waitSmallFilePackage.SwitchId(); | ||||
|                         waitSmallFilePackage.Package(byteBlock); | ||||
|                         this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock); | ||||
|                         await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         waitSmallFilePackage.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.RequestPushSmallFile, waitSmallFilePackage); | ||||
|                         _ = this.RequestPushSmallFile(waitSmallFilePackage); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -495,9 +491,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|  | ||||
|                     if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_pushSmallFile_Response, byteBlock); | ||||
|                             await actor.SendAsync(this.m_pushSmallFile_Response, byteBlock); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
| @@ -568,24 +564,20 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|             return this.FileController.GetFullPath(this.m_rootPath, path); | ||||
|         } | ||||
|  | ||||
|         private bool TryFindDmtpFileTransferActor(string targetId, out DmtpFileTransferActor rpcActor) | ||||
|         private async Task<DmtpFileTransferActor> TryFindDmtpFileTransferActor(string targetId) | ||||
|         { | ||||
|             if (targetId == this.DmtpActor.Id) | ||||
|             { | ||||
|                 rpcActor = this; | ||||
|                 return true; | ||||
|                 return this; | ||||
|             } | ||||
|             if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor)) | ||||
|             if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor) | ||||
|             { | ||||
|                 if (smtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor) | ||||
|                 if (dmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor) | ||||
|                 { | ||||
|                     rpcActor = newActor; | ||||
|                     return true; | ||||
|                     return newActor; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             rpcActor = default; | ||||
|             return false; | ||||
|             return default; | ||||
|         } | ||||
|  | ||||
|         #region Id传输 | ||||
| @@ -598,9 +590,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 return this.PrivateFinishedFileResourceInfo(targetId, fileResourceInfo, code, metadata, timeout, token); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token); | ||||
|                 return actor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -625,9 +617,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 return this.PrivatePullFileResourceInfo(targetId, path, metadata, fileSectionSize, timeout, token); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token); | ||||
|                 return actor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -652,9 +644,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 return this.PrivatePullFileSection(targetId, fileSection, timeout, token); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.PullFileSection(fileSection, timeout, token); | ||||
|                 return actor.PullFileSection(fileSection, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -679,9 +671,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 return this.PrivatePushFileResourceInfo(targetId, savePath, fileResourceLocator, metadata, timeout, token); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token); | ||||
|                 return actor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -715,9 +707,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 return this.PrivatePushFileSection(targetId, fileResourceLocator, fileSection, timeout, token); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.PushFileSection(fileResourceLocator, fileSection, timeout, token); | ||||
|                 return actor.PushFileSection(fileResourceLocator, fileSection, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -1261,7 +1253,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 { | ||||
|                     waitFinishedPackage.SwitchId(); | ||||
|                     waitFinishedPackage.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock); | ||||
|                 } | ||||
|  | ||||
|                 var args = new FileTransferedEventArgs(transferType, waitFinishedPackage?.Metadata, resourceInfo?.FileInfo, waitFinishedPackage.Code == ResultCode.Canceled ? Result.Canceled : resultThis) | ||||
| @@ -1332,7 +1324,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 { | ||||
|                     waitFileResource.SwitchId(); | ||||
|                     waitFileResource.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock); | ||||
|                 } | ||||
|             } | ||||
|             catch | ||||
| @@ -1454,7 +1446,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 { | ||||
|                     waitFileResource.SwitchId(); | ||||
|                     waitFileResource.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock); | ||||
|                 } | ||||
|             } | ||||
|             catch | ||||
| @@ -1528,7 +1520,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|         /// <inheritdoc/> | ||||
|         public PullSmallFileResult PullSmallFile(string targetId, string path, Metadata metadata = null, int timeout = 5000, CancellationToken token = default) | ||||
|         { | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var actor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return actor.PullSmallFile(path, metadata, timeout, token); | ||||
|             } | ||||
| @@ -1565,9 +1557,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|         /// <inheritdoc/> | ||||
|         public Result PushSmallFile(string targetId, string savePath, FileInfo fileInfo, Metadata metadata = null, int timeout = 5000, CancellationToken token = default) | ||||
|         { | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor) | ||||
|             { | ||||
|                 return rpcActor.PushSmallFile(savePath, fileInfo, metadata, timeout, token); | ||||
|                 return actor.PushSmallFile(savePath, fileInfo, metadata, timeout, token); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -1827,7 +1819,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 { | ||||
|                     waitSmallFilePackage.SwitchId(); | ||||
|                     waitSmallFilePackage.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock); | ||||
|                 } | ||||
|  | ||||
|                 var resultArgs = new FileTransferedEventArgs( | ||||
| @@ -1891,7 +1883,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
|                 { | ||||
|                     waitSmallFilePackage.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock); | ||||
|                 } | ||||
|  | ||||
|                 var resultArgs = new FileTransferedEventArgs( | ||||
|   | ||||
| @@ -48,7 +48,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|         /// <inheritdoc/> | ||||
|         public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             var smtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor) | ||||
|             var dmtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor) | ||||
|             { | ||||
|                 FileController = this.m_fileResourceController, | ||||
|                 OnFileTransfering = this.OnFileTransfering, | ||||
| @@ -56,25 +56,25 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                 RootPath = this.RootPath, | ||||
|                 MaxSmallFileLength = this.MaxSmallFileLength | ||||
|             }; | ||||
|             smtpFileTransferActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetDmtpFileTransferActor(smtpFileTransferActor); | ||||
|             dmtpFileTransferActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetDmtpFileTransferActor(dmtpFileTransferActor); | ||||
|  | ||||
|             return e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         { | ||||
|             if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor smtpFileTransferActor) | ||||
|             if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor dmtpFileTransferActor) | ||||
|             { | ||||
|                 if (smtpFileTransferActor.InputReceivedData(e.DmtpMessage)) | ||||
|                 if (await dmtpFileTransferActor.InputReceivedData(e.DmtpMessage)) | ||||
|                 { | ||||
|                     e.Handled = true; | ||||
|                     return EasyTask.CompletedTask; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return e.InvokeNext(); | ||||
|             await e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpFileTransferActor.MaxSmallFileLength"/> | ||||
|   | ||||
| @@ -48,21 +48,21 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|         /// <summary> | ||||
|         /// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpFileTransferActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         /// <returns></returns> | ||||
|         public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor smtpActor) | ||||
|         public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor dmtpActor) | ||||
|         { | ||||
|             return smtpActor.GetValue(DmtpFileTransferActorProperty); | ||||
|             return dmtpActor.GetValue(DmtpFileTransferActorProperty); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 向<see cref="DmtpActor"/>中设置<see cref="DmtpFileTransferActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         /// <param name="smtpRpcActor"></param> | ||||
|         internal static void SetDmtpFileTransferActor(this IDmtpActor smtpActor, DmtpFileTransferActor smtpRpcActor) | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         /// <param name="dmtpRpcActor"></param> | ||||
|         internal static void SetDmtpFileTransferActor(this IDmtpActor dmtpActor, DmtpFileTransferActor dmtpRpcActor) | ||||
|         { | ||||
|             smtpActor.SetValue(DmtpFileTransferActorProperty, smtpRpcActor); | ||||
|             dmtpActor.SetValue(DmtpFileTransferActorProperty, dmtpRpcActor); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -22,10 +22,10 @@ namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
|         /// <summary> | ||||
|         /// DmtpRedisActor | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         public DmtpRedisActor(IDmtpActor smtpActor) | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         public DmtpRedisActor(IDmtpActor dmtpActor) | ||||
|         { | ||||
|             this.DmtpActor = smtpActor; | ||||
|             this.DmtpActor = dmtpActor; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
| @@ -241,7 +241,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
|         /// </summary> | ||||
|         /// <param name="message"></param> | ||||
|         /// <returns></returns> | ||||
|         public bool InputReceivedData(DmtpMessage message) | ||||
|         public async Task<bool> InputReceivedData(DmtpMessage message) | ||||
|         { | ||||
|             if (message.ProtocolFlags == this.m_redis_Request) | ||||
|             { | ||||
| @@ -311,7 +311,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
|                 { | ||||
|                     waitResult.Package(byteBlock); | ||||
|                     this.DmtpActor.Send(this.m_redis_Response, byteBlock); | ||||
|                     await this.DmtpActor.SendAsync(this.m_redis_Response, byteBlock); | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|   | ||||
| @@ -22,6 +22,8 @@ | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
|  | ||||
| using ThingsGateway.Foundation.Resources; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
| @@ -52,16 +54,16 @@ namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
|         /// <summary> | ||||
|         /// 从<see cref="DmtpActor"/>中获得<see cref="IDmtpRedisActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         /// <returns></returns> | ||||
|         public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor smtpActor) | ||||
|         public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor dmtpActor) | ||||
|         { | ||||
|             return smtpActor.GetValue(DmtpRedisActorProperty); | ||||
|             return dmtpActor.GetValue(DmtpRedisActorProperty); | ||||
|         } | ||||
|  | ||||
|         internal static void SetStmpRedisActor(this IDmtpActor smtpActor, DmtpRedisActor redisClient) | ||||
|         internal static void SetStmpRedisActor(this IDmtpActor dmtpActor, DmtpRedisActor redisClient) | ||||
|         { | ||||
|             smtpActor.SetValue(DmtpRedisActorProperty, redisClient); | ||||
|             dmtpActor.SetValue(DmtpRedisActorProperty, redisClient); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -58,30 +58,30 @@ namespace ThingsGateway.Foundation.Dmtp.Redis | ||||
|         /// <inheritdoc/> | ||||
|         public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             var smtpRedisActor = new DmtpRedisActor(client.DmtpActor) | ||||
|             var dmtpRedisActor = new DmtpRedisActor(client.DmtpActor) | ||||
|             { | ||||
|                 ICache = this.ICache, | ||||
|                 Converter = this.Converter | ||||
|             }; | ||||
|  | ||||
|             smtpRedisActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetStmpRedisActor(smtpRedisActor); | ||||
|             dmtpRedisActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetStmpRedisActor(dmtpRedisActor); | ||||
|  | ||||
|             return e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         { | ||||
|             if (client.DmtpActor.GetDmtpRedisActor() is DmtpRedisActor redisClient) | ||||
|             { | ||||
|                 if (redisClient.InputReceivedData(e.DmtpMessage)) | ||||
|                 if (await redisClient.InputReceivedData(e.DmtpMessage)) | ||||
|                 { | ||||
|                     e.Handled = true; | ||||
|                     return EasyTask.CompletedTask; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             return e.InvokeNext(); | ||||
|             await e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -36,10 +36,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         /// <summary> | ||||
|         /// 创建一个DmtpRpcActor | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         public DmtpRpcActor(IDmtpActor smtpActor) | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         public DmtpRpcActor(IDmtpActor dmtpActor) | ||||
|         { | ||||
|             this.DmtpActor = smtpActor; | ||||
|             this.DmtpActor = dmtpActor; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
| @@ -69,7 +69,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         /// </summary> | ||||
|         /// <param name="message"></param> | ||||
|         /// <returns></returns> | ||||
|         public bool InputReceivedData(DmtpMessage message) | ||||
|         public async Task<bool> InputReceivedData(DmtpMessage message) | ||||
|         { | ||||
|             var byteBlock = message.BodyByteBlock; | ||||
|  | ||||
| @@ -77,14 +77,13 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     //Console.WriteLine(byteBlock.Len); | ||||
|                     var rpcPackage = new DmtpRpcPackage(); | ||||
|                     rpcPackage.UnpackageRouter(byteBlock); | ||||
|                     if (rpcPackage.Route && this.DmtpActor.AllowRoute) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryRoute(RouteType.Rpc, rpcPackage)) | ||||
|                         if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.Rpc, rpcPackage)).ConfigureFalseAwait()) | ||||
|                         { | ||||
|                             if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor)) | ||||
|                             if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                             { | ||||
|                                 actor.Send(this.m_invoke_Request, byteBlock); | ||||
|                                 return true; | ||||
| @@ -108,8 +107,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     else | ||||
|                     { | ||||
|                         rpcPackage.UnpackageBody(byteBlock); | ||||
|                         Task.Factory.StartNew(this.InvokeThis, rpcPackage); | ||||
|                         //this.InvokeThis(rpcPackage); | ||||
|                         _ = Task.Factory.StartNew(this.InvokeThis, rpcPackage); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -126,7 +124,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     rpcPackage.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && rpcPackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_invoke_Response, byteBlock); | ||||
|                         } | ||||
| @@ -151,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     canceledPackage.UnpackageRouter(byteBlock); | ||||
|                     if (this.DmtpActor.AllowRoute && canceledPackage.Route) | ||||
|                     { | ||||
|                         if (this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId, out var actor)) | ||||
|                         if (await this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor) | ||||
|                         { | ||||
|                             actor.Send(this.m_cancelInvoke, byteBlock); | ||||
|                         } | ||||
| @@ -203,7 +201,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             try | ||||
|             { | ||||
|                 var rpcPackage = (DmtpRpcPackage)o; | ||||
|                 //Console.WriteLine(rpcPackage.MethodName); | ||||
|  | ||||
|                 var psData = rpcPackage.ParametersBytes; | ||||
|                 if (rpcPackage.Feedback == FeedbackType.WaitSend) | ||||
|                 { | ||||
| @@ -227,7 +225,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|                 var invokeResult = new InvokeResult(); | ||||
|                 object[] ps = null; | ||||
|                 var methodInstance = this.GetInvokeMethod?.Invoke(rpcPackage.MethodName); | ||||
|                 var methodInstance = this.GetInvokeMethod.Invoke(rpcPackage.MethodName); | ||||
|                 DmtpRpcCallContext callContext = null; | ||||
|                 if (methodInstance != null) | ||||
|                 { | ||||
| @@ -283,7 +281,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     { | ||||
|                         transientRpcServer.CallContext = callContext; | ||||
|                     } | ||||
|                     invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext); | ||||
|                     invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext).ConfigureFalseAwait(); | ||||
|                 } | ||||
|  | ||||
|                 if (rpcPackage.Feedback == FeedbackType.OnlySend) | ||||
| @@ -369,24 +367,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private bool TryFindDmtpRpcActor(string targetId, out DmtpRpcActor rpcActor) | ||||
|         private async Task<DmtpRpcActor> TryFindDmtpRpcActor(string targetId) | ||||
|         { | ||||
|             if (targetId == this.DmtpActor.Id) | ||||
|             { | ||||
|                 rpcActor = this; | ||||
|                 return true; | ||||
|                 return this; | ||||
|             } | ||||
|             if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor)) | ||||
|             if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor) | ||||
|             { | ||||
|                 if (smtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor) | ||||
|                 if (dmtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor) | ||||
|                 { | ||||
|                     rpcActor = newActor; | ||||
|                     return true; | ||||
|                     return newActor; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             rpcActor = default; | ||||
|             return false; | ||||
|             return default; | ||||
|         } | ||||
|  | ||||
|         #region Rpc | ||||
| @@ -504,8 +498,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -532,7 +524,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -689,8 +680,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -722,7 +711,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -779,8 +767,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetWaitDataAsync(rpcPackage); | ||||
|  | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -818,7 +804,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|                     case FeedbackType.WaitSend: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     break; | ||||
| @@ -832,7 +818,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitInvoke: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     { | ||||
| @@ -898,7 +884,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -907,7 +892,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitSend: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.Overtime: | ||||
|                                     { | ||||
| @@ -918,7 +903,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitInvoke: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     { | ||||
| @@ -961,7 +946,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 actor.Invoke(invokeKey, invokeOption, parameters); | ||||
|                 return; | ||||
| @@ -977,7 +962,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -1009,7 +993,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1069,9 +1052,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 return rpcActor.Invoke(returnType, invokeKey, invokeOption, parameters); | ||||
|                 return actor.Invoke(returnType, invokeKey, invokeOption, parameters); | ||||
|             } | ||||
|  | ||||
|             var rpcPackage = new DmtpRpcPackage | ||||
| @@ -1084,10 +1067,8 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|  | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
|                 { | ||||
|                     if (invokeOption == default) | ||||
| @@ -1116,7 +1097,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1175,9 +1155,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 rpcActor.Invoke(invokeKey, invokeOption, ref parameters, types); | ||||
|                 actor.Invoke(invokeKey, invokeOption, ref parameters, types); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
| @@ -1191,7 +1171,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -1219,7 +1198,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1289,9 +1267,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 return rpcActor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types); | ||||
|                 return actor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types); | ||||
|             } | ||||
|  | ||||
|             var rpcPackage = new DmtpRpcPackage | ||||
| @@ -1304,7 +1282,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage); | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -1330,7 +1307,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1400,9 +1376,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor)) | ||||
|             if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 await actor.InvokeAsync(invokeKey, invokeOption, parameters); | ||||
|                 await actor.InvokeAsync(invokeKey, invokeOption, parameters).ConfigureFalseAwait(); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
| @@ -1416,7 +1392,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|             var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitDataAsync(rpcPackage); | ||||
|  | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
| @@ -1448,7 +1423,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1456,7 +1430,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|                     case FeedbackType.WaitSend: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     break; | ||||
| @@ -1470,7 +1444,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitInvoke: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     { | ||||
| @@ -1508,9 +1482,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                 throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey)); | ||||
|             } | ||||
|  | ||||
|             if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor)) | ||||
|             if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor) | ||||
|             { | ||||
|                 return await rpcActor.InvokeAsync(returnType, invokeKey, invokeOption, parameters); | ||||
|                 return await actor.InvokeAsync(returnType, invokeKey, invokeOption, parameters).ConfigureFalseAwait(); | ||||
|             } | ||||
|  | ||||
|             var rpcPackage = new DmtpRpcPackage | ||||
| @@ -1553,8 +1527,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                     this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|  | ||||
|                 switch (invokeOption.FeedbackType) | ||||
|                 { | ||||
|                     case FeedbackType.OnlySend: | ||||
| @@ -1563,7 +1535,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitSend: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.Overtime: | ||||
|                                     { | ||||
| @@ -1574,7 +1546,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|                         } | ||||
|                     case FeedbackType.WaitInvoke: | ||||
|                         { | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout)) | ||||
|                             switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait()) | ||||
|                             { | ||||
|                                 case WaitDataStatus.SetRunning: | ||||
|                                     { | ||||
|   | ||||
| @@ -42,11 +42,11 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         /// <summary> | ||||
|         /// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpRpcActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         /// <returns></returns> | ||||
|         public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor smtpActor) | ||||
|         public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor dmtpActor) | ||||
|         { | ||||
|             return smtpActor.GetValue(DmtpRpcActorProperty); | ||||
|             return dmtpActor.GetValue(DmtpRpcActorProperty); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -57,12 +57,12 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         /// <exception cref="ArgumentNullException"></exception> | ||||
|         public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActorObject client) | ||||
|         { | ||||
|             var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor(); | ||||
|             if (smtpRpcActor is null) | ||||
|             var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor(); | ||||
|             if (dmtpRpcActor is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription()); | ||||
|                 throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription()); | ||||
|             } | ||||
|             return smtpRpcActor; | ||||
|             return dmtpRpcActor; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -73,22 +73,22 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         /// <exception cref="ArgumentNullException"></exception> | ||||
|         public static TDmtpRpcActor GetDmtpRpcActor<TDmtpRpcActor>(this IDmtpActorObject client) where TDmtpRpcActor : IDmtpRpcActor | ||||
|         { | ||||
|             var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor(); | ||||
|             if (smtpRpcActor is null) | ||||
|             var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor(); | ||||
|             if (dmtpRpcActor is null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription()); | ||||
|                 throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription()); | ||||
|             } | ||||
|             return (TDmtpRpcActor)smtpRpcActor; | ||||
|             return (TDmtpRpcActor)dmtpRpcActor; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 向<see cref="DmtpActor"/>中设置<see cref="IDmtpRpcActor"/> | ||||
|         /// </summary> | ||||
|         /// <param name="smtpActor"></param> | ||||
|         /// <param name="smtpRpcActor"></param> | ||||
|         internal static void SetDmtpRpcActor(this IDmtpActor smtpActor, IDmtpRpcActor smtpRpcActor) | ||||
|         /// <param name="dmtpActor"></param> | ||||
|         /// <param name="dmtpRpcActor"></param> | ||||
|         internal static void SetDmtpRpcActor(this IDmtpActor dmtpActor, IDmtpRpcActor dmtpRpcActor) | ||||
|         { | ||||
|             smtpActor.SetValue(DmtpRpcActorProperty, smtpRpcActor); | ||||
|             dmtpActor.SetValue(DmtpRpcActorProperty, dmtpRpcActor); | ||||
|         } | ||||
|  | ||||
|         #region 插件扩展 | ||||
|   | ||||
| @@ -94,9 +94,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             return this.ActionMap.GetMethodInstance(name); | ||||
|         } | ||||
|  | ||||
|         private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor smtpActor) | ||||
|         private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor dmtpActor) | ||||
|         { | ||||
|             return new DmtpRpcActor(smtpActor); | ||||
|             return new DmtpRpcActor(dmtpActor); | ||||
|         } | ||||
|  | ||||
|         #region Rpc配置 | ||||
| @@ -135,31 +135,30 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|             pluginsManager.Add<IDmtpActorObject, DmtpMessageEventArgs>(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this.OnDmtpReceived); | ||||
|         } | ||||
|  | ||||
|         private Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e) | ||||
|         private async Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e) | ||||
|         { | ||||
|             var smtpRpcActor = CreateDmtpRpcActor(client.DmtpActor); | ||||
|             smtpRpcActor.RpcStore = this.RpcStore; | ||||
|             smtpRpcActor.SerializationSelector = this.SerializationSelector; | ||||
|             smtpRpcActor.GetInvokeMethod = this.GetInvokeMethod; | ||||
|             var dmtpRpcActor = this.CreateDmtpRpcActor(client.DmtpActor); | ||||
|             dmtpRpcActor.RpcStore = this.RpcStore; | ||||
|             dmtpRpcActor.SerializationSelector = this.SerializationSelector; | ||||
|             dmtpRpcActor.GetInvokeMethod = this.GetInvokeMethod; | ||||
|  | ||||
|             smtpRpcActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetDmtpRpcActor(smtpRpcActor); | ||||
|             dmtpRpcActor.SetProtocolFlags(this.StartProtocol); | ||||
|             client.DmtpActor.SetDmtpRpcActor(dmtpRpcActor); | ||||
|  | ||||
|             return e.InvokeNext(); | ||||
|             await e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         private Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         private async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e) | ||||
|         { | ||||
|             if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor smtpRpcActor) | ||||
|             if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor dmtpRpcActor) | ||||
|             { | ||||
|                 if (smtpRpcActor.InputReceivedData(e.DmtpMessage)) | ||||
|                 if (await dmtpRpcActor.InputReceivedData(e.DmtpMessage).ConfigureFalseAwait()) | ||||
|                 { | ||||
|                     e.Handled = true; | ||||
|                     return EasyTask.CompletedTask; | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return e.InvokeNext(); | ||||
|             await e.InvokeNext(); | ||||
|         } | ||||
|  | ||||
|         #endregion Config | ||||
|   | ||||
| @@ -108,10 +108,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|  | ||||
|         internal void LoadInvokeOption(IInvokeOption option) | ||||
|         { | ||||
|             if (option is DmtpInvokeOption smtpInvokeOption) | ||||
|             if (option is DmtpInvokeOption dmtpInvokeOption) | ||||
|             { | ||||
|                 this.Feedback = smtpInvokeOption.FeedbackType; | ||||
|                 this.SerializationType = smtpInvokeOption.SerializationType; | ||||
|                 this.Feedback = dmtpInvokeOption.FeedbackType; | ||||
|                 this.SerializationType = dmtpInvokeOption.SerializationType; | ||||
|             } | ||||
|             else if (option is InvokeOption invokeOption) | ||||
|             { | ||||
|   | ||||
| @@ -27,6 +27,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// </summary> | ||||
|         /// <param name="message"></param> | ||||
|         /// <returns>当满足本协议时,应当返回<see langword="true"/>,其他时候应该返回<see langword="false"/>.</returns> | ||||
|         public bool InputReceivedData(DmtpMessage message); | ||||
|         public Task<bool> InputReceivedData(DmtpMessage message); | ||||
|     } | ||||
| } | ||||
| @@ -58,7 +58,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                         failedCount++; | ||||
|                         if (failedCount > this.MaxFailCount) | ||||
|                         { | ||||
|                             client.DmtpActor.Close(true, "自动心跳失败次数达到最大,已断开连接。"); | ||||
|                             client.DmtpActor.Close("自动心跳失败次数达到最大,已断开连接。"); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -18,8 +18,8 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|     public class DmtpRouteService : IDmtpRouteService | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 查找路由的委托 | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         public Func<string, IDmtpActor> FindDmtpActor { get; set; } | ||||
|         public Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -31,12 +31,26 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// </summary> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="func"></param> | ||||
|         public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> func) | ||||
|         public static void AddDmtpRouteService(this IContainer container, Func<string, Task<IDmtpActor>> func) | ||||
|         { | ||||
|             container.RegisterSingleton<IDmtpRouteService>(new DmtpRouteService() | ||||
|             { | ||||
|                 FindDmtpActor = func | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 添加基于设定委托的Dmtp路由服务。 | ||||
|         /// </summary> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="action"></param> | ||||
|         public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> action) | ||||
|         { | ||||
|             AddDmtpRouteService(container, async (id) => | ||||
|             { | ||||
|                 await EasyTask.CompletedTask; | ||||
|                 return action.Invoke(id); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -20,6 +20,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// <summary> | ||||
|         /// 查找其他IDmtpActor | ||||
|         /// </summary> | ||||
|         Func<string, IDmtpActor> FindDmtpActor { get; set; } | ||||
|         Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -72,7 +72,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             { | ||||
|                 return new WebSocketReceiveResult(this.ComplateRead, null); | ||||
|             } | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait(); | ||||
|             return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame); | ||||
|         } | ||||
| #if NET6_0_OR_GREATER | ||||
| @@ -82,7 +82,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             { | ||||
|                 return new WebSocketReceiveResult(this.ComplateRead, null); | ||||
|             } | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait(); | ||||
|             return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame); | ||||
|         } | ||||
| #endif | ||||
| @@ -146,7 +146,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|             if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10))) | ||||
|             if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10)).ConfigureFalseAwait()) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Diagnostics; | ||||
| using System.IO.Ports; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Serial; | ||||
| @@ -40,13 +39,12 @@ public class SerialCore : IDisposable, ISender | ||||
|     public readonly object SyncRoot = new object(); | ||||
|  | ||||
|     private long m_bufferRate; | ||||
|     private SpinLock m_lock; | ||||
|     private bool m_online => m_serialPort?.IsOpen == true; | ||||
|     private int m_receiveBufferSize = 1024 * 10; | ||||
|     private ValueCounter m_receiveCounter; | ||||
|     private int m_sendBufferSize = 1024 * 10; | ||||
|     private ValueCounter m_sendCounter; | ||||
|     private readonly EasyLock m_semaphore = new EasyLock(); | ||||
|     private readonly EasyLock m_semaphoreForSend = new EasyLock(); | ||||
|     private SerialPort m_serialPort; | ||||
|  | ||||
|     #endregion 字段 | ||||
| @@ -56,7 +54,6 @@ public class SerialCore : IDisposable, ISender | ||||
|     /// </summary> | ||||
|     public SerialCore() | ||||
|     { | ||||
|         this.m_lock = new SpinLock(Debugger.IsAttached); | ||||
|         this.m_receiveCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
| @@ -215,10 +212,20 @@ public class SerialCore : IDisposable, ISender | ||||
|         this.OnBreakOut = null; | ||||
|         this.UserToken = null; | ||||
|         this.m_bufferRate = 1; | ||||
|         this.m_lock = new SpinLock(); | ||||
|         this.m_receiveBufferSize = this.MinBufferSize; | ||||
|         this.m_sendBufferSize = this.MinBufferSize; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 判断,当不在连接状态时触发异常。 | ||||
|     /// </summary> | ||||
|     /// <exception cref="NotConnectedException"></exception> | ||||
|     protected void ThrowIfNotConnected() | ||||
|     { | ||||
|         if (!this.m_online) | ||||
|         { | ||||
|             throw new NotConnectedException(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 发送数据。 | ||||
| @@ -231,15 +238,15 @@ public class SerialCore : IDisposable, ISender | ||||
|     /// <param name="length"></param> | ||||
|     public virtual void Send(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         var lockTaken = false; | ||||
|         this.ThrowIfNotConnected(); | ||||
|         try | ||||
|         { | ||||
|             this.m_lock.Enter(ref lockTaken); | ||||
|             this.m_semaphoreForSend.Wait(); | ||||
|             this.m_serialPort.Write(buffer, offset, length); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             if (lockTaken) this.m_lock.Exit(false); | ||||
|             this.m_semaphoreForSend.Release(); | ||||
|         } | ||||
|         this.m_sendCounter.Increment(length); | ||||
|     } | ||||
| @@ -254,15 +261,16 @@ public class SerialCore : IDisposable, ISender | ||||
|     /// <exception cref="Exception"></exception> | ||||
|     public virtual async Task SendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         this.ThrowIfNotConnected(); | ||||
|         try | ||||
|         { | ||||
|             await this.m_semaphore.WaitAsync(); | ||||
|             await this.m_semaphoreForSend.WaitAsync(); | ||||
|  | ||||
|             this.m_serialPort.Write(buffer, offset, length); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             this.m_semaphore.Release(); | ||||
|             this.m_semaphoreForSend.Release(); | ||||
|         } | ||||
|  | ||||
|         this.m_sendCounter.Increment(length); | ||||
|   | ||||
| @@ -255,7 +255,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|             { | ||||
|                 Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg)); | ||||
|                 this.MainSerialPort.TryClose(); | ||||
|                 this.BreakOut(default, true, msg); | ||||
|                 this.BreakOut(true, msg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -272,7 +272,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|             if (this.m_online) | ||||
|             { | ||||
|                 Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                 this.BreakOut(default, true, $"{nameof(Dispose)}主动断开"); | ||||
|                 this.BreakOut(true, $"{nameof(Dispose)}主动断开"); | ||||
|             } | ||||
|         } | ||||
|         base.Dispose(disposing); | ||||
| @@ -361,7 +361,16 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     private void BreakOut(SerialCore core, bool manual, string msg) | ||||
|     private void SerialCoreBreakOut(SerialCore core, bool manual, string msg) | ||||
|     { | ||||
|         this.BreakOut(manual, msg); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// BreakOut。 | ||||
|     /// </summary> | ||||
|     /// <param name="manual"></param> | ||||
|     /// <param name="msg"></param> | ||||
|     protected void BreakOut(bool manual, string msg) | ||||
|     { | ||||
|         lock (this.SyncRoot) | ||||
|         { | ||||
| @@ -759,7 +768,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         } | ||||
|         this.m_serialCore.Reset(serialPort); | ||||
|         this.m_serialCore.OnReceived = this.HandleReceived; | ||||
|         this.m_serialCore.OnBreakOut = this.BreakOut; | ||||
|         this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut; | ||||
|         if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue) | ||||
|         { | ||||
|             this.m_serialCore.MinBufferSize = minValue; | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Diagnostics; | ||||
| using System.Net.Security; | ||||
| using System.Net.Sockets; | ||||
|  | ||||
| @@ -41,14 +40,13 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|     public readonly object SyncRoot = new object(); | ||||
|  | ||||
|     private long m_bufferRate; | ||||
|     private SpinLock m_lock; | ||||
|     private volatile bool m_online; | ||||
|     private int m_receiveBufferSize = 1024 * 10; | ||||
|     private ValueCounter m_receiveCounter; | ||||
|     private int m_sendBufferSize = 1024 * 10; | ||||
|     private ValueCounter m_sendCounter; | ||||
|     private Socket m_socket; | ||||
|     private readonly EasyLock m_semaphore = new(); | ||||
|     private readonly EasyLock m_semaphoreForSend = new(); | ||||
|     #endregion 字段 | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -56,7 +54,6 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|     /// </summary> | ||||
|     public TcpCore() | ||||
|     { | ||||
|         this.m_lock = new SpinLock(Debugger.IsAttached); | ||||
|         this.m_receiveCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
| @@ -295,12 +292,21 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|         this.OnBreakOut = null; | ||||
|         this.UserToken = null; | ||||
|         this.m_bufferRate = 1; | ||||
|         this.m_lock = new SpinLock(); | ||||
|         this.m_receiveBufferSize = this.MinBufferSize; | ||||
|         this.m_sendBufferSize = this.MinBufferSize; | ||||
|         this.m_online = false; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 判断,当不在连接状态时触发异常。 | ||||
|     /// </summary> | ||||
|     /// <exception cref="NotConnectedException"></exception> | ||||
|     protected void ThrowIfNotConnected() | ||||
|     { | ||||
|         if (!this.m_online) | ||||
|         { | ||||
|             throw new NotConnectedException(); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 发送数据。 | ||||
|     /// <para> | ||||
| @@ -312,16 +318,16 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|     /// <param name="length"></param> | ||||
|     public virtual void Send(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         this.ThrowIfNotConnected(); | ||||
|         if (this.UseSsl) | ||||
|         { | ||||
|             this.SslStream.Write(buffer, offset, length); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             var lockTaken = false; | ||||
|             try | ||||
|             { | ||||
|                 this.m_lock.Enter(ref lockTaken); | ||||
|                 this.m_semaphoreForSend.Wait(); | ||||
|                 while (length > 0) | ||||
|                 { | ||||
|                     var r = this.m_socket.Send(buffer, offset, length, SocketFlags.None); | ||||
| @@ -335,7 +341,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 if (lockTaken) this.m_lock.Exit(false); | ||||
|                 this.m_semaphoreForSend.Release(); | ||||
|             } | ||||
|         } | ||||
|         this.m_sendCounter.Increment(length); | ||||
| @@ -354,6 +360,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|     /// <exception cref="Exception"></exception> | ||||
|     public virtual async Task SendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         this.ThrowIfNotConnected(); | ||||
| #if NET6_0_OR_GREATER | ||||
|         if (this.UseSsl) | ||||
|         { | ||||
| @@ -363,7 +370,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphore.WaitAsync(); | ||||
|                 await this.m_semaphoreForSend.WaitAsync(); | ||||
|  | ||||
|                 while (length > 0) | ||||
|                 { | ||||
| @@ -378,7 +385,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphore.Release(); | ||||
|                 this.m_semaphoreForSend.Release(); | ||||
|             } | ||||
|         } | ||||
| #else | ||||
| @@ -390,7 +397,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphore.WaitAsync(); | ||||
|                 await this.m_semaphoreForSend.WaitAsync(); | ||||
|  | ||||
|                 while (length > 0) | ||||
|                 { | ||||
| @@ -405,7 +412,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_semaphore.Release(); | ||||
|                 this.m_semaphoreForSend.Release(); | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|   | ||||
| @@ -149,7 +149,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 this.BreakOut(default, false, ex.ToString()); | ||||
|                 this.BreakOut(false, ex.ToString()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -226,7 +226,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             var tcpCore = this.Service.RentTcpCore(); | ||||
|             tcpCore.Reset(socket); | ||||
|             tcpCore.OnReceived = this.HandleReceived; | ||||
|             tcpCore.OnBreakOut = this.BreakOut; | ||||
|             tcpCore.OnBreakOut = this.TcpCoreBreakOut; | ||||
|             if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue) | ||||
|             { | ||||
|                 tcpCore.MinBufferSize = minValue; | ||||
| @@ -239,7 +239,17 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             this.m_tcpCore = tcpCore; | ||||
|         } | ||||
|  | ||||
|         private void BreakOut(TcpCore core, bool manual, string msg) | ||||
|         private void TcpCoreBreakOut(TcpCore core, bool manual, string msg) | ||||
|         { | ||||
|             this.BreakOut(manual, msg); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 中断连接 | ||||
|         /// </summary> | ||||
|         /// <param name="manual"></param> | ||||
|         /// <param name="msg"></param> | ||||
|         protected void BreakOut(bool manual, string msg) | ||||
|         { | ||||
|             if (this.GetSocketCliectCollection().TryRemove(this.Id, out _)) | ||||
|             { | ||||
| @@ -397,7 +407,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             { | ||||
|                 var tcp = this.m_tcpCore; | ||||
|                 this.m_tcpCore = null; | ||||
|                 this.Service?.ReturnTcpCore(tcp); | ||||
|                 this.Service.ReturnTcpCore(tcp); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -424,7 +434,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 { | ||||
|                     Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg)); | ||||
|                     this.MainSocket.TryClose(); | ||||
|                     this.BreakOut(default, true, msg); | ||||
|                     this.BreakOut(true, msg); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -505,7 +515,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 if (this.Online) | ||||
|                 { | ||||
|                     Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                     this.BreakOut(default, true, $"{nameof(Dispose)}主动断开"); | ||||
|                     this.BreakOut(true, $"{nameof(Dispose)}主动断开"); | ||||
|                 } | ||||
|  | ||||
|                 base.Dispose(disposing); | ||||
|   | ||||
| @@ -280,7 +280,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 { | ||||
|                     Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg)); | ||||
|                     this.MainSocket.TryClose(); | ||||
|                     this.BreakOut(default, true, msg); | ||||
|                     this.BreakOut(true, msg); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -297,7 +297,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 if (this.m_online) | ||||
|                 { | ||||
|                     Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                     this.BreakOut(default, true, $"{nameof(Dispose)}主动断开"); | ||||
|                     this.BreakOut(true, $"{nameof(Dispose)}主动断开"); | ||||
|                 } | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
| @@ -502,7 +502,17 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         { | ||||
|             return this.GetIPPort(); | ||||
|         } | ||||
|         private void BreakOut(TcpCore core, bool manual, string msg) | ||||
|  | ||||
|         private void TcpCoreBreakOut(TcpCore core, bool manual, string msg) | ||||
|         { | ||||
|             this.BreakOut(manual, msg); | ||||
|         } | ||||
|         /// <summary> | ||||
|         /// BreakOut。 | ||||
|         /// </summary> | ||||
|         /// <param name="manual"></param> | ||||
|         /// <param name="msg"></param> | ||||
|         protected void BreakOut(bool manual, string msg) | ||||
|         { | ||||
|             lock (this.SyncRoot) | ||||
|             { | ||||
| @@ -935,7 +945,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             } | ||||
|             this.m_tcpCore.Reset(socket); | ||||
|             this.m_tcpCore.OnReceived = this.HandleReceived; | ||||
|             this.m_tcpCore.OnBreakOut = this.BreakOut; | ||||
|             this.m_tcpCore.OnBreakOut = this.TcpCoreBreakOut; | ||||
|             if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue) | ||||
|             { | ||||
|                 this.m_tcpCore.MinBufferSize = minValue; | ||||
|   | ||||
| @@ -204,7 +204,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     public class UdpPackageAdapter : UdpDataHandlingAdapter | ||||
|     { | ||||
|         private readonly SnowflakeIdGenerator m_iDGenerator; | ||||
|         private readonly ConcurrentDictionary<long, UdpPackage> revStore; | ||||
|         private readonly ConcurrentDictionary<long, UdpPackage> m_revStore; | ||||
|         private int m_mtu = 1472; | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -212,7 +212,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         public UdpPackageAdapter() | ||||
|         { | ||||
|             this.revStore = new ConcurrentDictionary<long, UdpPackage>(); | ||||
|             this.m_revStore = new ConcurrentDictionary<long, UdpPackage>(); | ||||
|             this.m_iDGenerator = new SnowflakeIdGenerator(4); | ||||
|         } | ||||
|  | ||||
| @@ -250,17 +250,17 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             var udpFrame = new UdpFrame(); | ||||
|             if (udpFrame.Parse(byteBlock.Buffer, 0, byteBlock.Len)) | ||||
|             { | ||||
|                 var udpPackage = this.revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.revStore)); | ||||
|                 var udpPackage = this.m_revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.m_revStore)); | ||||
|                 udpPackage.Add(udpFrame); | ||||
|                 if (udpPackage.Length > this.MaxPackageSize) | ||||
|                 { | ||||
|                     this.revStore.TryRemove(udpPackage.Id, out _); | ||||
|                     this.m_revStore.TryRemove(udpPackage.Id, out _); | ||||
|                     this.Logger?.Error("数据长度大于设定的最大值。"); | ||||
|                     return; | ||||
|                 } | ||||
|                 if (udpPackage.IsComplated) | ||||
|                 { | ||||
|                     if (this.revStore.TryRemove(udpPackage.Id, out _)) | ||||
|                     if (this.m_revStore.TryRemove(udpPackage.Id, out _)) | ||||
|                     { | ||||
|                         using (var block = new ByteBlock(udpPackage.Length)) | ||||
|                         { | ||||
|   | ||||
| @@ -34,7 +34,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <summary> | ||||
|         /// 构造函数 | ||||
|         /// </summary> | ||||
|         public NotConnectedException() | ||||
|         public NotConnectedException() : this(TouchSocketResource.NotConnected.GetDescription()) | ||||
|         { } | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -42,7 +42,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         public async Task<ReceiverResult> ReadAsync(CancellationToken token) | ||||
|         { | ||||
|             this.ThrowIfDisposed(); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait(); | ||||
|             return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo); | ||||
|         } | ||||
|  | ||||
| @@ -51,7 +51,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         public async ValueTask<ReceiverResult> ValueReadAsync(CancellationToken token) | ||||
|         { | ||||
|             this.ThrowIfDisposed(); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait(); | ||||
|             return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo); | ||||
|         } | ||||
| #endif | ||||
|   | ||||
| @@ -28,7 +28,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     internal class WaitingClient<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, ISender | ||||
|     { | ||||
|         private readonly EasyLock m_semaphoreSlim = new(); | ||||
|         private volatile bool m_breaked; | ||||
|         private CancellationTokenSource m_cancellationTokenSource; | ||||
|  | ||||
|  | ||||
| @@ -75,8 +74,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 this.m_semaphoreSlim.Wait(); | ||||
|                 this.m_breaked = false; | ||||
|                 this.m_semaphoreSlim.Wait(token); | ||||
|                 if (token.CanBeCanceled) | ||||
|                 { | ||||
|                     this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token); | ||||
| @@ -85,7 +83,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 { | ||||
|                     this.m_cancellationTokenSource = new CancellationTokenSource(5000); | ||||
|                 } | ||||
|                 using (m_cancellationTokenSource) | ||||
|                 using (this.m_cancellationTokenSource) | ||||
|                 { | ||||
|                     if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session) | ||||
|                     { | ||||
| @@ -113,7 +111,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                                 { | ||||
|                                     if (receiverResult.IsClosed) | ||||
|                                     { | ||||
|                                         this.m_breaked = true; | ||||
|                                         this.Cancel(); | ||||
|                                     } | ||||
|                                     var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo); | ||||
| @@ -135,10 +132,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (OperationCanceledException) | ||||
|             { | ||||
|                 return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException(); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_cancellationTokenSource = null; | ||||
| @@ -156,8 +149,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 await this.m_semaphoreSlim.WaitAsync(); | ||||
|                 this.m_breaked = false; | ||||
|                 await this.m_semaphoreSlim.WaitAsync(token); | ||||
|                 if (token.CanBeCanceled) | ||||
|                 { | ||||
|                     this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token); | ||||
| @@ -166,7 +158,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 { | ||||
|                     this.m_cancellationTokenSource = new CancellationTokenSource(5000); | ||||
|                 } | ||||
|                 using (m_cancellationTokenSource) | ||||
|                 using (this.m_cancellationTokenSource) | ||||
|                 { | ||||
|                     if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session) | ||||
|                     { | ||||
| @@ -194,7 +186,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                                 { | ||||
|                                     if (receiverResult.IsClosed) | ||||
|                                     { | ||||
|                                         this.m_breaked = true; | ||||
|                                         this.Cancel(); | ||||
|                                     } | ||||
|                                     var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo); | ||||
| @@ -216,10 +207,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (OperationCanceledException) | ||||
|             { | ||||
|                 return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException(); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 this.m_cancellationTokenSource = null; | ||||
|   | ||||
| @@ -30,22 +30,11 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     /// </summary> | ||||
|     public class WaitingOptions | ||||
|     { | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当Client为Tcp系时。是否在断开连接时立即触发结果。默认会返回null。当<see cref="ThrowBreakException"/>为<see langword="true"/>时,会触发异常。 | ||||
|         /// </summary> | ||||
|         public bool BreakTrigger { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 远程地址(仅在Udp模式下生效) | ||||
|         /// </summary> | ||||
|         public IPHost RemoteIPHost { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当Client为Tcp系时。是否在断开连接时以异常返回结果。 | ||||
|         /// </summary> | ||||
|         public bool ThrowBreakException { get; set; } = true; | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 筛选函数 | ||||
|   | ||||
| @@ -75,7 +75,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger | ||||
|                     var bytes = new byte[stream.Length]; | ||||
|                     stream.Read(bytes, 0, bytes.Length); | ||||
|                     var prefix = this.Prefix.IsNullOrEmpty() ? "/" : (this.Prefix.StartsWith("/") ? this.Prefix : $"/{this.Prefix}"); | ||||
|                     var name = item.Replace("ThingsGateway.Foundation.WebApi.Swagger.api.", string.Empty); | ||||
|                     var name = item.Replace("ThingsGateway.Foundation.TouchSocket.WebApi.Swagger.api.", string.Empty); | ||||
|                     if (name == "openapi.json") | ||||
|                     { | ||||
|                         try | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.20</Version> | ||||
| 		<Version>3.0.0.24</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<ImplicitUsings>enable</ImplicitUsings> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
|   | ||||
| @@ -20,6 +20,7 @@ using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet; | ||||
| using MQTTnet.Client; | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
|  | ||||
| @@ -310,7 +311,9 @@ public class IotSharpClient : UpLoadBase | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Init(UploadDeviceRunTime device) | ||||
|     { | ||||
|         var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage)); | ||||
|         var log = new MqttNetEventLogger(); | ||||
|         log.LogMessagePublished += Log_LogMessagePublished; | ||||
|         var mqttFactory = new MqttFactory(log); | ||||
|         _mqttClientOptions = mqttFactory.CreateClientOptionsBuilder() | ||||
|            .WithClientId(Guid.NewGuid().ToString()) | ||||
|            .WithCredentials(driverPropertys.Accesstoken)//账密 | ||||
| @@ -355,6 +358,11 @@ public class IotSharpClient : UpLoadBase | ||||
|         exDeviceTimerTick = new(driverPropertys.UploadInterval); | ||||
|     } | ||||
|  | ||||
|     private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|  | ||||
|     private void DeviceStatusChange(CollectDeviceRunTime collectDeviceRunTime) | ||||
|     { | ||||
|         if (driverPropertys?.IsInterval != true) | ||||
|   | ||||
| @@ -18,6 +18,7 @@ using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet; | ||||
| using MQTTnet.Client; | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
| using System.Text; | ||||
| @@ -300,7 +301,9 @@ public class MqttClient : UpLoadBase | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Init(UploadDeviceRunTime device) | ||||
|     { | ||||
|         var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage)); | ||||
|         var log = new MqttNetEventLogger(); | ||||
|         log.LogMessagePublished += Log_LogMessagePublished; | ||||
|         var mqttFactory = new MqttFactory(log); | ||||
|         _mqttClientOptions = mqttFactory.CreateClientOptionsBuilder() | ||||
|            .WithClientId(driverPropertys.ConnectId) | ||||
|            .WithCredentials(driverPropertys.UserName, driverPropertys.Password)//账密 | ||||
| @@ -353,6 +356,11 @@ public class MqttClient : UpLoadBase | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|  | ||||
|     private async Task AllPublishAsync(CancellationToken cancellationToken) | ||||
|     { | ||||
|         //保留消息 | ||||
|   | ||||
| @@ -17,6 +17,7 @@ using Mapster; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet; | ||||
| using MQTTnet.Diagnostics; | ||||
| using MQTTnet.Internal; | ||||
| using MQTTnet.Protocol; | ||||
| using MQTTnet.Server; | ||||
| @@ -224,7 +225,9 @@ public class MqttServer : UpLoadBase | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Init(UploadDeviceRunTime device) | ||||
|     { | ||||
|         var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage)); | ||||
|         var log = new MqttNetEventLogger(); | ||||
|         log.LogMessagePublished += Log_LogMessagePublished; | ||||
|         var mqttFactory = new MqttFactory(log); | ||||
|         var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder() | ||||
|             .WithDefaultEndpointBoundIPAddress(string.IsNullOrEmpty(driverPropertys.IP) ? null : IPAddress.Parse(driverPropertys.IP)) | ||||
|             .WithDefaultEndpointPort(driverPropertys.Port) | ||||
| @@ -251,7 +254,11 @@ public class MqttServer : UpLoadBase | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         if (e.LogMessage.Exception is not ArgumentNullException) | ||||
|             LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|     private void DeviceStatusChange(CollectDeviceRunTime collectDeviceRunTime) | ||||
|     { | ||||
|         _collectDeviceRunTimes.Enqueue(collectDeviceRunTime.Adapt<DeviceData>()); | ||||
|   | ||||
| @@ -12,10 +12,11 @@ | ||||
|  | ||||
| using MQTTnet; | ||||
| using MQTTnet.Client; | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Plugin.Mqtt; | ||||
| using ThingsGateway.Gateway.Application; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Demo; | ||||
| /// <summary> | ||||
| @@ -56,14 +57,19 @@ public partial class MqttClientPage | ||||
|     /// <inheritdoc/> | ||||
|     protected override void OnInitialized() | ||||
|     { | ||||
|         MqttFactory = new MqttFactory(new PrivateLogger(new EasyLogger(LogAction) { LogLevel = LogLevel.Trace })); | ||||
|         var log = new MqttNetEventLogger(); | ||||
|         log.LogMessagePublished += Log_LogMessagePublished; | ||||
|         MqttFactory = new MqttFactory(log); | ||||
|  | ||||
|  | ||||
|         MqttClient = MqttFactory.CreateMqttClient(); | ||||
|         MqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync; | ||||
|         base.OnInitialized(); | ||||
|     } | ||||
|  | ||||
|     private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         new EasyLogger(LogAction) { LogLevel = LogLevel.Trace }.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|     private async Task Connect() | ||||
|     { | ||||
|         try | ||||
|   | ||||
| @@ -1,49 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| namespace ThingsGateway.Plugin.Mqtt | ||||
| { | ||||
|     internal class PrivateLogger : IMqttNetLogger | ||||
|     { | ||||
|         readonly ILog LogMessage; | ||||
|         public PrivateLogger(ILog logger) | ||||
|         { | ||||
|             LogMessage = logger; | ||||
|         } | ||||
|  | ||||
|         public bool IsEnabled => true; | ||||
|         public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) | ||||
|         { | ||||
|             switch (logLevel) | ||||
|             { | ||||
|                 case MqttNetLogLevel.Verbose: | ||||
|                     LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception); | ||||
|                     break; | ||||
|  | ||||
|                 case MqttNetLogLevel.Info: | ||||
|                     LogMessage?.Log(LogLevel.Info, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                     break; | ||||
|  | ||||
|                 case MqttNetLogLevel.Warning: | ||||
|                     LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                     break; | ||||
|  | ||||
|                 case MqttNetLogLevel.Error: | ||||
|                     LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Plugin.OPCUA; | ||||
|  | ||||
| /// <inheritdoc/> | ||||
|   | ||||
| @@ -67,6 +67,8 @@ public class SQLDB : UpLoadBase | ||||
|         await Task.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private bool readDBInitSuccess; | ||||
|  | ||||
|     public override async Task ExecuteAsync(CancellationToken cancellationToken) | ||||
|     { | ||||
|         var db = GetHisDbAsync(); | ||||
| @@ -75,14 +77,33 @@ public class SQLDB : UpLoadBase | ||||
|         { | ||||
|             if (exRealTimerTick.IsTickHappen()) | ||||
|             { | ||||
|  | ||||
|                 try | ||||
|                 { | ||||
|                     var varList = _uploadVariables.ToList().Adapt<List<SQLRealValue>>(); | ||||
|  | ||||
|                     if (!readDBInitSuccess) | ||||
|                     { | ||||
|                         //事务 | ||||
|                         var result = db.UseTran(() => | ||||
|                         { | ||||
|                             db.Storageable(varList).As(driverPropertys.ReadDBTableName).PageSize(10000).ExecuteSqlBulkCopy(); | ||||
|                             //db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkMerge(varList); | ||||
|                         }); | ||||
|                         if (result.IsSuccess)//如果成功了 | ||||
|                         { | ||||
|                             readDBInitSuccess = true; | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             throw new(result.ErrorMessage); | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     if (varList?.Count != 0) | ||||
|                     { | ||||
|                         //var result = await db.Storageable(varList).As(driverPropertys.ReadDBTableName).ExecuteCommandAsync(cancellationToken); | ||||
|                         await db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdateAsync(varList); | ||||
|  | ||||
|                         db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdate(varList); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
| @@ -180,6 +201,7 @@ public class SQLDB : UpLoadBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             readDBInitSuccess = false; | ||||
|             _globalDeviceData?.AllVariables?.ForEach(a => a.VariableValueChange -= VariableValueChange); | ||||
|             _uploadVariables = null; | ||||
|         } | ||||
|   | ||||
| @@ -43,9 +43,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -42,9 +42,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -42,9 +42,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -42,9 +42,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -42,9 +42,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -42,9 +42,13 @@ namespace ThingsGateway.Plugin.Siemens | ||||
|             { | ||||
|                 _plc.LocalTSAP = driverPropertys.LocalTSAP; | ||||
|             } | ||||
|             if (driverPropertys.DestTSAP != 0) | ||||
|             if (driverPropertys.Rack != 0) | ||||
|             { | ||||
|                 _plc.DestTSAP = driverPropertys.DestTSAP; | ||||
|                 _plc.Rack = driverPropertys.Rack; | ||||
|             } | ||||
|             if (driverPropertys.Slot != 0) | ||||
|             { | ||||
|                 _plc.Slot = driverPropertys.Slot; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -37,13 +37,19 @@ public class SiemensProperty : CollectDriverPropertyBase | ||||
|     /// </summary> | ||||
|     [DeviceProperty("默认解析顺序", "")] public DataFormat DataFormat { get; set; } | ||||
|     /// <summary> | ||||
|     /// DestTSAP | ||||
|     /// Rack | ||||
|     /// </summary> | ||||
|     [DeviceProperty("DestTSAP", "为0时不写入,通常默认0即可")] public int DestTSAP { get; set; } = 0; | ||||
|     [DeviceProperty("机架号", "为0时不写入")] public byte Rack { get; set; } = 0; | ||||
|     /// <summary> | ||||
|     /// Slot | ||||
|     /// </summary> | ||||
|     [DeviceProperty("槽位号", "为0时不写入")] public byte Slot { get; set; } = 0; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// LocalTSAP | ||||
|     /// </summary> | ||||
|     [DeviceProperty("LocalTSAP", "为0时不写入,通常默认0即可")] public int LocalTSAP { get; set; } = 0; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| using Furion; | ||||
|  | ||||
| using Mapster; | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Plugin.SQLDB; | ||||
|  | ||||
| public class TDengineDBProperty : UpDriverPropertyBase | ||||
|   | ||||
| @@ -99,8 +99,6 @@ Global | ||||
| 		{16C62A28-BACE-4391-91F8-C2D78D063A1E} = {79E7042F-F9E3-4D87-BFA9-4B7DD9736735} | ||||
| 		{8FA03089-322F-44CB-8E4B-F2637388E944} = {79E7042F-F9E3-4D87-BFA9-4B7DD9736735} | ||||
| 		{14FF7150-6DB7-455B-AD00-6AB4DE37855B} = {79E7042F-F9E3-4D87-BFA9-4B7DD9736735} | ||||
| 		{2861AA39-AAAE-47ED-9ACC-4C165DDF3EF1} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{9FF2A8A6-48D0-4D8A-9EAD-1905174291CC} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{51313113-7BB8-494E-9C24-6787BECE39BB} = {BB9C2A85-7A8A-4CF9-BF44-34DE9848EC15} | ||||
| 		{79E7042F-F9E3-4D87-BFA9-4B7DD9736735} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{BB9C2A85-7A8A-4CF9-BF44-34DE9848EC15} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
|   | ||||
| @@ -105,6 +105,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.Plugin.QuestD | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThingsGateway.Plugin.TDengineDB", "Plugin\ThingsGateway.Plugin.TDengineDB\ThingsGateway.Plugin.TDengineDB.csproj", "{2C827B2C-75DF-413B-9AB2-2D1B438AC082}" | ||||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Admin", "Admin", "{5854938A-F669-40F4-A54C-EC2651730B73}" | ||||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{C39748E6-34AC-4C4A-AEC7-7D807FFB4813}" | ||||
| EndProject | ||||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gateway", "Gateway", "{05A88744-64D9-4959-8A97-5189F327BBBE}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Any CPU = Debug|Any CPU | ||||
| @@ -254,18 +260,16 @@ Global | ||||
| 		{566783A4-222B-46F5-AA12-0753997B3254} = {0874CBC5-C583-4FAD-BA93-94571D446898} | ||||
| 		{BEFBC44A-E140-4E3E-AFBE-2DD8B98EB9BF} = {0874CBC5-C583-4FAD-BA93-94571D446898} | ||||
| 		{9695B353-D773-40DD-B65E-7B10EB0C16EC} = {0874CBC5-C583-4FAD-BA93-94571D446898} | ||||
| 		{799C49A4-8E23-475A-A82D-080854718BEE} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{616CA361-B667-42C8-B4DC-097C7CD39830} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{16C62A28-BACE-4391-91F8-C2D78D063A1E} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{8FA03089-322F-44CB-8E4B-F2637388E944} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{14FF7150-6DB7-455B-AD00-6AB4DE37855B} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{2861AA39-AAAE-47ED-9ACC-4C165DDF3EF1} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{9FF2A8A6-48D0-4D8A-9EAD-1905174291CC} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{51313113-7BB8-494E-9C24-6787BECE39BB} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{5D7BE567-2345-46C8-9F54-DDC1DA96D198} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{5CF1B3EC-84E2-484A-8DFC-2ECD2EE18E2F} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{CD0F211A-F65B-4026-9750-68AC3C70D012} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{5CD79F91-7182-4A9D-9BEF-4DF410C782D2} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{799C49A4-8E23-475A-A82D-080854718BEE} = {C39748E6-34AC-4C4A-AEC7-7D807FFB4813} | ||||
| 		{616CA361-B667-42C8-B4DC-097C7CD39830} = {5854938A-F669-40F4-A54C-EC2651730B73} | ||||
| 		{16C62A28-BACE-4391-91F8-C2D78D063A1E} = {5854938A-F669-40F4-A54C-EC2651730B73} | ||||
| 		{8FA03089-322F-44CB-8E4B-F2637388E944} = {5854938A-F669-40F4-A54C-EC2651730B73} | ||||
| 		{14FF7150-6DB7-455B-AD00-6AB4DE37855B} = {5854938A-F669-40F4-A54C-EC2651730B73} | ||||
| 		{51313113-7BB8-494E-9C24-6787BECE39BB} = {C39748E6-34AC-4C4A-AEC7-7D807FFB4813} | ||||
| 		{5D7BE567-2345-46C8-9F54-DDC1DA96D198} = {05A88744-64D9-4959-8A97-5189F327BBBE} | ||||
| 		{5CF1B3EC-84E2-484A-8DFC-2ECD2EE18E2F} = {05A88744-64D9-4959-8A97-5189F327BBBE} | ||||
| 		{CD0F211A-F65B-4026-9750-68AC3C70D012} = {05A88744-64D9-4959-8A97-5189F327BBBE} | ||||
| 		{5CD79F91-7182-4A9D-9BEF-4DF410C782D2} = {05A88744-64D9-4959-8A97-5189F327BBBE} | ||||
| 		{2057E5BE-FACA-4D44-A2BA-E1F864A8DAFF} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| 		{A723D4D7-B796-4D97-BA68-95E5696C9559} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| 		{D9944D52-81B4-4DBC-8C3B-2A334CCBD4F6} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| @@ -281,6 +285,9 @@ Global | ||||
| 		{7EBD5500-0DA0-415A-831D-5DC350917501} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| 		{A99787D7-A93B-4357-A8B5-B5F1FD2930AB} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| 		{2C827B2C-75DF-413B-9AB2-2D1B438AC082} = {CC8D0880-B73E-4DFC-9052-86504728708E} | ||||
| 		{5854938A-F669-40F4-A54C-EC2651730B73} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{C39748E6-34AC-4C4A-AEC7-7D807FFB4813} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 		{05A88744-64D9-4959-8A97-5189F327BBBE} = {9EB46BB6-D4EA-4B06-95EE-6C971E653030} | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||
| 		SolutionGuid = {C49B2D3E-6818-4E28-91B7-6E4E7E264BBB} | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.20</Version> | ||||
| 		<Version>3.0.0.24</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Authors>Diego</Authors> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.20</Version> | ||||
| 		<Version>3.0.0.24</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<ImplicitUsings>enable</ImplicitUsings> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| @@ -11,7 +11,6 @@ | ||||
| 		<SignAssembly>True</SignAssembly> | ||||
| 		<DelaySign>False</DelaySign> | ||||
| 		<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 	</PropertyGroup> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| 		<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.48" /> | ||||
| 		<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.48" /> | ||||
| 		<PackageReference Include="Furion.Pure" Version="4.8.8.48" /> | ||||
| 		<PackageReference Include="SqlSugarCore" Version="5.1.4.110" /> | ||||
| 		<PackageReference Include="SqlSugarCore" Version="5.1.4.112" /> | ||||
| 		<PackageReference Include="SqlSugar.TDengineCore" Version="2.9.0" /> | ||||
| 		<PackageReference Include="UAParser" Version="3.1.47" /> | ||||
| 		<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> | ||||
|   | ||||
| @@ -2,8 +2,9 @@ | ||||
|  | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Masa.Blazor" Version="1.1.0" /> | ||||
| 		<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.1.0" /> | ||||
| 		<PackageReference Include="Masa.Blazor" Version="1.1.1" /> | ||||
| 		<PackageReference Include="Masa.Blazor.SomethingSkia" Version="1.1.1" /> | ||||
| 		<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	 | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
|   | ||||
| @@ -23,6 +23,7 @@ public class DriverPluginSeedData : ISqlSugarEntitySeedData<DriverPlugin> | ||||
|         return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json") | ||||
|             .Concat(SeedDataUtil.GetSeedData<DriverPlugin>("pro_driver_plugin.json")) | ||||
|             .Concat(SeedDataUtil.GetSeedData<DriverPlugin>("custom_driver_plugin.json")) | ||||
|             .Concat(SeedDataUtil.GetSeedData<DriverPlugin>("other_driver_plugin.json")) | ||||
|             ; | ||||
|     } | ||||
| } | ||||
| @@ -63,6 +63,26 @@ public class PluginSingletonService : ISingleton | ||||
|     { | ||||
|         lock (this) | ||||
|         { | ||||
|             //添加默认上下文中继承类获取 | ||||
|             switch (plugin.DriverTypeEnum) | ||||
|             { | ||||
|                 case DriverEnum.Collect: | ||||
|                     var driverType = App.EffectiveTypes.Where(x => (typeof(CollectBase).IsAssignableFrom(x)) && x.IsClass && !x.IsAbstract).FirstOrDefault(it => it.Name == plugin.AssembleName); | ||||
|                     if (driverType != null) | ||||
|                     { | ||||
|                         return GetDriver(plugin, driverType); | ||||
|                     } | ||||
|                     break; | ||||
|                 case DriverEnum.Upload: | ||||
|                     var upLoadType = App.EffectiveTypes.Where(x => (typeof(UpLoadBase).IsAssignableFrom(x)) && x.IsClass && !x.IsAbstract).FirstOrDefault(it => it.Name == plugin.AssembleName); | ||||
|                     if (upLoadType != null) | ||||
|                     { | ||||
|                         return GetDriver(plugin, upLoadType); | ||||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|  | ||||
|  | ||||
|             //先判断是否已经拥有插件模块 | ||||
|             if (DriverPluginDict.ContainsKey(plugin.Id)) | ||||
|             { | ||||
|   | ||||
| @@ -20,6 +20,7 @@ using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet; | ||||
| using MQTTnet.Client; | ||||
| using MQTTnet.Diagnostics; | ||||
| using MQTTnet.Internal; | ||||
| using MQTTnet.Protocol; | ||||
| using MQTTnet.Server; | ||||
| @@ -392,7 +393,9 @@ public class ManageGatewayWorker : BackgroundService | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var mqttFactory = new MqttFactory(new MqttNetLogger(_manageLogger)); | ||||
|                 var log = new MqttNetEventLogger(); | ||||
|                 log.LogMessagePublished += ServerLog_LogMessagePublished; | ||||
|                 var mqttFactory = new MqttFactory(log); | ||||
|                 var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder() | ||||
|                     .WithDefaultEndpointBoundIPAddress(string.IsNullOrEmpty(ManageGatewayConfig.MqttBrokerIP) ? null : IPAddress.Parse(ManageGatewayConfig.MqttBrokerIP)) | ||||
|                     .WithDefaultEndpointPort(ManageGatewayConfig.MqttBrokerPort) | ||||
| @@ -426,7 +429,9 @@ public class ManageGatewayWorker : BackgroundService | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var mqttFactory = new MqttFactory(new MqttNetLogger(_clientLogger)); | ||||
|                 var log = new MqttNetEventLogger(); | ||||
|                 log.LogMessagePublished += Log_LogMessagePublished; | ||||
|                 var mqttFactory = new MqttFactory(log); | ||||
|                 _mqttClientOptions = mqttFactory.CreateClientOptionsBuilder() | ||||
|                   .WithCredentials(ClientGatewayConfig.UserName, ClientGatewayConfig.Password)//账密 | ||||
|                   .WithTcpServer(ClientGatewayConfig.MqttBrokerIP, ClientGatewayConfig.MqttBrokerPort)//服务器 | ||||
| @@ -468,6 +473,15 @@ public class ManageGatewayWorker : BackgroundService | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         if (e.LogMessage.Exception is not ArgumentNullException) | ||||
|             _clientLogger.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|     private void ServerLog_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e) | ||||
|     { | ||||
|         _manageLogger.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// ClientGatewayConfig | ||||
|   | ||||
| @@ -0,0 +1,65 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| namespace ThingsGateway.Gateway.Application; | ||||
|  | ||||
| public static class MqttLoggerExtensions | ||||
| { | ||||
|     public static void LogOut(this ILog LogMessage, MqttNetLogLevel logLevel, string source, string message, Exception exception) | ||||
|     { | ||||
|         switch (logLevel) | ||||
|         { | ||||
|             case MqttNetLogLevel.Verbose: | ||||
|                 LogMessage?.Log(Foundation.Core.LogLevel.Trace, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Info: | ||||
|                 LogMessage?.Log(Foundation.Core.LogLevel.Info, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Warning: | ||||
|                 LogMessage?.Log(Foundation.Core.LogLevel.Warning, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Error: | ||||
|                 LogMessage?.Log(Foundation.Core.LogLevel.Warning, source, message, exception); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void LogOut(this ILogger LogMessage, MqttNetLogLevel logLevel, string source, string message, Exception exception) | ||||
|     { | ||||
|         switch (logLevel) | ||||
|         { | ||||
|             case MqttNetLogLevel.Verbose: | ||||
|                 LogMessage?.Log(Microsoft.Extensions.Logging.LogLevel.Trace, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Info: | ||||
|                 LogMessage?.Log(Microsoft.Extensions.Logging.LogLevel.Information, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Warning: | ||||
|                 LogMessage?.Log(Microsoft.Extensions.Logging.LogLevel.Warning, source, message, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Error: | ||||
|                 LogMessage?.Log(Microsoft.Extensions.Logging.LogLevel.Warning, source, message, exception); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,51 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using MQTTnet.Diagnostics; | ||||
|  | ||||
| using LogLevel = Microsoft.Extensions.Logging.LogLevel; | ||||
|  | ||||
| namespace ThingsGateway.Gateway.Application; | ||||
|  | ||||
| internal class MqttNetLogger : IMqttNetLogger | ||||
| { | ||||
|     readonly ILogger LogMessage; | ||||
|     public MqttNetLogger(ILogger logger) | ||||
|     { | ||||
|         LogMessage = logger; | ||||
|     } | ||||
|  | ||||
|     public bool IsEnabled => true; | ||||
|     public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception) | ||||
|     { | ||||
|         switch (logLevel) | ||||
|         { | ||||
|             case MqttNetLogLevel.Verbose: | ||||
|                 LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Info: | ||||
|                 LogMessage?.Log(LogLevel.Information, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Warning: | ||||
|                 LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                 break; | ||||
|  | ||||
|             case MqttNetLogLevel.Error: | ||||
|                 LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -9,6 +9,7 @@ | ||||
|         //"DbType": "MySql", //数据库类型 | ||||
|         "ConnectionString": "Data Source=Admin.db;", //连接字符串 | ||||
|         "DbType": "Sqlite", //数据库类型 | ||||
|         "LanguageType": "Chinese",//中文提示 | ||||
|         "IsAutoCloseConnection": true, //是否自动释放 | ||||
|         "IsInitDb": true, //是否初始化数据库,适用于codefirst | ||||
|         "IsUnderLine": false, //是否驼峰转下划线 | ||||
| @@ -21,6 +22,7 @@ | ||||
|         //"DbType": "MySql", //数据库类型 | ||||
|         "ConnectionString": "Data Source=Log.db", //连接字符串 | ||||
|         "DbType": "Sqlite", //数据库类型 | ||||
|         "LanguageType": "Chinese", //中文提示 | ||||
|         "IsAutoCloseConnection": true, //是否自动释放 | ||||
|         "IsInitDb": true, //是否初始化数据库,适用于codefirst | ||||
|         "IsUnderLine": false, //是否驼峰转下划线 | ||||
| @@ -33,6 +35,7 @@ | ||||
|         //"DbType": "MySql", //数据库类型 | ||||
|         "ConnectionString": "Data Source=ThingsGateway.db", //连接字符串 | ||||
|         "DbType": "Sqlite", //数据库类型 | ||||
|         "LanguageType": "Chinese", //中文提示 | ||||
|         "IsAutoCloseConnection": true, //是否自动释放 | ||||
|         "IsInitDb": true, //是否初始化数据库,适用于codefirst | ||||
|         "IsUnderLine": false, //是否驼峰转下划线 | ||||
|   | ||||
| @@ -33,4 +33,11 @@ | ||||
| 		<ProjectReference Include="..\ThingsGateway.Gateway.ApiController\ThingsGateway.Gateway.ApiController.csproj" /> | ||||
| 		<ProjectReference Include="..\ThingsGateway.Gateway.Blazor\ThingsGateway.Gateway.Blazor.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
|  | ||||
| 	<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro - AF2021' OR '$(SolutionName)'=='ThingsGateway - Pro'"> | ||||
| 		<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.LK.Application\ThingsGateway.LK.Application.csproj" /> | ||||
| 	</ItemGroup> | ||||
| 	 | ||||
| </Project> | ||||
| @@ -53,6 +53,19 @@ public class Program | ||||
|         builder.Host.UseWindowsService(); | ||||
|         builder.Host.UseSystemd(); | ||||
|  | ||||
| #if AF2021 | ||||
|  | ||||
|         builder.WebHost.UseKestrel( | ||||
|     o => | ||||
|     { | ||||
|         var config = Furion.App.GetConfig<LK.Application.MqttConfig>("MqttConfig", true); | ||||
|  | ||||
|         o.ListenAnyIP(config.Port, a => MQTTnet.AspNetCore.ConnectionBuilderExtensions.UseMqtt(a)); | ||||
|  | ||||
|         o.ListenAnyIP(config.WebSocketPort); // Default HTTP pipeline | ||||
|     }); | ||||
| #endif | ||||
|  | ||||
|         //Furion便利方法 | ||||
|         builder.Inject(); | ||||
|         var app = builder.Build(); | ||||
|   | ||||
| @@ -47,5 +47,8 @@ | ||||
| 		<ProjectReference Include="..\ThingsGateway.Web.Core\ThingsGateway.Web.Core.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' OR '$(SolutionName)'=='ThingsGateway - Pro - AF2021'"> | ||||
| 		<DefineConstants>AF2021</DefineConstants> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| </Project> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user