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