Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7ba9ac7a5b | ||
![]() |
85b8f26e8e | ||
![]() |
594a0f1410 | ||
![]() |
d317d757d7 | ||
![]() |
fdf0ba6318 | ||
![]() |
15bf7de5fa | ||
![]() |
d3402b058e | ||
![]() |
e7dfdd4031 | ||
![]() |
b2dd7b6364 | ||
![]() |
9bd6d9abbf | ||
![]() |
cd14428fea | ||
![]() |
19d9f03c2b | ||
![]() |
0d57e72bbf | ||
![]() |
329516a61b | ||
![]() |
d566869589 | ||
![]() |
9cb8d8e6c7 | ||
![]() |
9de3c57e5d | ||
![]() |
f32ff92b0b | ||
![]() |
88d71e271e | ||
![]() |
fd9c14612a | ||
![]() |
e26e5a160f | ||
![]() |
b836bfed22 | ||
![]() |
a4b598c6d0 | ||
![]() |
c9ab755839 | ||
![]() |
9920edba53 | ||
![]() |
12bd7280d1 | ||
![]() |
d30ea7f63b | ||
![]() |
ebd3390db6 | ||
![]() |
9a374a9ebc | ||
![]() |
b1bc22cb08 | ||
![]() |
4930d53890 | ||
![]() |
c31327b5bc | ||
![]() |
3f2aa1f1e1 | ||
![]() |
6e78c00a96 | ||
![]() |
c27dde085e | ||
![]() |
d26cc308c0 | ||
![]() |
fb1efdf290 | ||
![]() |
3c99f2a472 | ||
![]() |
affe9a44e0 | ||
![]() |
43730fa519 | ||
![]() |
d39aa22b09 | ||
![]() |
e232a6b6ea |
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.20</Version>
|
||||
<Version>3.0.0.25</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
<Authors>Diego</Authors>
|
||||
|
@@ -26,10 +26,10 @@
|
||||
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port />
|
||||
|
||||
<MButton Class="ma-1" OnClick=@Connect Color="primary">
|
||||
连接
|
||||
启动
|
||||
</MButton>
|
||||
<MButton Class="ma-1" OnClick=@DisConnect Color="red">
|
||||
断开
|
||||
停止
|
||||
</MButton>
|
||||
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
@@ -26,7 +26,7 @@ public partial class MainLayout
|
||||
[
|
||||
{
|
||||
"Href": "/index",
|
||||
"Title": "<EFBFBD><EFBFBD>ҳ"
|
||||
"Title": "首页"
|
||||
},
|
||||
{
|
||||
"Title": "Modbus",
|
||||
|
@@ -56,10 +56,10 @@
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\MqttRpcNameVaueWithId.cs" Link="Pages\Mqtt\MqttRpcNameVaueWithId.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor.cs" Link="Pages\Mqtt\MqttClientDebugPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor.cs" Link="Pages\Mqtt\MqttClientPage.razor.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\PrivateLogger.cs" Link="Pages\Mqtt\PrivateLogger.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClient.cs" Link="Pages\Mqtt\MqttRpcClient.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcClientExtensions.cs" Link="Pages\Mqtt\MqttRpcClientExtensions.cs" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\RpcClass\MqttRpcTopicPair.cs" Link="Pages\Mqtt\MqttRpcTopicPair.cs" />
|
||||
<Compile Include="..\..\Web\ThingsGateway.Gateway.Application\Workers\ManageGateway\MqttLoggerExtensions.cs" Link="Pages\Mqtt\MqttLoggerExtensions.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor" Link="Pages\DLT645\DLT645_2007DebugPage.razor" />
|
||||
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor.cs" />
|
||||
<Content Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007OverTcpDebugPage.razor" Link="Pages\DLT645\DLT645_2007OverTcpDebugPage.razor" />
|
||||
@@ -115,7 +115,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup >
|
||||
<ItemGroup>
|
||||
<!--<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" />
|
||||
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" />
|
||||
@@ -128,7 +128,7 @@
|
||||
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />
|
||||
|
||||
</ItemGroup>
|
||||
<ItemGroup >
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.20</Version>
|
||||
<Version>3.0.0.25</Version>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<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);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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[]>("功能码错误");
|
||||
}
|
||||
|
||||
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)
|
||||
finally
|
||||
{
|
||||
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);
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -173,87 +187,108 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
|
||||
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
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();
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
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());
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -186,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
var item = commandResult.Content;
|
||||
if (FrameTime != 0)
|
||||
Thread.Sleep(FrameTime);
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { ThrowBreakException = true });
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
|
||||
|
||||
var item = commandResult.Content;
|
||||
await Task.Delay(FrameTime, cancellationToken);
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { ThrowBreakException = true });
|
||||
var WaitingClientEx = client.CreateWaitingClient(new() { });
|
||||
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
|
||||
return (MessageBase)result.RequestInfo;
|
||||
}
|
||||
|
@@ -104,62 +104,75 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
|
||||
|
||||
}
|
||||
|
||||
EasyLock easyLock = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult<byte[]>(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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[]>("功能码错误");
|
||||
}
|
||||
|
||||
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)
|
||||
finally
|
||||
{
|
||||
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);
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult<byte[]>("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -193,84 +206,104 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new OperResult(ex);
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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];
|
||||
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
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();
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
mAddress = ModbusAddress.ParseFrom(address, Station);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (new OperResult(ex));
|
||||
}
|
||||
if (MulStation)
|
||||
{
|
||||
Init(mAddress);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Station != mAddress.Station)
|
||||
easyLock.Wait();
|
||||
ModbusAddress mAddress;
|
||||
try
|
||||
{
|
||||
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("功能码错误");
|
||||
|
||||
}
|
||||
|
||||
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
|
||||
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
|
||||
switch (mAddress.ReadFunction)
|
||||
finally
|
||||
{
|
||||
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());
|
||||
|
||||
easyLock.Release();
|
||||
}
|
||||
return new OperResult("功能码错误");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#region copyright
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -9,7 +8,6 @@
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endregion
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -549,6 +547,7 @@ public class OPCUAClient : IDisposable
|
||||
throw new ArgumentNullException("未初始化配置");
|
||||
}
|
||||
var useSecurity = OPCNode?.IsUseSecurity ?? true;
|
||||
|
||||
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, useSecurity, 10000);
|
||||
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
|
||||
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
|
||||
@@ -571,7 +570,8 @@ public class OPCUAClient : IDisposable
|
||||
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
|
||||
60000,
|
||||
userIdentity,
|
||||
Array.Empty<string>());
|
||||
Array.Empty<string>()
|
||||
).ConfigureAwait(false);
|
||||
typeSystem = new ComplexTypeSystem(m_session);
|
||||
|
||||
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
|
||||
@@ -741,7 +741,7 @@ public class OPCUAClient : IDisposable
|
||||
NodeId nodeToRead = new(nodeIdStr);
|
||||
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, NodeClass.Variable, false, cancellationToken);
|
||||
if (OPCNode.LoadType)
|
||||
await typeSystem.LoadType(node.DataType);
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStr, node);
|
||||
return node;
|
||||
}
|
||||
@@ -781,7 +781,7 @@ public class OPCUAClient : IDisposable
|
||||
if (StatusCode.IsGood(nodes.Item2[i].StatusCode))
|
||||
{
|
||||
var node = ((VariableNode)nodes.Item1[i]);
|
||||
await typeSystem.LoadType(node.DataType);
|
||||
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
|
||||
_variableDicts.AddOrUpdate(nodeIdStrs[i], node);
|
||||
}
|
||||
else
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#region copyright
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
@@ -9,7 +8,6 @@
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endregion
|
||||
|
||||
using Opc.Ua;
|
||||
|
@@ -11,5 +11,4 @@
|
||||
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
@@ -36,11 +36,42 @@ internal partial class SiemensHelper
|
||||
// return OperResult.CreateSuccessResult<byte[]>(numArray);
|
||||
//}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisReadByte(byte[] sends, byte[] content)
|
||||
{
|
||||
int length = 0;
|
||||
int itemLen = (sends.Length - 19) / 12;
|
||||
|
||||
//添加错误代码校验
|
||||
if (content[17] + content[18] > 0)
|
||||
{
|
||||
return new($"PLC返回错误,错误类型{content[17].ToString("X2")}错误代码:{content[18].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
if (content.Length < 21)
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
if (content.Length < 25 + content[20])
|
||||
{
|
||||
return new($"长度不足")
|
||||
{
|
||||
Content2 = FilterResult.Cache
|
||||
};
|
||||
}
|
||||
//添加返回代码校验
|
||||
if (content[21] != 0xff)
|
||||
{
|
||||
return new($"PLC返回错误,返回代码{content[21].ToString("X2")}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
for (int index = 0; index < itemLen; index++)
|
||||
{
|
||||
if (sends[22 + (index * 12)] >= (byte)S7WordLength.Word)
|
||||
@@ -53,9 +84,9 @@ internal partial class SiemensHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (content.Length < 21 || content[20] != itemLen)
|
||||
if (content[20] != itemLen)
|
||||
{
|
||||
return new OperResult<byte[]>("数据块长度校验失败");
|
||||
return new("数据块长度校验失败");
|
||||
}
|
||||
|
||||
byte[] dataArray = new byte[length];
|
||||
@@ -105,29 +136,39 @@ internal partial class SiemensHelper
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[index2] + GetCpuError(content[index2]));
|
||||
return new((int)content[index2] + GetCpuError(content[index2]))
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return OperResult.CreateSuccessResult(dataArray);
|
||||
return OperResult.CreateSuccessResult(dataArray, FilterResult.Success);
|
||||
|
||||
}
|
||||
|
||||
internal static OperResult<byte[]> AnalysisWrite(byte[] content)
|
||||
internal static OperResult<byte[], FilterResult> AnalysisWrite(byte[] content)
|
||||
{
|
||||
if (content.Length < 22)
|
||||
{
|
||||
return new OperResult<byte[]>() { Message = "未知错误" };
|
||||
return new()
|
||||
{
|
||||
Message = "长度不足",
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
|
||||
byte err = content[21];
|
||||
if (err != byte.MaxValue)
|
||||
{
|
||||
return new OperResult<byte[]>((int)content[21] + GetCpuError(content[21]));
|
||||
return new($"错误代码:{(int)content[21]}描述:{GetCpuError(content[21])}")
|
||||
{
|
||||
Content2 = FilterResult.Success
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return OperResult.CreateSuccessResult(content);
|
||||
return OperResult.CreateSuccessResult(content, FilterResult.Success);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -123,34 +123,7 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
|
||||
#region 设置
|
||||
|
||||
/// <summary>
|
||||
/// 远程TSAP,需重新连接
|
||||
/// </summary>
|
||||
public int DestTSAP
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart ?
|
||||
(ISO_CR[17] * 256) + ISO_CR[18] :
|
||||
(ISO_CR[20] * 256) + ISO_CR[21];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart)
|
||||
{
|
||||
ISO_CR[17] = BitConverter.GetBytes(value)[1];
|
||||
ISO_CR[18] = BitConverter.GetBytes(value)[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
ISO_CR[20] = BitConverter.GetBytes(value)[1];
|
||||
ISO_CR[21] = BitConverter.GetBytes(value)[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地TSAP,需重新连接
|
||||
/// 本地TSAP
|
||||
/// </summary>
|
||||
public int LocalTSAP
|
||||
{
|
||||
|
@@ -35,10 +35,10 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
/// <inheritdoc/>
|
||||
protected override FilterResult UnpackResponse(SiemensMessage request, byte[] send, byte[] body, byte[] response)
|
||||
{
|
||||
var result = new OperResult<byte[]>();
|
||||
var result = new OperResult<byte[], FilterResult>();
|
||||
if (response[2] * 256 + response[3] == 7)
|
||||
{
|
||||
result = new OperResult<byte[]>() { Content = response };
|
||||
result = new() { Content = response, Content2 = FilterResult.Success };
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,6 +56,6 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
|
||||
request.ErrorCode = result.ErrorCode;
|
||||
request.Message = result.Message;
|
||||
request.Content = result.Content;
|
||||
return FilterResult.Success;
|
||||
return result.Content2;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,15 @@
|
||||
0x00 Reserved 未定义,预留
|
||||
|
||||
0x01 Hardware error 硬件错误
|
||||
|
||||
0x03 Accessing the object not allowed 对象不允许访问
|
||||
|
||||
0x05 Invalid address 无效地址,所需的地址超出此PLC的极限
|
||||
|
||||
0x06 Data type not supported 数据类型不支持
|
||||
|
||||
0x07 Data type inconsistent 日期类型不一致
|
||||
|
||||
0x0a Object does not exist 对象不存在
|
||||
|
||||
0xff Success 成功
|
@@ -0,0 +1,825 @@
|
||||
附录一:错误码具体含义
|
||||
|
||||
0x0000
|
||||
|
||||
没有错误
|
||||
|
||||
0x0110
|
||||
|
||||
块号无效
|
||||
|
||||
0x0111
|
||||
|
||||
请求长度无效
|
||||
|
||||
0x0112
|
||||
|
||||
参数无效
|
||||
|
||||
0x0113
|
||||
|
||||
块类型无效
|
||||
|
||||
0x0114
|
||||
|
||||
找不到块
|
||||
|
||||
0x0115
|
||||
|
||||
块已存在
|
||||
|
||||
0x0116
|
||||
|
||||
块被写保护
|
||||
|
||||
0x0117
|
||||
|
||||
块/操作系统更新太大
|
||||
|
||||
0x0118
|
||||
|
||||
块号无效
|
||||
|
||||
0x0119
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0x011A
|
||||
|
||||
PG资源错误
|
||||
|
||||
0x011B
|
||||
|
||||
PLC资源错误
|
||||
|
||||
0x011C
|
||||
|
||||
协议错误
|
||||
|
||||
0x011D
|
||||
|
||||
块太多(与模块相关的限制)
|
||||
|
||||
0x011E
|
||||
|
||||
不再与数据库建立连接,或者S7DOS句柄无效
|
||||
|
||||
0x011F
|
||||
|
||||
结果缓冲区太小
|
||||
|
||||
0x0120
|
||||
|
||||
块结束列表
|
||||
|
||||
0x0140
|
||||
|
||||
可用内存不足
|
||||
|
||||
0x0141
|
||||
|
||||
由于缺少资源,无法处理作业
|
||||
|
||||
0x8001
|
||||
|
||||
当块处于当前状态时,无法执行请求的服务
|
||||
|
||||
0x8003
|
||||
|
||||
S7协议错误:传输块时发生错误
|
||||
|
||||
0x8100
|
||||
|
||||
应用程序,一般错误:远程模块未知的服务
|
||||
|
||||
0x8104
|
||||
|
||||
未在模块上实现此服务或报告了帧错误
|
||||
|
||||
0x8204
|
||||
|
||||
对象的类型规范不一致
|
||||
|
||||
0x8205
|
||||
|
||||
复制的块已存在且未链接
|
||||
|
||||
0x8301
|
||||
|
||||
模块上的内存空间或工作内存不足,或者指定的存储介质不可访问
|
||||
|
||||
0x8302
|
||||
|
||||
可用资源太少或处理器资源不可用
|
||||
|
||||
0x8304
|
||||
|
||||
无法进一步并行上传。存在资源瓶颈
|
||||
|
||||
0x8305
|
||||
|
||||
功能不可用
|
||||
|
||||
0x8306
|
||||
|
||||
工作内存不足(用于复制,链接,加载AWP)
|
||||
|
||||
0x8307
|
||||
|
||||
保持性工作记忆不够(用于复制,链接,加载AWP)
|
||||
|
||||
0x8401
|
||||
|
||||
S7协议错误:无效的服务序列(例如,加载或上载块)
|
||||
|
||||
0x8402
|
||||
|
||||
由于寻址对象的状态,服务无法执行
|
||||
|
||||
0x8404
|
||||
|
||||
S7协议:无法执行该功能
|
||||
|
||||
0x8405
|
||||
|
||||
远程块处于DISABLE状态(CFB)。该功能无法执行
|
||||
|
||||
0x8500
|
||||
|
||||
S7协议错误:帧错误
|
||||
|
||||
0x8503
|
||||
|
||||
来自模块的警报:服务过早取消
|
||||
|
||||
0x8701
|
||||
|
||||
寻址通信伙伴上的对象时出错(例如,区域长度错误)
|
||||
|
||||
0x8702
|
||||
|
||||
模块不支持所请求的服务
|
||||
|
||||
0x8703
|
||||
|
||||
拒绝访问对象
|
||||
|
||||
0x8704
|
||||
|
||||
访问错误:对象已损坏
|
||||
|
||||
0xD001
|
||||
|
||||
协议错误:非法的作业号
|
||||
|
||||
0xD002
|
||||
|
||||
参数错误:非法的作业变体
|
||||
|
||||
0xD003
|
||||
|
||||
参数错误:模块不支持调试功能
|
||||
|
||||
0xD004
|
||||
|
||||
参数错误:作业状态非法
|
||||
|
||||
0xD005
|
||||
|
||||
参数错误:作业终止非法
|
||||
|
||||
0xD006
|
||||
|
||||
参数错误:非法链路断开ID
|
||||
|
||||
0xD007
|
||||
|
||||
参数错误:缓冲区元素数量非法
|
||||
|
||||
0xD008
|
||||
|
||||
参数错误:扫描速率非法
|
||||
|
||||
0xD009
|
||||
|
||||
参数错误:执行次数非法
|
||||
|
||||
0xD00A
|
||||
|
||||
参数错误:非法触发事件
|
||||
|
||||
0xD00B
|
||||
|
||||
参数错误:非法触发条件
|
||||
|
||||
0xD011
|
||||
|
||||
调用环境路径中的参数错误:块不存在
|
||||
|
||||
0xD012
|
||||
|
||||
参数错误:块中的地址错误
|
||||
|
||||
0xD014
|
||||
|
||||
参数错误:正在删除/覆盖块
|
||||
|
||||
0xD015
|
||||
|
||||
参数错误:标签地址非法
|
||||
|
||||
0xD016
|
||||
|
||||
参数错误:由于用户程序错误,无法测试作业
|
||||
|
||||
0xD017
|
||||
|
||||
参数错误:非法触发号
|
||||
|
||||
0xD025
|
||||
|
||||
参数错误:路径无效
|
||||
|
||||
0xD026
|
||||
|
||||
参数错误:非法访问类型
|
||||
|
||||
0xD027
|
||||
|
||||
参数错误:不允许此数据块数
|
||||
|
||||
0xD031
|
||||
|
||||
内部协议错误
|
||||
|
||||
0xD032
|
||||
|
||||
参数错误:结果缓冲区长度错误
|
||||
|
||||
0xD033
|
||||
|
||||
协议错误:作业长度错误
|
||||
|
||||
0xD03F
|
||||
|
||||
编码错误:参数部分出错(例如,保留字节不等于0)
|
||||
|
||||
0xD041
|
||||
|
||||
数据错误:非法状态列表ID
|
||||
|
||||
0xD042
|
||||
|
||||
数据错误:标签地址非法
|
||||
|
||||
0xD043
|
||||
|
||||
数据错误:找不到引用的作业,检查作业数据
|
||||
|
||||
0xD044
|
||||
|
||||
数据错误:标签值非法,检查作业数据
|
||||
|
||||
0xD045
|
||||
|
||||
数据错误:HOLD中不允许退出ODIS控制
|
||||
|
||||
0xD046
|
||||
|
||||
数据错误:运行时测量期间非法测量阶段
|
||||
|
||||
0xD047
|
||||
|
||||
数据错误:“读取作业列表”中的非法层次结构
|
||||
|
||||
0xD048
|
||||
|
||||
数据错误:“删除作业”中的非法删除ID
|
||||
|
||||
0xD049
|
||||
|
||||
“替换作业”中的替换ID无效
|
||||
|
||||
0xD04A
|
||||
|
||||
执行'程序状态'时出错
|
||||
|
||||
0xD05F
|
||||
|
||||
编码错误:数据部分出错(例如,保留字节不等于0,...)
|
||||
|
||||
0xD061
|
||||
|
||||
资源错误:没有作业的内存空间
|
||||
|
||||
0xD062
|
||||
|
||||
资源错误:作业列表已满
|
||||
|
||||
0xD063
|
||||
|
||||
资源错误:触发事件占用
|
||||
|
||||
0xD064
|
||||
|
||||
资源错误:没有足够的内存空间用于一个结果缓冲区元素
|
||||
|
||||
0xD065
|
||||
|
||||
资源错误:没有足够的内存空间用于多个结果缓冲区元素
|
||||
|
||||
0xD066
|
||||
|
||||
资源错误:可用于运行时测量的计时器被另一个作业占用
|
||||
|
||||
0xD067
|
||||
|
||||
资源错误:“修改标记”作业过多(特别是多处理器操作)
|
||||
|
||||
0xD081
|
||||
|
||||
当前模式下不允许使用的功能
|
||||
|
||||
0xD082
|
||||
|
||||
模式错误:无法退出HOLD模式
|
||||
|
||||
0xD0A1
|
||||
|
||||
当前保护级别不允许使用的功能
|
||||
|
||||
0xD0A2
|
||||
|
||||
目前无法运行,因为正在运行的函数会修改内存
|
||||
|
||||
0xD0A3
|
||||
|
||||
I / O上活动的“修改标记”作业太多(特别是多处理器操作)
|
||||
|
||||
0xD0A4
|
||||
|
||||
'强制'已经建立
|
||||
|
||||
0xD0A5
|
||||
|
||||
找不到引用的作业
|
||||
|
||||
0xD0A6
|
||||
|
||||
无法禁用/启用作业
|
||||
|
||||
0xD0A7
|
||||
|
||||
无法删除作业,例如因为当前正在读取作业
|
||||
|
||||
0xD0A8
|
||||
|
||||
无法替换作业,例如因为当前正在读取或删除作业
|
||||
|
||||
0xD0A9
|
||||
|
||||
无法读取作业,例如因为当前正在删除作业
|
||||
|
||||
0xD0AA
|
||||
|
||||
处理操作超出时间限制
|
||||
|
||||
0xD0AB
|
||||
|
||||
进程操作中的作业参数无效
|
||||
|
||||
0xD0AC
|
||||
|
||||
进程操作中的作业数据无效
|
||||
|
||||
0xD0AD
|
||||
|
||||
已设置操作模式
|
||||
|
||||
0xD0AE
|
||||
|
||||
作业是通过不同的连接设置的,只能通过此连接进行处理
|
||||
|
||||
0xD0C1
|
||||
|
||||
访问标签时至少检测到一个错误
|
||||
|
||||
0xD0C2
|
||||
|
||||
切换到STOP / HOLD模式
|
||||
|
||||
0xD0C3
|
||||
|
||||
访问标记时至少检测到一个错误。模式更改为STOP / HOLD
|
||||
|
||||
0xD0C4
|
||||
|
||||
运行时测量期间超时
|
||||
|
||||
0xD0C5
|
||||
|
||||
块堆栈的显示不一致,因为块被删除/重新加载
|
||||
|
||||
0xD0C6
|
||||
|
||||
作业已被删除,因为它所引用的作业已被删除
|
||||
|
||||
0xD0C7
|
||||
|
||||
由于退出了STOP模式,因此作业被自动删除
|
||||
|
||||
0xD0C8
|
||||
|
||||
由于测试作业和正在运行的程序之间不一致,“块状态”中止
|
||||
|
||||
0xD0C9
|
||||
|
||||
通过复位OB90退出状态区域
|
||||
|
||||
0xD0CA
|
||||
|
||||
通过在退出前重置OB90并访问错误读取标签退出状态范围
|
||||
|
||||
0xD0CB
|
||||
|
||||
外设输出的输出禁用再次激活
|
||||
|
||||
0xD0CC
|
||||
|
||||
调试功能的数据量受时间限制
|
||||
|
||||
0xD201
|
||||
|
||||
块名称中的语法错误
|
||||
|
||||
0xD202
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD205
|
||||
|
||||
RAM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD206
|
||||
|
||||
EPROM中已存在链接块:无法进行条件复制
|
||||
|
||||
0xD208
|
||||
|
||||
超出模块的最大复制(未链接)块数
|
||||
|
||||
0xD209
|
||||
|
||||
(至少)模块上找不到给定块之一
|
||||
|
||||
0xD20A
|
||||
|
||||
超出了可以与一个作业链接的最大块数
|
||||
|
||||
0xD20B
|
||||
|
||||
超出了一个作业可以删除的最大块数
|
||||
|
||||
0xD20C
|
||||
|
||||
OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD20D
|
||||
|
||||
SDB无法解释(例如,未知数)
|
||||
|
||||
0xD20E
|
||||
|
||||
没有(进一步)阻止可用
|
||||
|
||||
0xD20F
|
||||
|
||||
超出模块特定的最大块大小
|
||||
|
||||
0xD210
|
||||
|
||||
块号无效
|
||||
|
||||
0xD212
|
||||
|
||||
标头属性不正确(与运行时相关)
|
||||
|
||||
0xD213
|
||||
|
||||
SDB太多。请注意对正在使用的模块的限制
|
||||
|
||||
0xD216
|
||||
|
||||
无效的用户程序 - 重置模块
|
||||
|
||||
0xD217
|
||||
|
||||
不允许在模块属性中指定的保护级别
|
||||
|
||||
0xD218
|
||||
|
||||
属性不正确(主动/被动)
|
||||
|
||||
0xD219
|
||||
|
||||
块长度不正确(例如,第一部分或整个块的长度不正确)
|
||||
|
||||
0xD21A
|
||||
|
||||
本地数据长度不正确或写保护错误
|
||||
|
||||
0xD21B
|
||||
|
||||
模块无法压缩或压缩早期中断
|
||||
|
||||
0xD21D
|
||||
|
||||
传输的动态项目数据量是非法的
|
||||
|
||||
0xD21E
|
||||
|
||||
无法为模块(例如FM,CP)分配参数。系统数据无法链接
|
||||
|
||||
0xD220
|
||||
|
||||
编程语言无效。请注意对正在使用的模块的限制
|
||||
|
||||
0xD221
|
||||
|
||||
连接或路由的系统数据无效
|
||||
|
||||
0xD222
|
||||
|
||||
全局数据定义的系统数据包含无效参数
|
||||
|
||||
0xD223
|
||||
|
||||
通信功能块的实例数据块错误或超出最大背景数据块数
|
||||
|
||||
0xD224
|
||||
|
||||
SCAN系统数据块包含无效参数
|
||||
|
||||
0xD225
|
||||
|
||||
DP系统数据块包含无效参数
|
||||
|
||||
0xD226
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD230
|
||||
|
||||
块中发生结构错误
|
||||
|
||||
0xD231
|
||||
|
||||
至少有一个已加载的OB无法复制,因为关联的优先级不存在
|
||||
|
||||
0xD232
|
||||
|
||||
加载块的至少一个块编号是非法的
|
||||
|
||||
0xD234
|
||||
|
||||
块在指定的内存介质或作业中存在两次
|
||||
|
||||
0xD235
|
||||
|
||||
该块包含不正确的校验和
|
||||
|
||||
0xD236
|
||||
|
||||
该块不包含校验和
|
||||
|
||||
0xD237
|
||||
|
||||
您将要加载块两次,即CPU上已存在具有相同时间戳的块
|
||||
|
||||
0xD238
|
||||
|
||||
指定的块中至少有一个不是DB
|
||||
|
||||
0xD239
|
||||
|
||||
至少有一个指定的DB在装载存储器中不可用作链接变量
|
||||
|
||||
0xD23A
|
||||
|
||||
至少有一个指定的DB与复制和链接的变体有很大不同
|
||||
|
||||
0xD240
|
||||
|
||||
违反了协调规则
|
||||
|
||||
0xD241
|
||||
|
||||
当前保护级别不允许该功能
|
||||
|
||||
0xD242
|
||||
|
||||
处理F块时的保护冲突
|
||||
|
||||
0xD250
|
||||
|
||||
更新和模块ID或版本不匹配
|
||||
|
||||
0xD251
|
||||
|
||||
操作系统组件序列不正确
|
||||
|
||||
0xD252
|
||||
|
||||
校验和错误
|
||||
|
||||
0xD253
|
||||
|
||||
没有可用的可执行加载程序; 只能使用存储卡进行更新
|
||||
|
||||
0xD254
|
||||
|
||||
操作系统中的存储错误
|
||||
|
||||
0xD280
|
||||
|
||||
在S7-300 CPU中编译块时出错
|
||||
|
||||
0xD2A1
|
||||
|
||||
块上的另一个块功能或触发器处于活动状态
|
||||
|
||||
0xD2A2
|
||||
|
||||
块上的触发器处于活动状态。首先完成调试功能
|
||||
|
||||
0xD2A3
|
||||
|
||||
块未激活(链接),块被占用或块当前被标记为删除
|
||||
|
||||
0xD2A4
|
||||
|
||||
该块已被另一个块函数处理
|
||||
|
||||
0xD2A6
|
||||
|
||||
无法同时保存和更改用户程序
|
||||
|
||||
0xD2A7
|
||||
|
||||
块具有“未链接”属性或未处理
|
||||
|
||||
0xD2A8
|
||||
|
||||
激活的调试功能阻止将参数分配给CPU
|
||||
|
||||
0xD2A9
|
||||
|
||||
正在为CPU分配新参数
|
||||
|
||||
0xD2AA
|
||||
|
||||
当前正在为模块分配新参数
|
||||
|
||||
0xD2AB
|
||||
|
||||
当前正在更改动态配置限制
|
||||
|
||||
0xD2AC
|
||||
|
||||
正在运行的激活或取消激活分配(SFC 12)暂时阻止R-KiR过程
|
||||
|
||||
0xD2B0
|
||||
|
||||
在RUN(CiR)中配置时发生错误
|
||||
|
||||
0xD2C0
|
||||
|
||||
已超出最大工艺对象数
|
||||
|
||||
0xD2C1
|
||||
|
||||
模块上已存在相同的技术数据块
|
||||
|
||||
0xD2C2
|
||||
|
||||
无法下载用户程序或下载硬件配置
|
||||
|
||||
0xD401
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD402
|
||||
|
||||
信息功能不可用
|
||||
|
||||
0xD403
|
||||
|
||||
服务已登录/注销(诊断/ PMC)
|
||||
|
||||
0xD404
|
||||
|
||||
达到的最大节点数。不再需要登录诊断/ PMC
|
||||
|
||||
0xD405
|
||||
|
||||
不支持服务或函数参数中的语法错误
|
||||
|
||||
0xD406
|
||||
|
||||
当前不可用的必需信息
|
||||
|
||||
0xD407
|
||||
|
||||
发生诊断错误
|
||||
|
||||
0xD408
|
||||
|
||||
更新已中止
|
||||
|
||||
0xD409
|
||||
|
||||
DP总线错误
|
||||
|
||||
0xD601
|
||||
|
||||
函数参数中的语法错误
|
||||
|
||||
0xD602
|
||||
|
||||
输入的密码不正确
|
||||
|
||||
0xD603
|
||||
|
||||
连接已合法化
|
||||
|
||||
0xD604
|
||||
|
||||
已启用连接
|
||||
|
||||
0xD605
|
||||
|
||||
由于密码不存在,因此无法进行合法化
|
||||
|
||||
0xD801
|
||||
|
||||
至少有一个标记地址无效
|
||||
|
||||
0xD802
|
||||
|
||||
指定的作业不存在
|
||||
|
||||
0xD803
|
||||
|
||||
非法的工作状态
|
||||
|
||||
0xD804
|
||||
|
||||
非法循环时间(非法时基或多个)
|
||||
|
||||
0xD805
|
||||
|
||||
不能再设置循环读取作业
|
||||
|
||||
0xD806
|
||||
|
||||
引用的作业处于无法执行请求的功能的状态
|
||||
|
||||
0xD807
|
||||
|
||||
功能因过载而中止,这意味着执行读取周期所需的时间比设置的扫描周期时间长
|
||||
|
||||
0xDC01
|
||||
|
||||
日期和/或时间无效
|
||||
|
||||
0xE201
|
||||
|
||||
CPU已经是主设备
|
||||
|
||||
0xE202
|
||||
|
||||
由于闪存模块中的用户程序不同,无法进行连接和更新
|
||||
|
||||
0xE203
|
||||
|
||||
由于固件不同,无法连接和更新
|
||||
|
||||
0xE204
|
||||
|
||||
由于内存配置不同,无法连接和更新
|
||||
|
||||
0xE205
|
||||
|
||||
由于同步错误导致连接/更新中止
|
||||
|
||||
0xE206
|
||||
|
||||
由于协调违规而拒绝连接/更新
|
||||
|
||||
0xEF01
|
||||
|
||||
S7协议错误:ID2错误; 工作中只允许00H
|
||||
|
||||
0xEF02
|
||||
|
||||
S7协议错误:ID2错误; 资源集不存在
|
@@ -24,7 +24,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
|
||||
{
|
||||
SerialSession = serialSession;
|
||||
WaitingClientEx = SerialSession.CreateWaitingClient(new() { ThrowBreakException = true });
|
||||
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
|
||||
SerialSession.Received -= Received;
|
||||
SerialSession.Connecting -= Connecting;
|
||||
SerialSession.Connected -= Connected;
|
||||
@@ -96,7 +96,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = SerialSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await SerialSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
public ReadWriteDevicesTcpClientBase(TcpClient tcpClient)
|
||||
{
|
||||
TcpClient = tcpClient;
|
||||
WaitingClientEx = TcpClient.CreateWaitingClient(new() { ThrowBreakException = true });
|
||||
WaitingClientEx = TcpClient.CreateWaitingClient(new() { });
|
||||
TcpClient.Connecting -= Connecting;
|
||||
TcpClient.Connected -= Connected;
|
||||
TcpClient.Disconnecting -= Disconnecting;
|
||||
@@ -86,7 +86,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = TcpClient.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await TcpClient.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
|
@@ -55,7 +55,8 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
|
||||
/// <inheritdoc/>
|
||||
public override Task ConnectAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.Run(() => TcpService.Start());
|
||||
Connect(cancellationToken);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -22,7 +22,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
UdpSession = udpSession;
|
||||
SetDataAdapter();
|
||||
WaitingClientEx = UdpSession.CreateWaitingClient(new() { ThrowBreakException = true });
|
||||
WaitingClientEx = UdpSession.CreateWaitingClient(new() { });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,7 +64,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = UdpSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
|
||||
{
|
||||
try
|
||||
{
|
||||
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
|
||||
waitingOptions ??= new WaitingOptions { };
|
||||
ResponsedData result = await UdpSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
|
||||
return OperResult.CreateSuccessResult(result.Data);
|
||||
}
|
||||
|
@@ -51,10 +51,10 @@ public sealed class EasyLock
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public void Wait()
|
||||
public void Wait(CancellationToken cancellationToken = default)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
m_waiterLock.Wait();
|
||||
m_waiterLock.Wait(cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
}
|
||||
/// <summary>
|
||||
@@ -71,10 +71,10 @@ public sealed class EasyLock
|
||||
/// <summary>
|
||||
/// 进入锁
|
||||
/// </summary>
|
||||
public async Task WaitAsync()
|
||||
public async Task WaitAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
Interlocked.Increment(ref lockWaitCount);
|
||||
await m_waiterLock.WaitAsync();
|
||||
await m_waiterLock.WaitAsync(cancellationToken);
|
||||
Interlocked.Decrement(ref lockWaitCount);
|
||||
}
|
||||
/// <summary>
|
||||
|
@@ -180,6 +180,13 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return Owner.ToString();
|
||||
if (Owner is SocketClient client)
|
||||
{
|
||||
return client.GetIPPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Owner.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -114,17 +115,47 @@ public static class StringExtensions
|
||||
else if (propertyType == typeof(sbyte))
|
||||
_value = sbyte.Parse(value);
|
||||
else if (propertyType == typeof(short))
|
||||
_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))
|
||||
_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))
|
||||
_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))
|
||||
_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))
|
||||
_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))
|
||||
_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))
|
||||
_value = float.Parse(value);
|
||||
else if (propertyType == typeof(double))
|
||||
@@ -142,7 +173,6 @@ public static class StringExtensions
|
||||
else if (propertyType.IsEnum)
|
||||
_value = Enum.Parse(propertyType, value);
|
||||
return _value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -189,7 +189,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetTupleElementNames(this ParameterInfo parameter)
|
||||
{
|
||||
return ((dynamic)parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
|
||||
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -199,7 +199,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetTupleElementNames(this MemberInfo memberInfo)
|
||||
{
|
||||
return ((dynamic)memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
|
||||
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@@ -23,6 +23,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace ThingsGateway.Foundation.Core
|
||||
{
|
||||
/// <summary>
|
||||
@@ -49,5 +51,27 @@ namespace ThingsGateway.Foundation.Core
|
||||
{
|
||||
task.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 配置ConfigureAwait为false。
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="task"></param>
|
||||
/// <returns></returns>
|
||||
public static ConfiguredTaskAwaitable<T> ConfigureFalseAwait<T>(this Task<T> task)
|
||||
{
|
||||
return task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置ConfigureAwait为false。
|
||||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
public static ConfiguredTaskAwaitable ConfigureFalseAwait(this Task task)
|
||||
{
|
||||
return task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -11,6 +11,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
using System.Numerics;
|
||||
@@ -55,12 +56,11 @@ namespace ThingsGateway.Foundation.Core
|
||||
}
|
||||
|
||||
var capacity = 0L;
|
||||
var poolId = this.Id;
|
||||
var maxBuckets = SelectBucketIndex(maxArrayLength);
|
||||
var buckets = new Bucket[maxBuckets + 1];
|
||||
for (var i = 0; i < buckets.Length; i++)
|
||||
{
|
||||
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
|
||||
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket);
|
||||
long num = GetMaxSizeForBucket(i) * maxArraysPerBucket;
|
||||
capacity += num;
|
||||
}
|
||||
@@ -183,16 +183,19 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int HitSize(int size)
|
||||
{
|
||||
return GetMaxSizeForBucket(SelectBucketIndex(size));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static int GetMaxSizeForBucket(int binIndex)
|
||||
{
|
||||
return 16 << binIndex;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static int SelectBucketIndex(int bufferSize)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
@@ -208,18 +211,16 @@ namespace ThingsGateway.Foundation.Core
|
||||
internal readonly int m_bufferLength;
|
||||
private readonly int m_numberOfBuffers;
|
||||
private T[][] m_buffers;
|
||||
private readonly int m_poolId;
|
||||
|
||||
private int m_index;
|
||||
private SpinLock m_lock;
|
||||
|
||||
internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
|
||||
internal Bucket(int bufferLength, int numberOfBuffers)
|
||||
{
|
||||
this.m_lock = new SpinLock(Debugger.IsAttached);
|
||||
this.m_buffers = new T[numberOfBuffers][];
|
||||
this.m_bufferLength = bufferLength;
|
||||
this.m_numberOfBuffers = numberOfBuffers;
|
||||
this.m_poolId = poolId;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
|
@@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Core
|
||||
/// <summary>
|
||||
/// 内存池
|
||||
/// </summary>
|
||||
public class BytePool : ArrayPool<byte>
|
||||
public sealed class BytePool : ArrayPool<byte>
|
||||
{
|
||||
private readonly Timer m_timer;
|
||||
|
||||
|
@@ -27,43 +27,48 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <summary>
|
||||
/// 请求关闭
|
||||
/// </summary>
|
||||
public Action<DmtpActor, string> OnClose { get; set; }
|
||||
public Func<DmtpActor, string, Task> Closed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当创建通道时
|
||||
/// </summary>
|
||||
public Action<DmtpActor, CreateChannelEventArgs> OnCreateChannel { get; set; }
|
||||
public Func<DmtpActor, CreateChannelEventArgs, Task> CreatedChannel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 查找其他IDmtpActor
|
||||
/// </summary>
|
||||
public Func<string, IDmtpActor> OnFindDmtpActor { get; set; }
|
||||
public Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaked { get; set; }
|
||||
public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 握手
|
||||
/// </summary>
|
||||
public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaking { get; set; }
|
||||
public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaking { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 重设Id
|
||||
/// </summary>
|
||||
public Action<DmtpActor, WaitSetId> OnResetId { get; set; }
|
||||
public Func<DmtpActor, IdChangedEventArgs, Task> IdChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当需要路由的时候
|
||||
/// </summary>
|
||||
public Action<DmtpActor, PackageRouterEventArgs> OnRouting { get; set; }
|
||||
public Func<DmtpActor, PackageRouterEventArgs, Task> Routing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据接口
|
||||
/// </summary>
|
||||
public Action<DmtpActor, ArraySegment<byte>[]> OutputSend { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送数据接口
|
||||
/// </summary>
|
||||
public Func<DmtpActor, ArraySegment<byte>[], Task> OutputSendAsync { get; set; }
|
||||
|
||||
#endregion 委托
|
||||
|
||||
#region 属性
|
||||
@@ -118,32 +123,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual void Close(bool sendClose, string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sendClose)
|
||||
{
|
||||
this.SendString(0, message);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
this.IsHandshaked = false;
|
||||
this.WaitHandlePool.CancelAll();
|
||||
this.OnClose?.Invoke(this, message);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 建立对点
|
||||
@@ -165,7 +144,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
Metadata = metadata
|
||||
};
|
||||
|
||||
this.OnHandshaking?.Invoke(this, args);
|
||||
this.OnHandshaking(args).GetFalseAwaitResult();
|
||||
|
||||
var waitVerify = new WaitVerify()
|
||||
{
|
||||
@@ -189,7 +168,8 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
this.Id = verifyResult.Id;
|
||||
this.IsHandshaked = true;
|
||||
this.PrivateHandshaked(new DmtpVerifyEventArgs()
|
||||
|
||||
Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs()
|
||||
{
|
||||
Id = verifyResult.Id,
|
||||
Metadata = verifyResult.Metadata,
|
||||
@@ -201,18 +181,15 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
else
|
||||
{
|
||||
verifyResult.Handle = true;
|
||||
this.Close(false, verifyResult.Message);
|
||||
throw new TokenVerifyException(verifyResult.Message);
|
||||
}
|
||||
}
|
||||
case WaitDataStatus.Overtime:
|
||||
this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription());
|
||||
throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription());
|
||||
case WaitDataStatus.Canceled:
|
||||
case WaitDataStatus.Disposed:
|
||||
default:
|
||||
this.Close(false, null);
|
||||
return;
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -240,7 +217,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
Metadata = metadata
|
||||
};
|
||||
|
||||
this.OnHandshaking?.Invoke(this, args);
|
||||
await this.OnHandshaking(args).ConfigureFalseAwait();
|
||||
|
||||
var waitVerify = new WaitVerify()
|
||||
{
|
||||
@@ -253,8 +230,8 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
try
|
||||
{
|
||||
this.SendJsonObject(P1_Handshake_Request, waitVerify);
|
||||
switch (await waitData.WaitAsync(timeout))
|
||||
await this.SendJsonObjectAsync(P1_Handshake_Request, waitVerify).ConfigureFalseAwait();
|
||||
switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -263,7 +240,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
this.Id = verifyResult.Id;
|
||||
this.IsHandshaked = true;
|
||||
this.PrivateHandshaked(new DmtpVerifyEventArgs()
|
||||
_ = Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs()
|
||||
{
|
||||
Id = verifyResult.Id,
|
||||
Metadata = verifyResult.Metadata,
|
||||
@@ -275,18 +252,15 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
else
|
||||
{
|
||||
verifyResult.Handle = true;
|
||||
this.Close(false, verifyResult.Message);
|
||||
throw new TokenVerifyException(verifyResult.Message);
|
||||
}
|
||||
}
|
||||
case WaitDataStatus.Overtime:
|
||||
this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription());
|
||||
throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription());
|
||||
case WaitDataStatus.Canceled:
|
||||
case WaitDataStatus.Disposed:
|
||||
default:
|
||||
this.Close(false, null);
|
||||
return;
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -295,6 +269,100 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
#region 委托触发
|
||||
|
||||
/// <summary>
|
||||
/// 当关闭后
|
||||
/// </summary>
|
||||
/// <param name="manual"></param>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual Task OnClosed(bool manual, string msg)
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.IsHandshaked = false;
|
||||
this.WaitHandlePool.CancelAll();
|
||||
}
|
||||
|
||||
if (manual)
|
||||
{
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
if (this.Closed != null)
|
||||
{
|
||||
return this.Closed.Invoke(this, msg);
|
||||
}
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 正在握手连接
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (this.Handshaking != null)
|
||||
{
|
||||
return this.Handshaking.Invoke(this, e);
|
||||
}
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 握手连接完成
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (this.Handshaked != null)
|
||||
{
|
||||
return this.Handshaked.Invoke(this, e);
|
||||
}
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当Id修改时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task OnIdChanged(IdChangedEventArgs e)
|
||||
{
|
||||
if (this.IdChanged != null)
|
||||
{
|
||||
return this.IdChanged.Invoke(this, e);
|
||||
}
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当完成创建通道时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual Task OnCreatedChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (this.CreatedChannel != null)
|
||||
{
|
||||
return this.CreatedChannel.Invoke(this, e);
|
||||
}
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void PrivateOnHandshaked(object obj)
|
||||
{
|
||||
this.OnHandshaked((DmtpVerifyEventArgs)obj);
|
||||
}
|
||||
|
||||
private void PrivateOnCreatedChannel(object obj)
|
||||
{
|
||||
this.OnCreatedChannel((CreateChannelEventArgs)obj);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region const
|
||||
|
||||
/// <summary>
|
||||
@@ -368,7 +436,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool InputReceivedData(DmtpMessage message)
|
||||
public virtual async Task<bool> InputReceivedData(DmtpMessage message)
|
||||
{
|
||||
this.LastActiveTime = DateTime.Now;
|
||||
var byteBlock = message.BodyByteBlock;
|
||||
@@ -376,7 +444,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
case P0_Close:
|
||||
{
|
||||
this.Close(false, message.GetBodyString());
|
||||
_ = this.OnClosed(false, message.GetBodyString());
|
||||
return true;
|
||||
}
|
||||
case P1_Handshake_Request:
|
||||
@@ -391,11 +459,11 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
Metadata = waitVerify.Metadata,
|
||||
Id = waitVerify.Id,
|
||||
};
|
||||
this.OnHandshaking?.Invoke(this, args);
|
||||
await this.OnHandshaking(args).ConfigureFalseAwait();
|
||||
|
||||
if (args.Id.HasValue())
|
||||
{
|
||||
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, args.Id));
|
||||
await this.OnIdChanged(new IdChangedEventArgs(this.Id, args.Id)).ConfigureFalseAwait();
|
||||
this.Id = args.Id;
|
||||
}
|
||||
|
||||
@@ -403,24 +471,23 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
waitVerify.Id = this.Id;
|
||||
waitVerify.Status = 1;
|
||||
this.SendJsonObject(P2_Handshake_Response, waitVerify);
|
||||
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait();
|
||||
this.IsHandshaked = true;
|
||||
args.Message = "Success";
|
||||
|
||||
Task.Factory.StartNew(this.PrivateHandshaked, args);
|
||||
_ = Task.Factory.StartNew(this.PrivateOnHandshaked, args);
|
||||
}
|
||||
else//不允许连接
|
||||
{
|
||||
waitVerify.Status = 2;
|
||||
waitVerify.Message = args.Message;
|
||||
this.SendJsonObject(P2_Handshake_Response, waitVerify);
|
||||
this.Close(false, args.Message);
|
||||
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait();
|
||||
_ = this.OnClosed(false, args.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.Error(this, $"在protocol={message.ProtocolFlags}中发生错误。信息:{ex.Message}");
|
||||
this.Close(false, ex.Message);
|
||||
_ = this.OnClosed(false, ex.Message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -449,7 +516,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
var waitSetId = this.ResolveJsonObject<WaitSetId>(message.GetBodyString());
|
||||
try
|
||||
{
|
||||
this.OnResetId?.Invoke(this, waitSetId);
|
||||
await this.OnIdChanged(new IdChangedEventArgs(waitSetId.OldId, waitSetId.NewId)).ConfigureFalseAwait();
|
||||
this.Id = waitSetId.NewId;
|
||||
waitSetId.Status = 1;
|
||||
}
|
||||
@@ -458,7 +525,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
waitSetId.Status = 2;
|
||||
waitSetId.Message = ex.Message;
|
||||
}
|
||||
this.SendJsonObject(P4_ResetId_Response, waitSetId);
|
||||
await this.SendJsonObjectAsync(P4_ResetId_Response, waitSetId).ConfigureFalseAwait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -486,11 +553,12 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
if (this.AllowRoute && waitPing.Route)
|
||||
{
|
||||
if (this.TryRoute(RouteType.Ping, waitPing))
|
||||
|
||||
if (await this.TryRoute(new PackageRouterEventArgs(RouteType.Ping, waitPing)).ConfigureFalseAwait())
|
||||
{
|
||||
if (this.TryFindDmtpActor(waitPing.TargetId, out var actor))
|
||||
if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(P5_Ping_Request, byteBlock);
|
||||
await actor.SendAsync(P5_Ping_Request, byteBlock).ConfigureFalseAwait();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -508,7 +576,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
waitPing.Status = TouchSocketDmtpStatus.Success.ToValue();
|
||||
}
|
||||
waitPing.SwitchId();
|
||||
this.SendJsonObject(P6_Ping_Response, waitPing);
|
||||
await this.SendJsonObjectAsync(P6_Ping_Response, waitPing).ConfigureFalseAwait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -524,9 +592,9 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
if (this.AllowRoute && waitPing.Route)
|
||||
{
|
||||
if (this.TryFindDmtpActor(waitPing.TargetId, out var actor))
|
||||
if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(P6_Ping_Response, byteBlock);
|
||||
await actor.SendAsync(P6_Ping_Response, byteBlock).ConfigureFalseAwait();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -548,11 +616,11 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
waitCreateChannel.UnpackageRouter(byteBlock);
|
||||
if (this.AllowRoute && waitCreateChannel.Route)
|
||||
{
|
||||
if (this.TryRoute(RouteType.CreateChannel, waitCreateChannel))
|
||||
if (await this.TryRoute(new PackageRouterEventArgs(RouteType.CreateChannel, waitCreateChannel)).ConfigureFalseAwait())
|
||||
{
|
||||
if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor))
|
||||
if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(P7_CreateChannel_Request, byteBlock);
|
||||
await actor.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -593,7 +661,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
waitCreateChannel.SwitchId();
|
||||
byteBlock.Reset();
|
||||
waitCreateChannel.Package(byteBlock);
|
||||
this.Send(P8_CreateChannel_Response, byteBlock);
|
||||
await this.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -609,9 +677,9 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
waitCreateChannel.UnpackageRouter(byteBlock);
|
||||
if (this.AllowRoute && waitCreateChannel.Route)
|
||||
{
|
||||
if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor))
|
||||
if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(P8_CreateChannel_Response, byteBlock);
|
||||
await actor.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -635,9 +703,9 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
channelPackage.UnpackageRouter(byteBlock);
|
||||
if (this.AllowRoute && channelPackage.Route)
|
||||
{
|
||||
if (this.TryFindDmtpActor(channelPackage.TargetId, out var actor))
|
||||
if (await this.TryFindDmtpActor(channelPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(P9_ChannelPackage, byteBlock);
|
||||
await actor.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -648,7 +716,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
channelPackage.DataType = ChannelDataType.DisposeOrder;
|
||||
byteBlock.Reset();
|
||||
channelPackage.Package(byteBlock);
|
||||
this.Send(P9_ChannelPackage, byteBlock);
|
||||
await this.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -683,7 +751,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <inheritdoc/>
|
||||
public virtual bool Ping(string targetId, int timeout = 5000)
|
||||
{
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
|
||||
{
|
||||
return actor.Ping(timeout);
|
||||
}
|
||||
@@ -697,15 +765,15 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Task<bool> PingAsync(string targetId, int timeout = 5000)
|
||||
public virtual async Task<bool> PingAsync(string targetId, int timeout = 5000)
|
||||
{
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
return actor.PingAsync(timeout);
|
||||
return await actor.PingAsync(timeout).ConfigureFalseAwait();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.PrivatePingAsync(targetId, timeout);
|
||||
return await this.PrivatePingAsync(targetId, timeout).ConfigureFalseAwait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,7 +792,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
if (waitData.WaitResult.Status == 1)
|
||||
{
|
||||
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id));
|
||||
this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).GetFalseAwaitResult();
|
||||
this.Id = id;
|
||||
}
|
||||
else
|
||||
@@ -754,13 +822,13 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
this.SendJsonObject(P3_ResetId_Request, waitSetId);
|
||||
|
||||
switch (await waitData.WaitAsync(5000))
|
||||
switch (await waitData.WaitAsync(5000).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
if (waitData.WaitResult.Status == 1)
|
||||
{
|
||||
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id));
|
||||
await this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).ConfigureFalseAwait();
|
||||
this.Id = id;
|
||||
}
|
||||
else
|
||||
@@ -801,6 +869,17 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
this.Send(protocol, bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
private Task SendJsonObjectAsync<T>(ushort protocol, in T obj)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
var bytes = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj, typeof(T), TouchSokcetDmtpSourceGenerationContext.Default);
|
||||
#else
|
||||
var bytes = SerializeConvert.JsonSerializeToBytes(obj);
|
||||
#endif
|
||||
|
||||
return this.SendAsync(protocol, bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
private T ResolveJsonObject<T>(string json)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
@@ -836,31 +915,34 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool TryFindDmtpActor(string targetId, out DmtpActor actor)
|
||||
public virtual async Task<DmtpActor> TryFindDmtpActor(string targetId)
|
||||
{
|
||||
if (targetId == this.Id)
|
||||
{
|
||||
actor = this;
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
if (this.OnFindDmtpActor?.Invoke(targetId) is DmtpActor newActor)
|
||||
if (this.FindDmtpActor != null)
|
||||
{
|
||||
actor = newActor;
|
||||
return true;
|
||||
if (await this.FindDmtpActor.Invoke(targetId).ConfigureFalseAwait() is DmtpActor newActor)
|
||||
{
|
||||
return newActor;
|
||||
}
|
||||
}
|
||||
|
||||
actor = default;
|
||||
return false;
|
||||
return default;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool TryRoute(RouteType routerType, RouterPackage routerPackage)
|
||||
public virtual async Task<bool> TryRoute(PackageRouterEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var args = new PackageRouterEventArgs(routerType, routerPackage);
|
||||
this.OnRouting?.Invoke(this, args);
|
||||
return args.IsPermitOperation;
|
||||
if (this.Routing != null)
|
||||
{
|
||||
await this.Routing.Invoke(this, e).ConfigureFalseAwait();
|
||||
return e.IsPermitOperation;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -868,27 +950,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage)
|
||||
{
|
||||
try
|
||||
{
|
||||
var args = new PackageRouterEventArgs(routerType, routerPackage);
|
||||
this.OnRouting?.Invoke(this, args);
|
||||
routerPackage.Message = args.Message;
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrivateHandshaked(object obj)
|
||||
{
|
||||
this.OnHandshaked?.Invoke(this, (DmtpVerifyEventArgs)obj);
|
||||
}
|
||||
|
||||
private bool PrivatePing(string targetId, int timeout)
|
||||
{
|
||||
var waitPing = new WaitPing
|
||||
@@ -942,7 +1003,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
try
|
||||
{
|
||||
this.SendJsonObject(P5_Ping_Request, waitPing);
|
||||
switch (await waitData.WaitAsync(timeout))
|
||||
switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -971,7 +1032,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
#region 重写
|
||||
#region 断开
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
@@ -979,19 +1040,36 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.OnClose = null;
|
||||
this.OnRouting = null;
|
||||
this.OnFindDmtpActor = null;
|
||||
this.OnHandshaked = null;
|
||||
this.OnHandshaking = null;
|
||||
this.OnResetId = null;
|
||||
|
||||
this.Closed = null;
|
||||
this.Routing = null;
|
||||
this.FindDmtpActor = null;
|
||||
this.Handshaked = null;
|
||||
this.Handshaking = null;
|
||||
this.IdChanged = null;
|
||||
this.OutputSend = null;
|
||||
this.OnClosed(true, nameof(Dispose));
|
||||
this.WaitHandlePool.SafeDispose();
|
||||
this.Close(false, nameof(Dispose));
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public void Close(string msg)
|
||||
{
|
||||
this.OnClosed(true, msg);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool SendClose(string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.SendString(0, msg);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endregion 重写
|
||||
|
||||
#region 协议同步发送
|
||||
@@ -1005,7 +1083,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
|
||||
new ArraySegment<byte>(buffer,offset,length)
|
||||
};
|
||||
this.OutputSend?.Invoke(this, transferBytes);
|
||||
this.OutputSend.Invoke(this, transferBytes);
|
||||
this.LastActiveTime = DateTime.Now;
|
||||
}
|
||||
|
||||
@@ -1022,10 +1100,20 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <inheritdoc/>
|
||||
public virtual Task SendAsync(ushort protocol, byte[] buffer, int offset, int length)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
var transferBytes = new ArraySegment<byte>[]
|
||||
{
|
||||
this.Send(protocol, buffer, offset, length);
|
||||
});
|
||||
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
|
||||
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
|
||||
new ArraySegment<byte>(buffer,offset,length)
|
||||
};
|
||||
this.LastActiveTime = DateTime.Now;
|
||||
return this.OutputSendAsync.Invoke(this, transferBytes);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Task SendAsync(ushort protocol, ByteBlock byteBlock)
|
||||
{
|
||||
return this.SendAsync(protocol, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
#endregion 协议异步发送
|
||||
@@ -1059,7 +1147,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
|
||||
}
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
|
||||
{
|
||||
return actor.CreateChannel(id, metadata);
|
||||
}
|
||||
@@ -1077,7 +1165,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
|
||||
}
|
||||
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
|
||||
{
|
||||
return actor.CreateChannel(metadata);
|
||||
}
|
||||
@@ -1100,37 +1188,37 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default)
|
||||
public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(targetId))
|
||||
{
|
||||
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
|
||||
}
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
return actor.CreateChannelAsync(id, metadata);
|
||||
return await actor.CreateChannelAsync(id, metadata).ConfigureFalseAwait();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.PrivateCreateChannelAsync(targetId, false, id, metadata);
|
||||
return await this.PrivateCreateChannelAsync(targetId, false, id, metadata).ConfigureFalseAwait();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default)
|
||||
public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(targetId))
|
||||
{
|
||||
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
|
||||
}
|
||||
|
||||
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
|
||||
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
return actor.CreateChannelAsync(metadata);
|
||||
return await actor.CreateChannelAsync(metadata).ConfigureFalseAwait();
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.PrivateCreateChannelAsync(targetId, true, 0, metadata);
|
||||
return await this.PrivateCreateChannelAsync(targetId, true, 0, metadata).ConfigureFalseAwait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,9 +1296,14 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
var channel = new InternalChannel(this, targetId, result.Metadata);
|
||||
channel.SetId(result.ChannelId);
|
||||
channel.SetUsing();
|
||||
return this.m_userChannels.TryAdd(result.ChannelId, channel)
|
||||
? (IDmtpChannel)channel
|
||||
: throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
|
||||
if (this.m_userChannels.TryAdd(result.ChannelId, channel))
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
|
||||
}
|
||||
}
|
||||
case TouchSocketDmtpStatus.ClientNotFind:
|
||||
{
|
||||
@@ -1269,8 +1362,8 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
try
|
||||
{
|
||||
waitCreateChannel.Package(byteBlock);
|
||||
this.Send(P7_CreateChannel_Request, byteBlock);
|
||||
switch (await waitData.WaitAsync(10 * 1000))
|
||||
await this.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait();
|
||||
switch (await waitData.WaitAsync(10 * 1000).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -1282,9 +1375,14 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
var channel = new InternalChannel(this, targetId, result.Metadata);
|
||||
channel.SetId(result.ChannelId);
|
||||
channel.SetUsing();
|
||||
return this.m_userChannels.TryAdd(result.ChannelId, channel)
|
||||
? (IDmtpChannel)channel
|
||||
: throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
|
||||
if (this.m_userChannels.TryAdd(result.ChannelId, channel))
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
|
||||
}
|
||||
}
|
||||
case TouchSocketDmtpStatus.ClientNotFind:
|
||||
{
|
||||
@@ -1333,7 +1431,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
channel.SetId(id);
|
||||
if (this.m_userChannels.TryAdd(id, channel))
|
||||
{
|
||||
Task.Factory.StartNew(this.ThisRequestCreateChannel, new CreateChannelEventArgs(id, metadata));
|
||||
Task.Factory.StartNew(this.PrivateOnCreatedChannel, new CreateChannelEventArgs(id, metadata));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -1344,16 +1442,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
private void ThisRequestCreateChannel(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.OnCreateChannel?.Invoke(this, (CreateChannelEventArgs)state);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IDmtpChannel
|
||||
}
|
||||
|
@@ -152,9 +152,8 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
/// <param name="sendClose">是否发送close报文</param>
|
||||
/// <param name="message">传递消息</param>
|
||||
void Close(bool sendClose, string message);
|
||||
void Close(string message);
|
||||
|
||||
/// <summary>
|
||||
/// 向当前对点发送一个Ping报文,并且等待回应。
|
||||
@@ -226,6 +225,14 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <param name="length"></param>
|
||||
Task SendAsync(ushort protocol, byte[] buffer, int offset, int length);
|
||||
|
||||
/// <summary>
|
||||
/// 异步发送字节块
|
||||
/// </summary>
|
||||
/// <param name="protocol"></param>
|
||||
/// <param name="byteBlock"></param>
|
||||
/// <returns></returns>
|
||||
Task SendAsync(ushort protocol, ByteBlock byteBlock);
|
||||
|
||||
/// <summary>
|
||||
/// 以Fast序列化,发送小(64K)对象。接收方需要使用ReadObject读取对象。
|
||||
/// </summary>
|
||||
@@ -260,25 +267,20 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 尝试获取指定Id的DmtpActor。一般此方法仅在Service下有效。
|
||||
/// </summary>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="actor"></param>
|
||||
/// <returns></returns>
|
||||
bool TryFindDmtpActor(string targetId, out DmtpActor actor);
|
||||
Task<DmtpActor> TryFindDmtpActor(string targetId);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试请求路由,触发路由相关插件。
|
||||
/// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgPermitEventArgs.Message"/>中传递消息。
|
||||
/// </summary>
|
||||
/// <param name="routerType"></param>
|
||||
/// <param name="routerPackage"></param>
|
||||
/// <returns></returns>
|
||||
bool TryRoute(RouteType routerType, RouterPackage routerPackage);
|
||||
Task<bool> TryRoute(PackageRouterEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgRouterPackage.Message"/>中传递消息。
|
||||
/// 发送Close请求
|
||||
/// </summary>
|
||||
/// <param name="routerType"></param>
|
||||
/// <param name="routerPackage"></param>
|
||||
/// <returns></returns>
|
||||
bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage);
|
||||
/// <param name="msg"></param>
|
||||
bool SendClose(string msg);
|
||||
|
||||
#endregion 方法
|
||||
}
|
||||
|
@@ -17,17 +17,22 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// </summary>
|
||||
public class TcpDmtpAdapter : CustomFixedHeaderByteBlockDataHandlingAdapter<DmtpMessage>
|
||||
{
|
||||
private SpinLock m_locker = new SpinLock();
|
||||
private readonly SemaphoreSlim m_locker = new SemaphoreSlim(1, 1);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanSendRequestInfo => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanSplicingSend => false;
|
||||
public override bool CanSplicingSend => true;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int HeaderLength => 6;
|
||||
|
||||
/// <summary>
|
||||
/// 最大拼接
|
||||
/// </summary>
|
||||
public const int MaxSplicing = 1024 * 64;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override DmtpMessage GetInstance()
|
||||
{
|
||||
@@ -40,6 +45,25 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
request.SafeDispose();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task PreviewSendAsync(IRequestInfo requestInfo)
|
||||
{
|
||||
if (!(requestInfo is DmtpMessage message))
|
||||
{
|
||||
throw new Exception($"无法将{nameof(requestInfo)}转换为{nameof(DmtpMessage)}");
|
||||
}
|
||||
if (message.BodyByteBlock != null && message.BodyByteBlock.Length > this.MaxPackageSize)
|
||||
{
|
||||
throw new Exception("发送的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}");
|
||||
}
|
||||
using (var byteBlock = new ByteBlock(message.GetLength()))
|
||||
{
|
||||
message.Build(byteBlock);
|
||||
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void PreviewSend(IRequestInfo requestInfo)
|
||||
{
|
||||
@@ -58,6 +82,54 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
if (transferBytes.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
length += item.Count;
|
||||
}
|
||||
|
||||
if (length > this.MaxPackageSize)
|
||||
{
|
||||
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
|
||||
}
|
||||
if (length > this.MaxPackageSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
await this.m_locker.WaitAsync();
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
await this.GoSendAsync(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_locker.Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var byteBlock = new ByteBlock(length))
|
||||
{
|
||||
foreach (var item in transferBytes)
|
||||
{
|
||||
byteBlock.Write(item.Array, item.Offset, item.Count);
|
||||
}
|
||||
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void PreviewSend(IList<ArraySegment<byte>> transferBytes)
|
||||
{
|
||||
@@ -77,20 +149,31 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
|
||||
}
|
||||
|
||||
var lockTaken = false;
|
||||
try
|
||||
if (length > this.MaxPackageSize)
|
||||
{
|
||||
this.m_locker.Enter(ref lockTaken);
|
||||
foreach (var item in transferBytes)
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -70,7 +70,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <summary>
|
||||
/// 最大传输速度。
|
||||
/// </summary>
|
||||
public long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
|
||||
public virtual long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
|
||||
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
|
@@ -33,19 +33,19 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
#region 字段
|
||||
|
||||
private bool m_allowRoute;
|
||||
private Func<string, IDmtpActor> m_findDmtpActor;
|
||||
private DmtpActor m_smtpActor;
|
||||
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
|
||||
private DmtpActor m_dmtpActor;
|
||||
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
|
||||
#endregion 字段
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.Id"/>
|
||||
public string Id => this.DmtpActor.Id;
|
||||
public string Id => this.m_dmtpActor.Id;
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
|
||||
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
|
||||
public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
|
||||
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
|
||||
|
||||
#region 连接
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
if (response.StatusCode == 101)
|
||||
{
|
||||
this.SwitchProtocolToDmtp();
|
||||
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
|
||||
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
|
||||
return this;
|
||||
@@ -114,7 +114,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
if (response.StatusCode == 101)
|
||||
{
|
||||
this.SwitchProtocolToDmtp();
|
||||
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
|
||||
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
|
||||
return this;
|
||||
@@ -156,7 +156,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
if (response.StatusCode == 101)
|
||||
{
|
||||
this.SwitchProtocolToDmtp();
|
||||
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
|
||||
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
|
||||
return this;
|
||||
@@ -184,7 +184,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
if (!this.Online)
|
||||
{
|
||||
await base.ConnectAsync(timeout, token);
|
||||
await base.ConnectAsync(timeout);
|
||||
}
|
||||
|
||||
var request = new HttpRequest()
|
||||
@@ -197,7 +197,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
if (response.StatusCode == 101)
|
||||
{
|
||||
this.SwitchProtocolToDmtp();
|
||||
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
|
||||
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
|
||||
return this;
|
||||
@@ -215,19 +215,47 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
#endregion 连接
|
||||
|
||||
#region 断开
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.DmtpActor.SafeDispose();
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.SafeDispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送<see cref="IDmtpActor"/>关闭消息。
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public override void Close(string msg = "")
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor.SendClose(msg);
|
||||
this.m_dmtpActor.Close(msg);
|
||||
}
|
||||
base.Close(msg);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
this.m_dmtpActor?.Close(e.Message);
|
||||
await base.OnDisconnected(e);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
|
||||
{
|
||||
if (!this.m_smtpActor.InputReceivedData(message))
|
||||
if (!await this.m_dmtpActor.InputReceivedData(message))
|
||||
{
|
||||
if (this.PluginsManager.Enable)
|
||||
{
|
||||
@@ -250,25 +278,19 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
await base.OnDisconnected(e);
|
||||
this.DmtpActor.Close(false, e.Message);
|
||||
}
|
||||
|
||||
#region ResetId
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
|
||||
public void ResetId(string id)
|
||||
{
|
||||
this.m_smtpActor.ResetId(id);
|
||||
this.m_dmtpActor.ResetId(id);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
|
||||
public Task ResetIdAsync(string newId)
|
||||
{
|
||||
return this.m_smtpActor.ResetIdAsync(newId);
|
||||
return this.m_dmtpActor.ResetIdAsync(newId);
|
||||
}
|
||||
|
||||
#endregion ResetId
|
||||
@@ -277,72 +299,47 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
this.Protocol = DmtpUtility.DmtpProtocol;
|
||||
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
|
||||
this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute)
|
||||
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
|
||||
{
|
||||
OutputSend = DmtpActorSend,
|
||||
OnRouting = OnDmtpActorRouting,
|
||||
OnHandshaking = this.OnDmtpActorHandshaking,
|
||||
OnHandshaked = OnDmtpActorHandshaked,
|
||||
OnClose = OnDmtpActorClose,
|
||||
OnCreateChannel = this.OnDmtpActorCreateChannel,
|
||||
OutputSend = this.DmtpActorSend,
|
||||
OutputSendAsync = this.DmtpActorSendAsync,
|
||||
Routing = this.OnDmtpActorRouting,
|
||||
Handshaking = this.OnDmtpActorHandshaking,
|
||||
Handshaked = this.OnDmtpActorHandshaked,
|
||||
Closed = this.OnDmtpActorClose,
|
||||
CreatedChannel = this.OnDmtpActorCreateChannel,
|
||||
Logger = this.Logger,
|
||||
Client = this,
|
||||
OnFindDmtpActor = this.m_findDmtpActor
|
||||
FindDmtpActor = this.m_findDmtpActor
|
||||
};
|
||||
}
|
||||
|
||||
#region 内部委托绑定
|
||||
|
||||
private void OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
private Task OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
{
|
||||
base.Close(msg);
|
||||
base.BreakOut(false, msg);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.OnCreateChannel(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
return this.OnCreateChannel(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaked(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnHandshaked(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaking(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
return this.OnHandshaking(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
{
|
||||
this.OnRouting(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnRouting(e);
|
||||
}
|
||||
|
||||
private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
@@ -350,6 +347,11 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
base.Send(transferBytes);
|
||||
}
|
||||
|
||||
private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
return base.SendAsync(transferBytes);
|
||||
}
|
||||
|
||||
#endregion 内部委托绑定
|
||||
|
||||
#region 事件触发
|
||||
@@ -358,32 +360,53 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 当创建通道
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
|
||||
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即将握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e">参数</param>
|
||||
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当需要转发路由包时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnRouting(PackageRouterEventArgs e)
|
||||
protected virtual async Task OnRouting(PackageRouterEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
|
||||
}
|
||||
|
||||
#endregion 事件触发
|
||||
|
@@ -46,7 +46,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
#region 字段
|
||||
|
||||
private bool m_allowRoute;
|
||||
private Func<string, IDmtpActor> m_findDmtpActor;
|
||||
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
@@ -68,17 +68,28 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
await base.OnConnected(socketClient, e);
|
||||
}
|
||||
|
||||
private IDmtpActor OnServiceFindDmtpActor(string id)
|
||||
{
|
||||
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
|
||||
}
|
||||
|
||||
private DmtpActor PrivateOnRpcActorInit()
|
||||
{
|
||||
return new SealedDmtpActor(this.m_allowRoute)
|
||||
{
|
||||
OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null
|
||||
FindDmtpActor = this.FindDmtpActor
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<IDmtpActor> FindDmtpActor(string id)
|
||||
{
|
||||
if (this.m_allowRoute)
|
||||
{
|
||||
if (this.m_findDmtpActor != null)
|
||||
{
|
||||
return await this.m_findDmtpActor.Invoke(id);
|
||||
}
|
||||
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -31,14 +31,14 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
public class HttpDmtpSocketClient : HttpSocketClient, IHttpDmtpSocketClient
|
||||
{
|
||||
internal Func<DmtpActor> m_internalOnRpcActorInit;
|
||||
private DmtpActor m_smtpActor;
|
||||
private DmtpActor m_dmtpActor;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证超时时间,默认为3000ms
|
||||
/// </summary>
|
||||
@@ -49,97 +49,67 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// </summary>
|
||||
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty);
|
||||
|
||||
#region 断开
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Close(string msg = "")
|
||||
{
|
||||
if (this.m_smtpActor == null)
|
||||
if (this.m_dmtpActor != null)
|
||||
{
|
||||
base.Close(msg);
|
||||
return;
|
||||
this.m_dmtpActor.SendClose(msg);
|
||||
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>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.DmtpActor?.SafeDispose();
|
||||
this.m_dmtpActor?.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
///// <inheritdoc/>
|
||||
//protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
//{
|
||||
// if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message)
|
||||
// {
|
||||
// if (!this.m_smtpActor.InputReceivedData(message))
|
||||
// {
|
||||
// if (this.PluginsManager.Enable)
|
||||
// {
|
||||
// this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return base.HandleReceivedData(byteBlock, requestInfo);
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
|
||||
{
|
||||
if (!this.m_smtpActor.InputReceivedData(message))
|
||||
{
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
}
|
||||
}
|
||||
await base.ReceivedData(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
this.DmtpActor?.Close(false, e.Message);
|
||||
this.m_dmtpActor?.Close(e.Message);
|
||||
await base.OnDisconnected(e);
|
||||
}
|
||||
|
||||
#endregion 断开
|
||||
|
||||
#region ResetId
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.ResetId(string)"/>
|
||||
public override void ResetId(string newId)
|
||||
{
|
||||
if (this.m_dmtpActor == null)
|
||||
{
|
||||
base.ResetId(newId);
|
||||
return;
|
||||
}
|
||||
this.m_dmtpActor.ResetId(newId);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
|
||||
public async Task ResetIdAsync(string newId)
|
||||
{
|
||||
if (this.m_dmtpActor == null)
|
||||
{
|
||||
base.ResetId(newId);
|
||||
return;
|
||||
}
|
||||
await this.m_dmtpActor.ResetIdAsync(newId);
|
||||
}
|
||||
|
||||
#endregion ResetId
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
@@ -158,66 +128,73 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
await base.OnReceivedHttpRequest(request);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
|
||||
{
|
||||
if (!await this.m_dmtpActor.InputReceivedData(message))
|
||||
{
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
}
|
||||
}
|
||||
await base.ReceivedData(e);
|
||||
}
|
||||
|
||||
private Task OnDmtpIdChanged(DmtpActor actor, IdChangedEventArgs e)
|
||||
{
|
||||
this.DirectResetId(e.NewId);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void SetRpcActor(DmtpActor actor)
|
||||
{
|
||||
actor.Id = this.Id;
|
||||
actor.OnResetId = this.ThisOnResetId;
|
||||
actor.IdChanged = this.OnDmtpIdChanged;
|
||||
actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync;
|
||||
actor.OutputSend = this.ThisDmtpActorOutputSend;
|
||||
actor.Client = this;
|
||||
actor.OnClose = this.OnDmtpActorClose;
|
||||
actor.OnRouting = this.OnDmtpActorRouting;
|
||||
actor.OnHandshaked = this.OnDmtpActorHandshaked;
|
||||
actor.OnHandshaking = this.OnDmtpActorHandshaking;
|
||||
actor.OnCreateChannel = this.OnDmtpActorCreateChannel;
|
||||
actor.Closed = this.OnDmtpActorClose;
|
||||
actor.Routing = this.OnDmtpActorRouting;
|
||||
actor.Handshaked = this.OnDmtpActorHandshaked;
|
||||
actor.Handshaking = this.OnDmtpActorHandshaking;
|
||||
actor.CreatedChannel = this.OnDmtpActorCreatedChannel;
|
||||
actor.Logger = this.Logger;
|
||||
this.m_smtpActor = actor;
|
||||
this.m_dmtpActor = actor;
|
||||
|
||||
this.Protocol = DmtpUtility.DmtpProtocol;
|
||||
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
|
||||
}
|
||||
|
||||
private void ThisOnResetId(DmtpActor actor, WaitSetId waitSetId)
|
||||
{
|
||||
this.DirectResetId(waitSetId.NewId);
|
||||
}
|
||||
|
||||
private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
base.Send(transferBytes);
|
||||
}
|
||||
|
||||
private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
return base.SendAsync(transferBytes);
|
||||
}
|
||||
|
||||
#region 内部委托绑定
|
||||
|
||||
private void OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
private Task OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
{
|
||||
base.Close(msg);
|
||||
base.BreakOut(false, msg);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.OnCreateChannel(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
return this.OnCreatedChannel(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaked(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnHandshaked(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Token == this.VerifyToken)
|
||||
{
|
||||
@@ -228,25 +205,12 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
e.Message = "Token不受理";
|
||||
}
|
||||
|
||||
this.OnHandshaking(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
return this.OnHandshaking(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
{
|
||||
this.OnRouting(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnRouting(e);
|
||||
}
|
||||
|
||||
#endregion 内部委托绑定
|
||||
@@ -257,32 +221,53 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 当创建通道
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
|
||||
protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在验证Token时
|
||||
/// </summary>
|
||||
/// <param name="e">参数</param>
|
||||
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在需要转发路由包时。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnRouting(PackageRouterEventArgs e)
|
||||
protected virtual async Task OnRouting(PackageRouterEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
|
||||
}
|
||||
|
||||
#endregion 事件
|
||||
|
@@ -10,6 +10,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
/// <summary>
|
||||
|
@@ -39,22 +39,24 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
|
||||
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.Id"/>
|
||||
public string Id => this.DmtpActor.Id;
|
||||
public string Id => this.m_dmtpActor.Id;
|
||||
|
||||
#region 字段
|
||||
|
||||
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
|
||||
private bool m_allowRoute;
|
||||
private Func<string, IDmtpActor> m_findDmtpActor;
|
||||
private SealedDmtpActor m_smtpActor;
|
||||
private SealedDmtpActor m_dmtpActor;
|
||||
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
|
||||
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
|
||||
public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked;
|
||||
|
||||
#region 断开
|
||||
|
||||
/// <summary>
|
||||
/// 发送<see cref="IDmtpActor"/>关闭消息。
|
||||
@@ -63,10 +65,33 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <returns></returns>
|
||||
public override void Close(string msg = "")
|
||||
{
|
||||
this.DmtpActor.Close(true, msg);
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.SendClose(msg);
|
||||
this.m_dmtpActor?.Close(msg);
|
||||
}
|
||||
base.Close(msg);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.SafeDispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
this.m_dmtpActor?.Close(e.Message);
|
||||
await base.OnDisconnected(e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
#endregion 断开
|
||||
|
||||
#region 连接
|
||||
|
||||
/// <summary>
|
||||
@@ -87,7 +112,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
base.Connect(timeout);
|
||||
}
|
||||
|
||||
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
|
||||
return this;
|
||||
}
|
||||
@@ -107,7 +132,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
base.Connect(timeout);
|
||||
}
|
||||
|
||||
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
|
||||
return this;
|
||||
}
|
||||
@@ -129,11 +154,10 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
if (!this.Online)
|
||||
{
|
||||
await base.ConnectAsync(timeout);
|
||||
await base.ConnectAsync(timeout).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
|
||||
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None).ConfigureFalseAwait();
|
||||
return this;
|
||||
}
|
||||
finally
|
||||
@@ -154,11 +178,10 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
if (!this.Online)
|
||||
{
|
||||
await base.ConnectAsync(timeout, token);
|
||||
await base.ConnectAsync(timeout).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
|
||||
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token).ConfigureFalseAwait();
|
||||
return this;
|
||||
}
|
||||
finally
|
||||
@@ -174,13 +197,13 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
|
||||
public void ResetId(string id)
|
||||
{
|
||||
this.m_smtpActor.ResetId(id);
|
||||
this.m_dmtpActor.ResetId(id);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
|
||||
public Task ResetIdAsync(string newId)
|
||||
{
|
||||
return this.m_smtpActor.ResetIdAsync(newId);
|
||||
return this.m_dmtpActor.ResetIdAsync(newId);
|
||||
}
|
||||
|
||||
#endregion ResetId
|
||||
@@ -229,13 +252,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
#endregion 发送
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.DmtpActor.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void LoadConfig(TouchSocketConfig config)
|
||||
{
|
||||
@@ -246,37 +262,31 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
this.m_allowRoute = true;
|
||||
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
|
||||
}
|
||||
this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute)
|
||||
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
|
||||
{
|
||||
OutputSend = this.DmtpActorSend,
|
||||
OnRouting = this.OnDmtpActorRouting,
|
||||
OnHandshaking = this.OnDmtpActorHandshaking,
|
||||
OnHandshaked = this.OnDmtpActorHandshaked,
|
||||
OnClose = this.OnDmtpActorClose,
|
||||
OutputSendAsync = this.DmtpActorSendAsync,
|
||||
Routing = this.OnDmtpActorRouting,
|
||||
Handshaking = this.OnDmtpActorHandshaking,
|
||||
Handshaked = this.OnDmtpActorHandshaked,
|
||||
Closed = this.OnDmtpActorClose,
|
||||
Logger = this.Logger,
|
||||
Client = this,
|
||||
OnFindDmtpActor = this.m_findDmtpActor,
|
||||
OnCreateChannel = this.OnDmtpActorCreateChannel
|
||||
FindDmtpActor = this.m_findDmtpActor,
|
||||
CreatedChannel = this.OnDmtpActorCreateChannel
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
await base.OnDisconnected(e);
|
||||
this.DmtpActor.Close(false, e.Message);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
var message = (DmtpMessage)e.RequestInfo;
|
||||
if (!this.m_smtpActor.InputReceivedData(message))
|
||||
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
|
||||
{
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
await base.ReceivedData(e);
|
||||
await base.ReceivedData(e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
#region 内部委托绑定
|
||||
@@ -286,52 +296,35 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
base.Send(transferBytes);
|
||||
}
|
||||
|
||||
private void OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
base.Close(msg);
|
||||
return base.SendAsync(transferBytes);
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
{
|
||||
this.OnCreateChannel(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
this.BreakOut(false, msg);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.OnHandshaked(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnCreatedChannel(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaking(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
return this.OnHandshaked(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.OnRouting(e);
|
||||
return this.OnHandshaking(e);
|
||||
}
|
||||
|
||||
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
{
|
||||
return this.OnRouting(e);
|
||||
}
|
||||
|
||||
#endregion 内部委托绑定
|
||||
@@ -342,32 +335,53 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 当创建通道
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
|
||||
protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即将握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e">参数</param>
|
||||
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当需要转发路由包时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnRouting(PackageRouterEventArgs e)
|
||||
protected virtual async Task OnRouting(PackageRouterEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
#endregion 事件触发
|
||||
|
@@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
#region 字段
|
||||
|
||||
private bool m_allowRoute;
|
||||
private Func<string, IDmtpActor> m_findDmtpActor;
|
||||
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
@@ -73,14 +73,25 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
socketClient.SetDmtpActor(new SealedDmtpActor(this.m_allowRoute)
|
||||
{
|
||||
Id = e.Id,
|
||||
OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null
|
||||
FindDmtpActor = this.FindDmtpActor
|
||||
});
|
||||
await base.OnConnecting(socketClient, e);
|
||||
}
|
||||
|
||||
private IDmtpActor OnServiceFindDmtpActor(string id)
|
||||
private async Task<IDmtpActor> FindDmtpActor(string id)
|
||||
{
|
||||
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>
|
||||
public partial class TcpDmtpSocketClient : SocketClient, ITcpDmtpSocketClient
|
||||
{
|
||||
private DmtpActor m_smtpActor;
|
||||
private DmtpActor m_dmtpActor;
|
||||
|
||||
/// <summary>
|
||||
/// TcpDmtpSocketClient
|
||||
@@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
|
||||
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
|
||||
|
||||
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
|
||||
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
|
||||
@@ -58,36 +58,23 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
#region 内部委托绑定
|
||||
|
||||
private void OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
private Task OnDmtpActorClose(DmtpActor actor, string msg)
|
||||
{
|
||||
base.Close(msg);
|
||||
base.BreakOut(false, msg);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.OnCreateChannel(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
return this.OnCreateChannel(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaked(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnHandshaked(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private async Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Token == this.VerifyToken)
|
||||
{
|
||||
@@ -98,25 +85,12 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
e.Message = "Token不受理";
|
||||
}
|
||||
|
||||
this.OnHandshaking(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
await this.OnHandshaking(e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
{
|
||||
this.OnRouting(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnRouting(e);
|
||||
}
|
||||
|
||||
#endregion 内部委托绑定
|
||||
@@ -127,99 +101,147 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 当创建通道
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
|
||||
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在验证Token时
|
||||
/// </summary>
|
||||
/// <param name="e">参数</param>
|
||||
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在需要转发路由包时。
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnRouting(PackageRouterEventArgs e)
|
||||
protected virtual async Task OnRouting(PackageRouterEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
|
||||
}
|
||||
|
||||
#endregion 事件
|
||||
|
||||
/// <inheritdoc/>
|
||||
#region 断开
|
||||
|
||||
/// <summary>
|
||||
/// 发送<see cref="IDmtpActor"/>关闭消息。
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public override void Close(string msg = "")
|
||||
{
|
||||
this.m_smtpActor.Close(true, msg);
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.SendClose(msg);
|
||||
this.m_dmtpActor?.Close(msg);
|
||||
}
|
||||
base.Close(msg);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.SafeDispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
this.m_dmtpActor?.Close(e.Message);
|
||||
}
|
||||
await base.OnDisconnected(e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
#endregion 断开
|
||||
|
||||
#region ResetId
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
|
||||
public override void ResetId(string id)
|
||||
{
|
||||
this.m_smtpActor.ResetId(id);
|
||||
this.m_dmtpActor.ResetId(id);
|
||||
}
|
||||
|
||||
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
|
||||
public Task ResetIdAsync(string newId)
|
||||
{
|
||||
return this.m_smtpActor.ResetIdAsync(newId);
|
||||
return this.m_dmtpActor.ResetIdAsync(newId);
|
||||
}
|
||||
|
||||
#endregion ResetId
|
||||
|
||||
internal void SetDmtpActor(DmtpActor actor)
|
||||
{
|
||||
actor.OnResetId = this.ThisOnResetId;
|
||||
actor.IdChanged = this.ThisOnResetId;
|
||||
actor.OutputSend = this.ThisDmtpActorOutputSend;
|
||||
actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync;
|
||||
actor.Client = this;
|
||||
actor.OnClose = this.OnDmtpActorClose;
|
||||
actor.OnRouting = this.OnDmtpActorRouting;
|
||||
actor.OnHandshaked = this.OnDmtpActorHandshaked;
|
||||
actor.OnHandshaking = this.OnDmtpActorHandshaking;
|
||||
actor.OnCreateChannel = this.OnDmtpActorCreateChannel;
|
||||
actor.Closed = this.OnDmtpActorClose;
|
||||
actor.Routing = this.OnDmtpActorRouting;
|
||||
actor.Handshaked = this.OnDmtpActorHandshaked;
|
||||
actor.Handshaking = this.OnDmtpActorHandshaking;
|
||||
actor.CreatedChannel = this.OnDmtpActorCreateChannel;
|
||||
actor.Logger = this.Logger;
|
||||
this.m_smtpActor = actor;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
this.DmtpActor.SafeDispose();
|
||||
base.Dispose(disposing);
|
||||
this.m_dmtpActor = actor;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task ReceivedData(ReceivedDataEventArgs e)
|
||||
{
|
||||
var message = (DmtpMessage)e.RequestInfo;
|
||||
if (!this.m_smtpActor.InputReceivedData(message))
|
||||
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
|
||||
{
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
|
||||
}
|
||||
await base.ReceivedData(e);
|
||||
await base.ReceivedData(e).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnConnected(ConnectedEventArgs e)
|
||||
{
|
||||
this.m_smtpActor.Id = this.Id;
|
||||
await base.OnConnected(e);
|
||||
this.m_dmtpActor.Id = this.Id;
|
||||
await base.OnConnected(e).ConfigureFalseAwait();
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(this.VerifyTimeout);
|
||||
await Task.Delay(this.VerifyTimeout).ConfigureFalseAwait();
|
||||
if (!this.IsHandshaked)
|
||||
{
|
||||
this.TryShutdown();
|
||||
@@ -228,21 +250,20 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OnDisconnected(DisconnectEventArgs e)
|
||||
{
|
||||
this.DmtpActor.Close(false, e.Message);
|
||||
await base.OnDisconnected(e);
|
||||
}
|
||||
|
||||
private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
base.Send(transferBytes);
|
||||
}
|
||||
|
||||
private void ThisOnResetId(DmtpActor rpcActor, WaitSetId waitSetId)
|
||||
private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
this.DirectResetId(waitSetId.NewId);
|
||||
return base.SendAsync(transferBytes);
|
||||
}
|
||||
|
||||
private Task ThisOnResetId(DmtpActor rpcActor, IdChangedEventArgs e)
|
||||
{
|
||||
this.DirectResetId(e.NewId);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
#region 发送
|
||||
|
@@ -84,7 +84,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
|
||||
var message = DmtpMessage.CreateFrom(e.ByteBlock);
|
||||
if (!client.InputReceivedData(message))
|
||||
if (!await client.InputReceivedData(message))
|
||||
{
|
||||
if (this.PluginsManager.Enable)
|
||||
{
|
||||
|
@@ -45,16 +45,17 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
{
|
||||
this.Id = endPoint.ToString();
|
||||
this.OutputSend = this.RpcActorSend;
|
||||
this.OnCreateChannel = this.OnDmtpActorCreateChannel;
|
||||
this.OutputSendAsync = this.RpcActorSendAsync;
|
||||
this.CreatedChannel = this.OnDmtpActorCreatedChannel;
|
||||
this.m_udpSession = udpSession;
|
||||
this.m_endPoint = endPoint;
|
||||
this.Logger = logger;
|
||||
this.Client = this;
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.pluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
return this.pluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
}
|
||||
|
||||
public bool Created(IPluginsManager pluginsManager)
|
||||
@@ -117,5 +118,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
{
|
||||
this.m_udpSession.Send(this.m_endPoint, transferBytes);
|
||||
}
|
||||
|
||||
private Task RpcActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
return this.m_udpSession.SendAsync(this.m_endPoint, transferBytes);
|
||||
}
|
||||
}
|
||||
}
|
@@ -50,15 +50,16 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
#region 字段
|
||||
|
||||
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
|
||||
private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1);
|
||||
private readonly SemaphoreSlim m_semaphoreForSend = new SemaphoreSlim(1, 1);
|
||||
private ClientWebSocket m_client;
|
||||
private SealedDmtpActor m_dmtpActor;
|
||||
private Func<string, IDmtpActor> m_findDmtpActor;
|
||||
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
|
||||
private int m_receiveBufferSize = 1024 * 10;
|
||||
private ValueCounter m_receiveCounter;
|
||||
private int m_sendBufferSize = 1024 * 10;
|
||||
private ValueCounter m_sendCounter;
|
||||
private TcpDmtpAdapter m_smtpAdapter;
|
||||
private TcpDmtpAdapter m_dmtpAdapter;
|
||||
|
||||
#endregion 字段
|
||||
|
||||
@@ -115,56 +116,15 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <returns></returns>
|
||||
public void Close(string msg = "")
|
||||
{
|
||||
this.DmtpActor.Close(true, msg);
|
||||
this.m_dmtpActor.SendClose(msg);
|
||||
this.m_dmtpActor.Close(msg);
|
||||
this.PrivateClose(msg);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task ConnectAsync(int timeout = 5000)
|
||||
public Task ConnectAsync(int timeout = 5000)
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.m_semaphore.WaitAsync();
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.m_client == null || this.m_client.State != WebSocketState.Open)
|
||||
{
|
||||
this.m_client.SafeDispose();
|
||||
this.m_client = new ClientWebSocket();
|
||||
await this.m_client.ConnectAsync(this.RemoteIPHost, default);
|
||||
|
||||
this.m_dmtpActor = new SealedDmtpActor(false)
|
||||
{
|
||||
OutputSend = this.OnDmtpActorSend,
|
||||
OnRouting = this.OnDmtpActorRouting,
|
||||
OnHandshaking = this.OnDmtpActorHandshaking,
|
||||
OnHandshaked = this.OnDmtpActorHandshaked,
|
||||
OnClose = this.OnDmtpActorClose,
|
||||
Logger = this.Logger,
|
||||
Client = this,
|
||||
OnFindDmtpActor = this.m_findDmtpActor,
|
||||
OnCreateChannel = this.OnDmtpActorCreateChannel
|
||||
};
|
||||
|
||||
this.m_smtpAdapter = new TcpDmtpAdapter()
|
||||
{
|
||||
ReceivedCallBack = this.PrivateHandleReceivedData
|
||||
};
|
||||
_ = this.BeginReceive();
|
||||
}
|
||||
|
||||
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
|
||||
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
|
||||
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
|
||||
this.IsHandshaked = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
}
|
||||
return this.ConnectAsync(CancellationToken.None, timeout);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -172,7 +132,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.m_semaphore.WaitAsync();
|
||||
await this.m_semaphoreForConnect.WaitAsync();
|
||||
if (this.IsHandshaked)
|
||||
{
|
||||
return;
|
||||
@@ -187,17 +147,18 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
this.m_dmtpActor = new SealedDmtpActor(false)
|
||||
{
|
||||
OutputSend = this.OnDmtpActorSend,
|
||||
OnRouting = this.OnDmtpActorRouting,
|
||||
OnHandshaking = this.OnDmtpActorHandshaking,
|
||||
OnHandshaked = this.OnDmtpActorHandshaked,
|
||||
OnClose = this.OnDmtpActorClose,
|
||||
OutputSendAsync = this.OnDmtpActorSendAsync,
|
||||
Routing = this.OnDmtpActorRouting,
|
||||
Handshaking = this.OnDmtpActorHandshaking,
|
||||
Handshaked = this.OnDmtpActorHandshaked,
|
||||
Closed = this.OnDmtpActorClose,
|
||||
Logger = this.Logger,
|
||||
Client = this,
|
||||
OnFindDmtpActor = this.m_findDmtpActor,
|
||||
OnCreateChannel = this.OnDmtpActorCreateChannel
|
||||
};
|
||||
FindDmtpActor = this.m_findDmtpActor,
|
||||
CreatedChannel = this.OnDmtpActorCreateChannel
|
||||
}; ;
|
||||
|
||||
this.m_smtpAdapter = new TcpDmtpAdapter()
|
||||
this.m_dmtpAdapter = new TcpDmtpAdapter()
|
||||
{
|
||||
ReceivedCallBack = this.PrivateHandleReceivedData
|
||||
};
|
||||
@@ -211,7 +172,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
this.m_semaphoreForConnect.Release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +276,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
byteBlock.SetLength(result.Count);
|
||||
this.m_receiveCounter.Increment(result.Count);
|
||||
|
||||
this.m_smtpAdapter.ReceivedInput(byteBlock);
|
||||
this.m_dmtpAdapter.ReceivedInput(byteBlock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,7 +298,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
this.m_client.CloseAsync(WebSocketCloseStatus.NormalClosure, msg, CancellationToken.None);
|
||||
this.m_client.SafeDispose();
|
||||
this.DmtpActor.SafeDispose();
|
||||
this.m_smtpAdapter.SafeDispose();
|
||||
this.m_dmtpAdapter.SafeDispose();
|
||||
this.OnDisconnected(new DisconnectEventArgs(manual, msg));
|
||||
}
|
||||
}
|
||||
@@ -403,7 +364,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
|
||||
{
|
||||
var message = (DmtpMessage)requestInfo;
|
||||
if (!this.m_dmtpActor.InputReceivedData(message))
|
||||
if (!this.m_dmtpActor.InputReceivedData(message).GetFalseAwaitResult())
|
||||
{
|
||||
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
|
||||
}
|
||||
@@ -411,70 +372,81 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
|
||||
#region 内部委托绑定
|
||||
|
||||
private void OnDmtpActorClose(DmtpActor actor, string arg2)
|
||||
private Task OnDmtpActorClose(DmtpActor actor, string arg2)
|
||||
{
|
||||
this.PrivateClose(arg2);
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
|
||||
{
|
||||
this.OnCreateChannel(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
return this.OnCreateChannel(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaked(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
return this.OnHandshaked(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
|
||||
{
|
||||
this.OnHandshaking(e);
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
return this.OnHandshaking(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
|
||||
{
|
||||
if (this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.OnRouting(e);
|
||||
return this.OnRouting(e);
|
||||
}
|
||||
|
||||
private void OnDmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
|
||||
{
|
||||
for (var i = 0; i < transferBytes.Length; i++)
|
||||
try
|
||||
{
|
||||
Task task;
|
||||
if (i == transferBytes.Length - 1)
|
||||
this.m_semaphoreForSend.Wait();
|
||||
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 内部委托绑定
|
||||
@@ -485,32 +457,53 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// 当创建通道
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
|
||||
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在完成握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即将握手连接时
|
||||
/// </summary>
|
||||
/// <param name="e">参数</param>
|
||||
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
|
||||
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当需要转发路由包时
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected virtual void OnRouting(PackageRouterEventArgs e)
|
||||
protected virtual async Task OnRouting(PackageRouterEventArgs e)
|
||||
{
|
||||
if (e.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
|
||||
}
|
||||
|
||||
#endregion 事件触发
|
||||
|
@@ -10,6 +10,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
namespace ThingsGateway.Foundation.Dmtp
|
||||
{
|
||||
/// <summary>
|
||||
|
@@ -22,10 +22,10 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// <summary>
|
||||
/// 创建一个<see cref="DmtpFileTransferActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
public DmtpFileTransferActor(IDmtpActor smtpActor)
|
||||
/// <param name="dmtpActor"></param>
|
||||
public DmtpFileTransferActor(IDmtpActor dmtpActor)
|
||||
{
|
||||
this.DmtpActor = smtpActor;
|
||||
this.DmtpActor = dmtpActor;
|
||||
}
|
||||
|
||||
#region 委托
|
||||
@@ -61,12 +61,8 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
|
||||
#endregion 字段
|
||||
|
||||
/// <summary>
|
||||
/// 处理收到的消息
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public bool InputReceivedData(DmtpMessage message)
|
||||
/// <inheritdoc/>
|
||||
public async Task<bool> InputReceivedData(DmtpMessage message)
|
||||
{
|
||||
var byteBlock = message.BodyByteBlock;
|
||||
if (message.ProtocolFlags == this.m_pullFileResourceInfo_Request)
|
||||
@@ -77,9 +73,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileResource.UnpackageRouter(byteBlock);
|
||||
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
|
||||
{
|
||||
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
|
||||
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullFileResourceInfo_Request, byteBlock);
|
||||
return true;
|
||||
@@ -101,7 +97,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
else
|
||||
{
|
||||
waitFileResource.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
|
||||
_ = Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -118,7 +114,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileResource.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
@@ -143,9 +139,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullFileSection_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_pullFileSection_Request, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -153,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.SwitchId();
|
||||
byteBlock.Reset();
|
||||
waitFileSection.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pullFileSection_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pullFileSection_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -177,9 +173,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullFileSection_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_pullFileSection_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -202,11 +198,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileResource.UnpackageRouter(byteBlock);
|
||||
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
|
||||
{
|
||||
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
|
||||
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushFileResourceInfo_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_pushFileResourceInfo_Request, byteBlock);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -221,12 +217,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
byteBlock.Reset();
|
||||
waitFileResource.SwitchId();
|
||||
waitFileResource.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
waitFileResource.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.RequestPushFileResourceInfo, waitFileResource);
|
||||
_ = this.RequestPushFileResourceInfo(waitFileResource);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -243,9 +239,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileResource.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -268,9 +264,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushFileSection_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_pushFileSection_Request, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,7 +274,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.SwitchId();
|
||||
byteBlock.Reset();
|
||||
waitFileSection.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pushFileSection_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pushFileSection_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -303,9 +299,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFileSection.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushFileSection_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_pushFileSection_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -328,9 +324,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFinishedPackage.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_finishedFileResourceInfo_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_finishedFileResourceInfo_Request, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -338,13 +334,13 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFinishedPackage.SwitchId();
|
||||
byteBlock.Reset();
|
||||
waitFinishedPackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waitFinishedPackage.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.RequestFinishedFileResourceInfo, waitFinishedPackage);
|
||||
_ = this.RequestFinishedFileResourceInfo(waitFinishedPackage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -361,9 +357,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitFinishedPackage.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -386,11 +382,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitSmallFilePackage.UnpackageRouter(byteBlock);
|
||||
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
|
||||
{
|
||||
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
|
||||
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullSmallFile_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_pullSmallFile_Request, byteBlock);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -405,12 +401,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
byteBlock.Reset();
|
||||
waitSmallFilePackage.SwitchId();
|
||||
waitSmallFilePackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
waitSmallFilePackage.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
|
||||
_ = Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -427,9 +423,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitSmallFilePackage.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pullSmallFile_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -452,11 +448,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
waitSmallFilePackage.UnpackageRouter(byteBlock);
|
||||
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
|
||||
{
|
||||
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
|
||||
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushSmallFile_Request, byteBlock);
|
||||
await actor.SendAsync(this.m_pushSmallFile_Request, byteBlock);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -472,12 +468,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
byteBlock.Reset();
|
||||
waitSmallFilePackage.SwitchId();
|
||||
waitSmallFilePackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
waitSmallFilePackage.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.RequestPushSmallFile, waitSmallFilePackage);
|
||||
_ = this.RequestPushSmallFile(waitSmallFilePackage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -495,9 +491,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
|
||||
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_pushSmallFile_Response, byteBlock);
|
||||
await actor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -568,24 +564,20 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.FileController.GetFullPath(this.m_rootPath, path);
|
||||
}
|
||||
|
||||
private bool TryFindDmtpFileTransferActor(string targetId, out DmtpFileTransferActor rpcActor)
|
||||
private async Task<DmtpFileTransferActor> TryFindDmtpFileTransferActor(string targetId)
|
||||
{
|
||||
if (targetId == this.DmtpActor.Id)
|
||||
{
|
||||
rpcActor = this;
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
|
||||
{
|
||||
if (smtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
|
||||
if (dmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
|
||||
{
|
||||
rpcActor = newActor;
|
||||
return true;
|
||||
return newActor;
|
||||
}
|
||||
}
|
||||
|
||||
rpcActor = default;
|
||||
return false;
|
||||
return default;
|
||||
}
|
||||
|
||||
#region Id传输
|
||||
@@ -598,9 +590,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.PrivateFinishedFileResourceInfo(targetId, fileResourceInfo, code, metadata, timeout, token);
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
|
||||
return actor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -625,9 +617,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.PrivatePullFileResourceInfo(targetId, path, metadata, fileSectionSize, timeout, token);
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
|
||||
return actor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -652,9 +644,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.PrivatePullFileSection(targetId, fileSection, timeout, token);
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.PullFileSection(fileSection, timeout, token);
|
||||
return actor.PullFileSection(fileSection, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -679,9 +671,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.PrivatePushFileResourceInfo(targetId, savePath, fileResourceLocator, metadata, timeout, token);
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
|
||||
return actor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -715,9 +707,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
return this.PrivatePushFileSection(targetId, fileResourceLocator, fileSection, timeout, token);
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
|
||||
return actor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1261,7 +1253,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
waitFinishedPackage.SwitchId();
|
||||
waitFinishedPackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
|
||||
var args = new FileTransferedEventArgs(transferType, waitFinishedPackage?.Metadata, resourceInfo?.FileInfo, waitFinishedPackage.Code == ResultCode.Canceled ? Result.Canceled : resultThis)
|
||||
@@ -1454,7 +1446,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
waitFileResource.SwitchId();
|
||||
waitFileResource.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
|
||||
}
|
||||
}
|
||||
catch
|
||||
@@ -1528,7 +1520,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// <inheritdoc/>
|
||||
public PullSmallFileResult PullSmallFile(string targetId, string path, Metadata metadata = null, int timeout = 5000, CancellationToken token = default)
|
||||
{
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var actor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return actor.PullSmallFile(path, metadata, timeout, token);
|
||||
}
|
||||
@@ -1565,9 +1557,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// <inheritdoc/>
|
||||
public Result PushSmallFile(string targetId, string savePath, FileInfo fileInfo, Metadata metadata = null, int timeout = 5000, CancellationToken token = default)
|
||||
{
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
|
||||
{
|
||||
return rpcActor.PushSmallFile(savePath, fileInfo, metadata, timeout, token);
|
||||
return actor.PushSmallFile(savePath, fileInfo, metadata, timeout, token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1827,7 +1819,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
{
|
||||
waitSmallFilePackage.SwitchId();
|
||||
waitSmallFilePackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
|
||||
}
|
||||
|
||||
var resultArgs = new FileTransferedEventArgs(
|
||||
@@ -1891,7 +1883,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
using (var byteBlock = new ByteBlock())
|
||||
{
|
||||
waitSmallFilePackage.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
|
||||
}
|
||||
|
||||
var resultArgs = new FileTransferedEventArgs(
|
||||
|
@@ -59,12 +59,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// </summary>
|
||||
public int TryCount { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 设置结果状态
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
public Result SetResult(Result result)
|
||||
internal Result SetResult(Result result)
|
||||
{
|
||||
this.Result = result;
|
||||
return result;
|
||||
|
@@ -48,7 +48,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// <inheritdoc/>
|
||||
public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
|
||||
{
|
||||
var smtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor)
|
||||
var dmtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor)
|
||||
{
|
||||
FileController = this.m_fileResourceController,
|
||||
OnFileTransfering = this.OnFileTransfering,
|
||||
@@ -56,25 +56,25 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
RootPath = this.RootPath,
|
||||
MaxSmallFileLength = this.MaxSmallFileLength
|
||||
};
|
||||
smtpFileTransferActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetDmtpFileTransferActor(smtpFileTransferActor);
|
||||
dmtpFileTransferActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetDmtpFileTransferActor(dmtpFileTransferActor);
|
||||
|
||||
return e.InvokeNext();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
{
|
||||
if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor smtpFileTransferActor)
|
||||
if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor dmtpFileTransferActor)
|
||||
{
|
||||
if (smtpFileTransferActor.InputReceivedData(e.DmtpMessage))
|
||||
if (await dmtpFileTransferActor.InputReceivedData(e.DmtpMessage))
|
||||
{
|
||||
e.Handled = true;
|
||||
return EasyTask.CompletedTask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return e.InvokeNext();
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IDmtpFileTransferActor.MaxSmallFileLength"/>
|
||||
|
@@ -48,21 +48,21 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
|
||||
/// <summary>
|
||||
/// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpFileTransferActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
/// <param name="dmtpActor"></param>
|
||||
/// <returns></returns>
|
||||
public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor smtpActor)
|
||||
public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor dmtpActor)
|
||||
{
|
||||
return smtpActor.GetValue(DmtpFileTransferActorProperty);
|
||||
return dmtpActor.GetValue(DmtpFileTransferActorProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向<see cref="DmtpActor"/>中设置<see cref="DmtpFileTransferActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
/// <param name="smtpRpcActor"></param>
|
||||
internal static void SetDmtpFileTransferActor(this IDmtpActor smtpActor, DmtpFileTransferActor smtpRpcActor)
|
||||
/// <param name="dmtpActor"></param>
|
||||
/// <param name="dmtpRpcActor"></param>
|
||||
internal static void SetDmtpFileTransferActor(this IDmtpActor dmtpActor, DmtpFileTransferActor dmtpRpcActor)
|
||||
{
|
||||
smtpActor.SetValue(DmtpFileTransferActorProperty, smtpRpcActor);
|
||||
dmtpActor.SetValue(DmtpFileTransferActorProperty, dmtpRpcActor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -22,10 +22,10 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
/// <summary>
|
||||
/// DmtpRedisActor
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
public DmtpRedisActor(IDmtpActor smtpActor)
|
||||
/// <param name="dmtpActor"></param>
|
||||
public DmtpRedisActor(IDmtpActor dmtpActor)
|
||||
{
|
||||
this.DmtpActor = smtpActor;
|
||||
this.DmtpActor = dmtpActor;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -241,7 +241,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public bool InputReceivedData(DmtpMessage message)
|
||||
public async Task<bool> InputReceivedData(DmtpMessage message)
|
||||
{
|
||||
if (message.ProtocolFlags == this.m_redis_Request)
|
||||
{
|
||||
@@ -311,7 +311,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
using (var byteBlock = new ByteBlock())
|
||||
{
|
||||
waitResult.Package(byteBlock);
|
||||
this.DmtpActor.Send(this.m_redis_Response, byteBlock);
|
||||
await this.DmtpActor.SendAsync(this.m_redis_Response, byteBlock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -22,6 +22,8 @@
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
using ThingsGateway.Foundation.Resources;
|
||||
|
||||
namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
@@ -52,16 +54,16 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
/// <summary>
|
||||
/// 从<see cref="DmtpActor"/>中获得<see cref="IDmtpRedisActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
/// <param name="dmtpActor"></param>
|
||||
/// <returns></returns>
|
||||
public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor smtpActor)
|
||||
public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor dmtpActor)
|
||||
{
|
||||
return smtpActor.GetValue(DmtpRedisActorProperty);
|
||||
return dmtpActor.GetValue(DmtpRedisActorProperty);
|
||||
}
|
||||
|
||||
internal static void SetStmpRedisActor(this IDmtpActor smtpActor, DmtpRedisActor redisClient)
|
||||
internal static void SetStmpRedisActor(this IDmtpActor dmtpActor, DmtpRedisActor redisClient)
|
||||
{
|
||||
smtpActor.SetValue(DmtpRedisActorProperty, redisClient);
|
||||
dmtpActor.SetValue(DmtpRedisActorProperty, redisClient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -58,30 +58,30 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
|
||||
/// <inheritdoc/>
|
||||
public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
|
||||
{
|
||||
var smtpRedisActor = new DmtpRedisActor(client.DmtpActor)
|
||||
var dmtpRedisActor = new DmtpRedisActor(client.DmtpActor)
|
||||
{
|
||||
ICache = this.ICache,
|
||||
Converter = this.Converter
|
||||
};
|
||||
|
||||
smtpRedisActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetStmpRedisActor(smtpRedisActor);
|
||||
dmtpRedisActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetStmpRedisActor(dmtpRedisActor);
|
||||
|
||||
return e.InvokeNext();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
{
|
||||
if (client.DmtpActor.GetDmtpRedisActor() is DmtpRedisActor redisClient)
|
||||
{
|
||||
if (redisClient.InputReceivedData(e.DmtpMessage))
|
||||
if (await redisClient.InputReceivedData(e.DmtpMessage))
|
||||
{
|
||||
e.Handled = true;
|
||||
return EasyTask.CompletedTask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return e.InvokeNext();
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -36,10 +36,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
/// <summary>
|
||||
/// 创建一个DmtpRpcActor
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
public DmtpRpcActor(IDmtpActor smtpActor)
|
||||
/// <param name="dmtpActor"></param>
|
||||
public DmtpRpcActor(IDmtpActor dmtpActor)
|
||||
{
|
||||
this.DmtpActor = smtpActor;
|
||||
this.DmtpActor = dmtpActor;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -69,7 +69,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public bool InputReceivedData(DmtpMessage message)
|
||||
public async Task<bool> InputReceivedData(DmtpMessage message)
|
||||
{
|
||||
var byteBlock = message.BodyByteBlock;
|
||||
|
||||
@@ -77,14 +77,13 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
{
|
||||
try
|
||||
{
|
||||
//Console.WriteLine(byteBlock.Len);
|
||||
var rpcPackage = new DmtpRpcPackage();
|
||||
rpcPackage.UnpackageRouter(byteBlock);
|
||||
if (rpcPackage.Route && this.DmtpActor.AllowRoute)
|
||||
{
|
||||
if (this.DmtpActor.TryRoute(RouteType.Rpc, rpcPackage))
|
||||
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.Rpc, rpcPackage)).ConfigureFalseAwait())
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_invoke_Request, byteBlock);
|
||||
return true;
|
||||
@@ -108,8 +107,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
else
|
||||
{
|
||||
rpcPackage.UnpackageBody(byteBlock);
|
||||
Task.Factory.StartNew(this.InvokeThis, rpcPackage);
|
||||
//this.InvokeThis(rpcPackage);
|
||||
_ = Task.Factory.StartNew(this.InvokeThis, rpcPackage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -126,7 +124,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
rpcPackage.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && rpcPackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_invoke_Response, byteBlock);
|
||||
}
|
||||
@@ -151,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
canceledPackage.UnpackageRouter(byteBlock);
|
||||
if (this.DmtpActor.AllowRoute && canceledPackage.Route)
|
||||
{
|
||||
if (this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId, out var actor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
|
||||
{
|
||||
actor.Send(this.m_cancelInvoke, byteBlock);
|
||||
}
|
||||
@@ -203,7 +201,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
try
|
||||
{
|
||||
var rpcPackage = (DmtpRpcPackage)o;
|
||||
//Console.WriteLine(rpcPackage.MethodName);
|
||||
|
||||
var psData = rpcPackage.ParametersBytes;
|
||||
if (rpcPackage.Feedback == FeedbackType.WaitSend)
|
||||
{
|
||||
@@ -227,7 +225,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var invokeResult = new InvokeResult();
|
||||
object[] ps = null;
|
||||
var methodInstance = this.GetInvokeMethod?.Invoke(rpcPackage.MethodName);
|
||||
var methodInstance = this.GetInvokeMethod.Invoke(rpcPackage.MethodName);
|
||||
DmtpRpcCallContext callContext = null;
|
||||
if (methodInstance != null)
|
||||
{
|
||||
@@ -242,7 +240,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
DmtpRpcPackage = rpcPackage
|
||||
};
|
||||
this.TryAdd(rpcPackage.Sign, callContext);
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps = new object[methodInstance.ParameterTypes.Length];
|
||||
ps[0] = callContext;
|
||||
@@ -283,7 +281,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
{
|
||||
transientRpcServer.CallContext = callContext;
|
||||
}
|
||||
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext);
|
||||
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
if (rpcPackage.Feedback == FeedbackType.OnlySend)
|
||||
@@ -316,7 +314,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
rpcPackage.ParametersBytes = new List<byte[]>();
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
@@ -369,24 +367,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryFindDmtpRpcActor(string targetId, out DmtpRpcActor rpcActor)
|
||||
private async Task<DmtpRpcActor> TryFindDmtpRpcActor(string targetId)
|
||||
{
|
||||
if (targetId == this.DmtpActor.Id)
|
||||
{
|
||||
rpcActor = this;
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
|
||||
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
|
||||
{
|
||||
if (smtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
|
||||
if (dmtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
|
||||
{
|
||||
rpcActor = newActor;
|
||||
return true;
|
||||
return newActor;
|
||||
}
|
||||
}
|
||||
|
||||
rpcActor = default;
|
||||
return false;
|
||||
return default;
|
||||
}
|
||||
|
||||
#region Rpc
|
||||
@@ -504,8 +498,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -532,7 +524,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -689,8 +680,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -722,7 +711,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -779,8 +767,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetWaitDataAsync(rpcPackage);
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -818,7 +804,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
case FeedbackType.WaitSend:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
break;
|
||||
@@ -832,7 +818,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitInvoke:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -898,7 +884,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -907,7 +892,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitSend:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.Overtime:
|
||||
{
|
||||
@@ -918,7 +903,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitInvoke:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -961,7 +946,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
|
||||
{
|
||||
actor.Invoke(invokeKey, invokeOption, parameters);
|
||||
return;
|
||||
@@ -977,7 +962,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -1009,7 +993,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1069,9 +1052,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
|
||||
{
|
||||
return rpcActor.Invoke(returnType, invokeKey, invokeOption, parameters);
|
||||
return actor.Invoke(returnType, invokeKey, invokeOption, parameters);
|
||||
}
|
||||
|
||||
var rpcPackage = new DmtpRpcPackage
|
||||
@@ -1084,10 +1067,8 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
using (var byteBlock = new ByteBlock())
|
||||
{
|
||||
if (invokeOption == default)
|
||||
@@ -1116,7 +1097,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1175,9 +1155,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
|
||||
{
|
||||
rpcActor.Invoke(invokeKey, invokeOption, ref parameters, types);
|
||||
actor.Invoke(invokeKey, invokeOption, ref parameters, types);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1191,7 +1171,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -1219,7 +1198,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1289,9 +1267,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
|
||||
{
|
||||
return rpcActor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
|
||||
return actor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
|
||||
}
|
||||
|
||||
var rpcPackage = new DmtpRpcPackage
|
||||
@@ -1304,7 +1282,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -1330,7 +1307,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1400,9 +1376,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
|
||||
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
|
||||
{
|
||||
await actor.InvokeAsync(invokeKey, invokeOption, parameters);
|
||||
await actor.InvokeAsync(invokeKey, invokeOption, parameters).ConfigureFalseAwait();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1416,7 +1392,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitDataAsync(rpcPackage);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (var byteBlock = new ByteBlock())
|
||||
@@ -1448,7 +1423,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1456,7 +1430,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
case FeedbackType.WaitSend:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
break;
|
||||
@@ -1470,7 +1444,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitInvoke:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
@@ -1508,9 +1482,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
|
||||
}
|
||||
|
||||
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
|
||||
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
|
||||
{
|
||||
return await rpcActor.InvokeAsync(returnType, invokeKey, invokeOption, parameters);
|
||||
return await actor.InvokeAsync(returnType, invokeKey, invokeOption, parameters).ConfigureFalseAwait();
|
||||
}
|
||||
|
||||
var rpcPackage = new DmtpRpcPackage
|
||||
@@ -1553,8 +1527,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (invokeOption.FeedbackType)
|
||||
{
|
||||
case FeedbackType.OnlySend:
|
||||
@@ -1563,7 +1535,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitSend:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.Overtime:
|
||||
{
|
||||
@@ -1574,7 +1546,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
}
|
||||
case FeedbackType.WaitInvoke:
|
||||
{
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout))
|
||||
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
|
||||
{
|
||||
case WaitDataStatus.SetRunning:
|
||||
{
|
||||
|
@@ -42,11 +42,11 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
/// <summary>
|
||||
/// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpRpcActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
/// <param name="dmtpActor"></param>
|
||||
/// <returns></returns>
|
||||
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor smtpActor)
|
||||
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor dmtpActor)
|
||||
{
|
||||
return smtpActor.GetValue(DmtpRpcActorProperty);
|
||||
return dmtpActor.GetValue(DmtpRpcActorProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,12 +57,12 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActorObject client)
|
||||
{
|
||||
var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
|
||||
if (smtpRpcActor is null)
|
||||
var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
|
||||
if (dmtpRpcActor is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
|
||||
throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
|
||||
}
|
||||
return smtpRpcActor;
|
||||
return dmtpRpcActor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -73,22 +73,22 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static TDmtpRpcActor GetDmtpRpcActor<TDmtpRpcActor>(this IDmtpActorObject client) where TDmtpRpcActor : IDmtpRpcActor
|
||||
{
|
||||
var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
|
||||
if (smtpRpcActor is null)
|
||||
var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
|
||||
if (dmtpRpcActor is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
|
||||
throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
|
||||
}
|
||||
return (TDmtpRpcActor)smtpRpcActor;
|
||||
return (TDmtpRpcActor)dmtpRpcActor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向<see cref="DmtpActor"/>中设置<see cref="IDmtpRpcActor"/>
|
||||
/// </summary>
|
||||
/// <param name="smtpActor"></param>
|
||||
/// <param name="smtpRpcActor"></param>
|
||||
internal static void SetDmtpRpcActor(this IDmtpActor smtpActor, IDmtpRpcActor smtpRpcActor)
|
||||
/// <param name="dmtpActor"></param>
|
||||
/// <param name="dmtpRpcActor"></param>
|
||||
internal static void SetDmtpRpcActor(this IDmtpActor dmtpActor, IDmtpRpcActor dmtpRpcActor)
|
||||
{
|
||||
smtpActor.SetValue(DmtpRpcActorProperty, smtpRpcActor);
|
||||
dmtpActor.SetValue(DmtpRpcActorProperty, dmtpRpcActor);
|
||||
}
|
||||
|
||||
#region 插件扩展
|
||||
|
@@ -94,9 +94,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
return this.ActionMap.GetMethodInstance(name);
|
||||
}
|
||||
|
||||
private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor smtpActor)
|
||||
private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor dmtpActor)
|
||||
{
|
||||
return new DmtpRpcActor(smtpActor);
|
||||
return new DmtpRpcActor(dmtpActor);
|
||||
}
|
||||
|
||||
#region Rpc配置
|
||||
@@ -135,31 +135,30 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
pluginsManager.Add<IDmtpActorObject, DmtpMessageEventArgs>(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this.OnDmtpReceived);
|
||||
}
|
||||
|
||||
private Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
|
||||
private async Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
|
||||
{
|
||||
var smtpRpcActor = CreateDmtpRpcActor(client.DmtpActor);
|
||||
smtpRpcActor.RpcStore = this.RpcStore;
|
||||
smtpRpcActor.SerializationSelector = this.SerializationSelector;
|
||||
smtpRpcActor.GetInvokeMethod = this.GetInvokeMethod;
|
||||
var dmtpRpcActor = this.CreateDmtpRpcActor(client.DmtpActor);
|
||||
dmtpRpcActor.RpcStore = this.RpcStore;
|
||||
dmtpRpcActor.SerializationSelector = this.SerializationSelector;
|
||||
dmtpRpcActor.GetInvokeMethod = this.GetInvokeMethod;
|
||||
|
||||
smtpRpcActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetDmtpRpcActor(smtpRpcActor);
|
||||
dmtpRpcActor.SetProtocolFlags(this.StartProtocol);
|
||||
client.DmtpActor.SetDmtpRpcActor(dmtpRpcActor);
|
||||
|
||||
return e.InvokeNext();
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
private Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
private async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
|
||||
{
|
||||
if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor smtpRpcActor)
|
||||
if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor dmtpRpcActor)
|
||||
{
|
||||
if (smtpRpcActor.InputReceivedData(e.DmtpMessage))
|
||||
if (await dmtpRpcActor.InputReceivedData(e.DmtpMessage).ConfigureFalseAwait())
|
||||
{
|
||||
e.Handled = true;
|
||||
return EasyTask.CompletedTask;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return e.InvokeNext();
|
||||
await e.InvokeNext();
|
||||
}
|
||||
|
||||
#endregion Config
|
||||
|
@@ -108,10 +108,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
|
||||
|
||||
internal void LoadInvokeOption(IInvokeOption option)
|
||||
{
|
||||
if (option is DmtpInvokeOption smtpInvokeOption)
|
||||
if (option is DmtpInvokeOption dmtpInvokeOption)
|
||||
{
|
||||
this.Feedback = smtpInvokeOption.FeedbackType;
|
||||
this.SerializationType = smtpInvokeOption.SerializationType;
|
||||
this.Feedback = dmtpInvokeOption.FeedbackType;
|
||||
this.SerializationType = dmtpInvokeOption.SerializationType;
|
||||
}
|
||||
else if (option is InvokeOption invokeOption)
|
||||
{
|
||||
|
@@ -27,6 +27,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns>当满足本协议时,应当返回<see langword="true"/>,其他时候应该返回<see langword="false"/>.</returns>
|
||||
public bool InputReceivedData(DmtpMessage message);
|
||||
public Task<bool> InputReceivedData(DmtpMessage message);
|
||||
}
|
||||
}
|
@@ -58,7 +58,7 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
failedCount++;
|
||||
if (failedCount > this.MaxFailCount)
|
||||
{
|
||||
client.DmtpActor.Close(true, "自动心跳失败次数达到最大,已断开连接。");
|
||||
client.DmtpActor.Close("自动心跳失败次数达到最大,已断开连接。");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,8 +18,8 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
public class DmtpRouteService : IDmtpRouteService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查找路由的委托
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
public Func<string, IDmtpActor> FindDmtpActor { get; set; }
|
||||
public Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; }
|
||||
}
|
||||
}
|
@@ -31,12 +31,26 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
/// <param name="func"></param>
|
||||
public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> func)
|
||||
public static void AddDmtpRouteService(this IContainer container, Func<string, Task<IDmtpActor>> func)
|
||||
{
|
||||
container.RegisterSingleton<IDmtpRouteService>(new DmtpRouteService()
|
||||
{
|
||||
FindDmtpActor = func
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加基于设定委托的Dmtp路由服务。
|
||||
/// </summary>
|
||||
/// <param name="container"></param>
|
||||
/// <param name="action"></param>
|
||||
public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> action)
|
||||
{
|
||||
AddDmtpRouteService(container, async (id) =>
|
||||
{
|
||||
await EasyTask.CompletedTask;
|
||||
return action.Invoke(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -20,6 +20,6 @@ namespace ThingsGateway.Foundation.Dmtp
|
||||
/// <summary>
|
||||
/// 查找其他IDmtpActor
|
||||
/// </summary>
|
||||
Func<string, IDmtpActor> FindDmtpActor { get; set; }
|
||||
Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; }
|
||||
}
|
||||
}
|
@@ -37,6 +37,10 @@ namespace ThingsGateway.Foundation.Http
|
||||
public HttpStaticPagePlugin()
|
||||
{
|
||||
this.FileCache = new FileCachePool();
|
||||
this.SetNavigateAction(request =>
|
||||
{
|
||||
return request.RelativeURL;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -81,15 +85,45 @@ namespace ThingsGateway.Foundation.Http
|
||||
this.FileCache.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重新导航
|
||||
/// </summary>
|
||||
public Func<HttpRequest, Task<string>> NavigateAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设定重新导航
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public HttpStaticPagePlugin SetNavigateAction(Func<HttpRequest, Task<string>> func)
|
||||
{
|
||||
this.NavigateAction = func;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设定重新导航
|
||||
/// </summary>
|
||||
/// <param name="func"></param>
|
||||
/// <returns></returns>
|
||||
public HttpStaticPagePlugin SetNavigateAction(Func<HttpRequest, string> func)
|
||||
{
|
||||
this.NavigateAction = (request) =>
|
||||
{
|
||||
return Task.FromResult(func(request));
|
||||
};
|
||||
return this;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public async Task OnHttpRequest(IHttpSocketClient client, HttpContextEventArgs e)
|
||||
{
|
||||
if (this.FileCache.Find(e.Context.Request.RelativeURL, out var data))
|
||||
var url = await this.NavigateAction.Invoke(e.Context.Request);
|
||||
if (this.FileCache.Find(url, out var data))
|
||||
{
|
||||
e.Context.Response.SetStatus();
|
||||
if (this.ContentTypeProvider?.TryGetContentType(e.Context.Request.RelativeURL, out var result) != true)
|
||||
if (this.ContentTypeProvider?.TryGetContentType(url, out var result) != true)
|
||||
{
|
||||
result = HttpTools.GetContentTypeFromExtension(e.Context.Request.RelativeURL);
|
||||
result = HttpTools.GetContentTypeFromExtension(url);
|
||||
}
|
||||
e.Context.Response.ContentType = result;
|
||||
e.Context.Response.SetContentLength(data.Length)
|
||||
|
@@ -72,7 +72,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
|
||||
{
|
||||
return new WebSocketReceiveResult(this.ComplateRead, null);
|
||||
}
|
||||
await this.m_resetEventForRead.WaitOneAsync(token);
|
||||
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
|
||||
return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame);
|
||||
}
|
||||
#if NET6_0_OR_GREATER
|
||||
@@ -82,7 +82,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
|
||||
{
|
||||
return new WebSocketReceiveResult(this.ComplateRead, null);
|
||||
}
|
||||
await this.m_resetEventForRead.WaitOneAsync(token);
|
||||
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
|
||||
return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame);
|
||||
}
|
||||
#endif
|
||||
@@ -146,7 +146,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10)))
|
||||
if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10)).ConfigureFalseAwait())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// 标识该接口将自动生成调用的扩展方法静态类
|
||||
/// 标识该接口将自动生成调用的代理类
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class GeneratorRpcProxyAttribute : Attribute
|
||||
@@ -39,7 +39,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
public string Namespace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成的类名,不要包含“I”,生成接口时会自动家。
|
||||
/// 生成的类名,不要包含“I”,生成接口时会自动添加。
|
||||
/// </summary>
|
||||
public string ClassName { get; set; }
|
||||
|
||||
@@ -48,11 +48,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public CodeGeneratorFlag GeneratorFlag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 继承接口
|
||||
/// </summary>
|
||||
|
@@ -39,7 +39,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public RpcAttribute()
|
||||
{
|
||||
this.MethodFlags = MethodFlags.None;
|
||||
this.Exceptions.Add(typeof(TimeoutException), "调用超时");
|
||||
this.Exceptions.Add(typeof(RpcInvokeException), "Rpc调用异常");
|
||||
this.Exceptions.Add(typeof(Exception), "其他异常");
|
||||
@@ -72,11 +71,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public string InvokeKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否仅以函数名调用,当为True是,调用时仅需要传入方法名即可。
|
||||
/// </summary>
|
||||
@@ -122,25 +116,25 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
|
||||
codeString.Append("public static ");
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("<TClient>(");//方法参数
|
||||
|
||||
codeString.Append($"this TClient client");
|
||||
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(") where TClient:");
|
||||
@@ -149,7 +143,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(InterfaceTypes[i].FullName);
|
||||
@@ -159,7 +153,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
@@ -173,7 +167,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -181,13 +175,13 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -199,7 +193,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
@@ -207,7 +201,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
@@ -215,7 +209,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -275,12 +269,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
//以下生成异步
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionAsync) /*&& !isOut && !isRef*/)
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
codeString.AppendLine("///</summary>");
|
||||
if (methodInstance.HasReturn)
|
||||
if (methodInstance.HasReturn && !isOut && !isRef)
|
||||
{
|
||||
codeString.Append("public static async ");
|
||||
}
|
||||
@@ -289,24 +283,24 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append("public static ");
|
||||
}
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("<TClient>(");//方法参数
|
||||
|
||||
codeString.Append($"this TClient client");
|
||||
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(") where TClient:");
|
||||
@@ -315,7 +309,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
|
||||
codeString.Append(InterfaceTypes[i].FullName);
|
||||
@@ -326,16 +320,39 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut)
|
||||
{
|
||||
codeString.Append($"default({this.GetProxyParameterName(parameter)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance.HasReturn)
|
||||
@@ -343,15 +360,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -365,6 +390,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append("client.Invoke(");
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append("return client.InvokeAsync(");
|
||||
@@ -372,6 +403,43 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.AppendLine("if(parameters!=null)");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i));
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
if (isOut)
|
||||
{
|
||||
codeString.AppendLine("else");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].IsOut)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i])));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
if (methodInstance.HasReturn)
|
||||
{
|
||||
codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.AppendLine(string.Format("return EasyTask.CompletedTask;"));
|
||||
}
|
||||
}
|
||||
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
return codeString.ToString();
|
||||
@@ -409,21 +477,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
|
||||
codeString.Append("public ");
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(")");
|
||||
@@ -438,7 +506,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
@@ -452,7 +520,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -460,13 +528,13 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
@@ -478,7 +546,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
@@ -554,12 +622,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
//以下生成异步
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceAsync))
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
codeString.AppendLine("///</summary>");
|
||||
if (methodInstance.HasReturn)
|
||||
if (methodInstance.HasReturn && (!isOut && !isRef))
|
||||
{
|
||||
codeString.Append("public async ");
|
||||
}
|
||||
@@ -568,21 +636,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append("public ");
|
||||
}
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parametersStr.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parametersStr[i]);
|
||||
}
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(")");
|
||||
@@ -597,16 +665,39 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count > 0)
|
||||
{
|
||||
codeString.Append($"object[] parameters = new object[]");
|
||||
codeString.Append("{");
|
||||
codeString.Append('{');
|
||||
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut)
|
||||
{
|
||||
codeString.Append($"default({this.GetProxyParameterName(parameter)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(parameter.Name);
|
||||
}
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.Append($"Type[] types = new Type[]");
|
||||
codeString.Append('{');
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
codeString.Append($"typeof({this.GetProxyParameterName(parameter)})");
|
||||
if (parameter != parameters[parameters.Length - 1])
|
||||
{
|
||||
codeString.Append(',');
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("};");
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance.HasReturn)
|
||||
@@ -614,15 +705,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
if (parametersStr.Count == 0)
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append("(");
|
||||
codeString.Append('(');
|
||||
codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
@@ -636,6 +735,12 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption, null);");
|
||||
}
|
||||
else if (isOut || isRef)
|
||||
{
|
||||
codeString.Append("Client.Invoke(");
|
||||
codeString.Append($"\"{this.GetInvokenKey(methodInstance)}\"");
|
||||
codeString.AppendLine(",invokeOption,ref parameters,types);");
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.Append("return Client.InvokeAsync(");
|
||||
@@ -643,8 +748,46 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
codeString.AppendLine(",invokeOption, parameters);");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
codeString.AppendLine("if(parameters!=null)");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i));
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
if (isOut)
|
||||
{
|
||||
codeString.AppendLine("else");
|
||||
codeString.AppendLine("{");
|
||||
for (var i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].IsOut)
|
||||
{
|
||||
codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i])));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
}
|
||||
|
||||
if (isOut || isRef)
|
||||
{
|
||||
if (methodInstance.HasReturn)
|
||||
{
|
||||
codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(methodInstance.Info.ReturnParameter)));
|
||||
}
|
||||
else
|
||||
{
|
||||
codeString.AppendLine(string.Format("return EasyTask.CompletedTask;"));
|
||||
}
|
||||
}
|
||||
codeString.AppendLine("}");
|
||||
}
|
||||
|
||||
|
||||
return codeString.ToString();
|
||||
}
|
||||
|
||||
@@ -669,26 +812,26 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
codeString.Append(this.GetReturn(methodInstance, false));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, false));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parameters[i]);
|
||||
}
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(");");
|
||||
}
|
||||
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceAsync) && !isOut && !isRef)//没有out或者ref
|
||||
if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceAsync))
|
||||
{
|
||||
codeString.AppendLine("///<summary>");
|
||||
codeString.AppendLine($"///{description}");
|
||||
@@ -699,21 +842,21 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
codeString.Append(this.GetReturn(methodInstance, true));
|
||||
codeString.Append(" ");
|
||||
codeString.Append(' ');
|
||||
codeString.Append(this.GetMethodName(methodInstance, true));
|
||||
codeString.Append("(");//方法参数
|
||||
codeString.Append('(');//方法参数
|
||||
|
||||
for (var i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(parameters[i]);
|
||||
}
|
||||
if (parameters.Count > 0)
|
||||
{
|
||||
codeString.Append(",");
|
||||
codeString.Append(',');
|
||||
}
|
||||
codeString.Append(this.GetInvokeOption());
|
||||
codeString.AppendLine(");");
|
||||
@@ -774,7 +917,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
isOut = false;
|
||||
isRef = false;
|
||||
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
var infos = new List<ParameterInfo>(methodInstance.Parameters);
|
||||
infos.RemoveAt(0);
|
||||
|
@@ -302,7 +302,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
@@ -75,10 +75,10 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
|
||||
var fromMethodInfos = new Dictionary<string, MethodInfo>();
|
||||
CodeGenerator.GetMethodInfos(ServerFromType, ref fromMethodInfos);
|
||||
CodeGenerator.GetMethodInfos(this.ServerFromType, ref fromMethodInfos);
|
||||
|
||||
var toMethodInfos = new Dictionary<string, MethodInfo>();
|
||||
CodeGenerator.GetMethodInfos(ServerToType, ref toMethodInfos);
|
||||
CodeGenerator.GetMethodInfos(this.ServerToType, ref toMethodInfos);
|
||||
|
||||
var attributes = method.GetCustomAttributes<RpcAttribute>(true);
|
||||
if (attributes.Any())
|
||||
@@ -98,7 +98,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in ServerFromType.GetCustomAttributes(true))
|
||||
foreach (var item in this.ServerFromType.GetCustomAttributes(true))
|
||||
{
|
||||
if (item is IRpcActionFilter filter)
|
||||
{
|
||||
@@ -106,7 +106,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
if (ServerFromType != ServerToType)
|
||||
if (this.ServerFromType != this.ServerToType)
|
||||
{
|
||||
foreach (var item in toMethod.GetCustomAttributes(true))
|
||||
{
|
||||
@@ -116,7 +116,7 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in ServerToType.GetCustomAttributes(true))
|
||||
foreach (var item in this.ServerToType.GetCustomAttributes(true))
|
||||
{
|
||||
if (item is IRpcActionFilter filter)
|
||||
{
|
||||
@@ -128,17 +128,23 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
this.Filters = actionFilters.ToArray();
|
||||
}
|
||||
foreach (var item in attributes)
|
||||
//foreach (var item in attributes)
|
||||
//{
|
||||
// this.MethodFlags |= item.MethodFlags;
|
||||
//}
|
||||
//if (this.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
//{
|
||||
// if (this.Parameters.Length == 0 || !typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
// {
|
||||
// throw new RpcException($"函数:{method},标识包含{MethodFlags.IncludeCallContext}时,必须包含{nameof(ICallContext)}或其派生类参数,且为第一参数。");
|
||||
// }
|
||||
//}
|
||||
|
||||
if (this.Parameters.Length > 0 && typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
{
|
||||
this.MethodFlags |= item.MethodFlags;
|
||||
}
|
||||
if (this.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
{
|
||||
if (this.Parameters.Length == 0 || !typeof(ICallContext).IsAssignableFrom(this.Parameters[0].ParameterType))
|
||||
{
|
||||
throw new RpcException($"函数:{method},标识包含{MethodFlags.IncludeCallContext}时,必须包含{nameof(ICallContext)}或其派生类参数,且为第一参数。");
|
||||
}
|
||||
this.IncludeCallContext = true;
|
||||
}
|
||||
|
||||
var names = new List<string>();
|
||||
foreach (var parameterInfo in this.Parameters)
|
||||
{
|
||||
@@ -155,6 +161,11 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含调用上下文
|
||||
/// </summary>
|
||||
public bool IncludeCallContext { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 筛选器
|
||||
/// </summary>
|
||||
@@ -165,11 +176,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// </summary>
|
||||
public bool IsEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
public MethodFlags MethodFlags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数名集合
|
||||
/// </summary>
|
||||
|
@@ -1,44 +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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:http://rrqm_home.gitee.io/touchsocket/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ThingsGateway.Foundation.Rpc
|
||||
{
|
||||
/// <summary>
|
||||
/// 函数标识
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MethodFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// 空
|
||||
/// </summary>
|
||||
None = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 包含调用上下文
|
||||
/// </summary>
|
||||
IncludeCallContext = 2
|
||||
}
|
||||
}
|
@@ -34,8 +34,8 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// 调用此服务的主体。
|
||||
/// <para>
|
||||
/// <list type="bullet">
|
||||
/// <item>当该服务在<see cref="ITcpService"/>及派生中调用时,该值一般为<see cref="ISocketClient"/>对象。</item>
|
||||
/// <item>当该服务在<see cref="ITcpClient"/>及派生中调用时,该值一般为<see cref="ITcpClient"/>对象。</item>
|
||||
/// <item>当该服务在ITcpService及派生中调用时,该值一般为ISocketClient对象。</item>
|
||||
/// <item>当该服务在ITcpClient及派生中调用时,该值一般为ITcpClient对象。</item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
|
@@ -39,7 +39,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
Task InvokeAsync(string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
|
||||
@@ -53,7 +52,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
Task<object> InvokeAsync(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
@@ -67,7 +65,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
void Invoke(string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
|
||||
@@ -81,7 +78,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="parameters">参数</param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
object Invoke(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, params object[] parameters);
|
||||
@@ -96,7 +92,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="types"></param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
void Invoke(string targetId, string invokeKey, IInvokeOption invokeOption, ref object[] parameters, Type[] types);
|
||||
|
||||
@@ -111,7 +106,6 @@ namespace ThingsGateway.Foundation.Rpc
|
||||
/// <param name="types"></param>
|
||||
/// <exception cref="TimeoutException">调用超时</exception>
|
||||
/// <exception cref="RpcInvokeException">调用内部异常</exception>
|
||||
/// <exception cref="ClientNotFindException">没有找到Id对应的客户端</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回值</returns>
|
||||
object Invoke(Type returnType, string targetId, string invokeKey, IInvokeOption invokeOption, ref object[] parameters, Type[] types);
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace ThingsGateway.Foundation.Serial;
|
||||
@@ -40,13 +39,12 @@ public class SerialCore : IDisposable, ISender
|
||||
public readonly object SyncRoot = new object();
|
||||
|
||||
private long m_bufferRate;
|
||||
private SpinLock m_lock;
|
||||
private bool m_online => m_serialPort?.IsOpen == true;
|
||||
private int m_receiveBufferSize = 1024 * 10;
|
||||
private ValueCounter m_receiveCounter;
|
||||
private int m_sendBufferSize = 1024 * 10;
|
||||
private ValueCounter m_sendCounter;
|
||||
private readonly EasyLock m_semaphore = new EasyLock();
|
||||
private readonly EasyLock m_semaphoreForSend = new EasyLock();
|
||||
private SerialPort m_serialPort;
|
||||
|
||||
#endregion 字段
|
||||
@@ -56,7 +54,6 @@ public class SerialCore : IDisposable, ISender
|
||||
/// </summary>
|
||||
public SerialCore()
|
||||
{
|
||||
this.m_lock = new SpinLock(Debugger.IsAttached);
|
||||
this.m_receiveCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
@@ -215,10 +212,20 @@ public class SerialCore : IDisposable, ISender
|
||||
this.OnBreakOut = null;
|
||||
this.UserToken = null;
|
||||
this.m_bufferRate = 1;
|
||||
this.m_lock = new SpinLock();
|
||||
this.m_receiveBufferSize = this.MinBufferSize;
|
||||
this.m_sendBufferSize = this.MinBufferSize;
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断,当不在连接状态时触发异常。
|
||||
/// </summary>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
protected void ThrowIfNotConnected()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据。
|
||||
@@ -231,15 +238,15 @@ public class SerialCore : IDisposable, ISender
|
||||
/// <param name="length"></param>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
var lockTaken = false;
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
this.m_lock.Enter(ref lockTaken);
|
||||
this.m_semaphoreForSend.Wait();
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken) this.m_lock.Exit(false);
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
this.m_sendCounter.Increment(length);
|
||||
}
|
||||
@@ -254,15 +261,16 @@ public class SerialCore : IDisposable, ISender
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual async Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
try
|
||||
{
|
||||
await this.m_semaphore.WaitAsync();
|
||||
await this.m_semaphoreForSend.WaitAsync();
|
||||
|
||||
this.m_serialPort.Write(buffer, offset, length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
|
||||
this.m_sendCounter.Increment(length);
|
||||
|
@@ -255,7 +255,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
|
||||
this.MainSerialPort.TryClose();
|
||||
this.BreakOut(default, true, msg);
|
||||
this.BreakOut(true, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
|
||||
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
@@ -361,7 +361,16 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
|
||||
#endregion
|
||||
|
||||
private void BreakOut(SerialCore core, bool manual, string msg)
|
||||
private void SerialCoreBreakOut(SerialCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
/// <summary>
|
||||
/// BreakOut。
|
||||
/// </summary>
|
||||
/// <param name="manual"></param>
|
||||
/// <param name="msg"></param>
|
||||
protected void BreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.SyncRoot)
|
||||
{
|
||||
@@ -718,6 +727,11 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetSerialCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -759,7 +773,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
|
||||
}
|
||||
this.m_serialCore.Reset(serialPort);
|
||||
this.m_serialCore.OnReceived = this.HandleReceived;
|
||||
this.m_serialCore.OnBreakOut = this.BreakOut;
|
||||
this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut;
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
|
||||
{
|
||||
this.m_serialCore.MinBufferSize = minValue;
|
||||
|
@@ -51,6 +51,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public int DelayLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 队列长度
|
||||
/// </summary>
|
||||
public int QueueCount => this.m_queueDatas.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 发送
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
|
||||
@@ -41,14 +40,13 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
public readonly object SyncRoot = new object();
|
||||
|
||||
private long m_bufferRate;
|
||||
private SpinLock m_lock;
|
||||
private volatile bool m_online;
|
||||
private int m_receiveBufferSize = 1024 * 10;
|
||||
private ValueCounter m_receiveCounter;
|
||||
private int m_sendBufferSize = 1024 * 10;
|
||||
private ValueCounter m_sendCounter;
|
||||
private Socket m_socket;
|
||||
private readonly EasyLock m_semaphore = new();
|
||||
private readonly EasyLock m_semaphoreForSend = new();
|
||||
#endregion 字段
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +54,6 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
/// </summary>
|
||||
public TcpCore()
|
||||
{
|
||||
this.m_lock = new SpinLock(Debugger.IsAttached);
|
||||
this.m_receiveCounter = new ValueCounter
|
||||
{
|
||||
Period = TimeSpan.FromSeconds(1),
|
||||
@@ -295,12 +292,21 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
this.OnBreakOut = null;
|
||||
this.UserToken = null;
|
||||
this.m_bufferRate = 1;
|
||||
this.m_lock = new SpinLock();
|
||||
this.m_receiveBufferSize = this.MinBufferSize;
|
||||
this.m_sendBufferSize = this.MinBufferSize;
|
||||
this.m_online = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断,当不在连接状态时触发异常。
|
||||
/// </summary>
|
||||
/// <exception cref="NotConnectedException"></exception>
|
||||
protected void ThrowIfNotConnected()
|
||||
{
|
||||
if (!this.m_online)
|
||||
{
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送数据。
|
||||
/// <para>
|
||||
@@ -312,16 +318,16 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
/// <param name="length"></param>
|
||||
public virtual void Send(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
if (this.UseSsl)
|
||||
{
|
||||
this.SslStream.Write(buffer, offset, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
var lockTaken = false;
|
||||
try
|
||||
{
|
||||
this.m_lock.Enter(ref lockTaken);
|
||||
this.m_semaphoreForSend.Wait();
|
||||
while (length > 0)
|
||||
{
|
||||
var r = this.m_socket.Send(buffer, offset, length, SocketFlags.None);
|
||||
@@ -335,7 +341,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockTaken) this.m_lock.Exit(false);
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
}
|
||||
this.m_sendCounter.Increment(length);
|
||||
@@ -354,6 +360,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
/// <exception cref="Exception"></exception>
|
||||
public virtual async Task SendAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
this.ThrowIfNotConnected();
|
||||
#if NET6_0_OR_GREATER
|
||||
if (this.UseSsl)
|
||||
{
|
||||
@@ -363,7 +370,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.m_semaphore.WaitAsync();
|
||||
await this.m_semaphoreForSend.WaitAsync();
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
@@ -378,7 +385,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -390,7 +397,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.m_semaphore.WaitAsync();
|
||||
await this.m_semaphoreForSend.WaitAsync();
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
@@ -405,7 +412,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_semaphore.Release();
|
||||
this.m_semaphoreForSend.Release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@@ -39,23 +39,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public SocketClient()
|
||||
{
|
||||
this.Protocol = Protocol.Tcp;
|
||||
//this.m_receiveCounter = new ValueCounter
|
||||
//{
|
||||
// Period = TimeSpan.FromSeconds(1),
|
||||
// OnPeriod = this.OnReceivePeriod
|
||||
//};
|
||||
//m_sendCounter = new ValueCounter
|
||||
//{
|
||||
// Period = TimeSpan.FromSeconds(1),
|
||||
// OnPeriod = this.OnSendPeriod
|
||||
//};
|
||||
}
|
||||
|
||||
#region 变量
|
||||
|
||||
//private ValueCounter m_receiveCounter;
|
||||
//private ValueCounter m_sendCounter;
|
||||
//private long m_bufferRate = 1;
|
||||
private DelaySender m_delaySender;
|
||||
|
||||
private TcpCore m_tcpCore;
|
||||
@@ -127,36 +114,23 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
#endregion 属性
|
||||
|
||||
#region Internal
|
||||
|
||||
internal Task AuthenticateAsync(ServiceSslOption sslOption)
|
||||
{
|
||||
return this.m_tcpCore.AuthenticateAsync(sslOption);
|
||||
}
|
||||
internal void BeginReceive()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_tcpCore.BeginIocpReceive();
|
||||
//if (this.ReceiveType == ReceiveType.Iocp)
|
||||
//{
|
||||
// //var eventArgs = new SocketAsyncEventArgs();
|
||||
// //eventArgs.Completed += this.EventArgs_Completed;
|
||||
// //var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
|
||||
// //eventArgs.UserToken = byteBlock;
|
||||
// //eventArgs.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity);
|
||||
// //if (!this.MainSocket.ReceiveAsync(eventArgs))
|
||||
// //{
|
||||
// // this.ProcessReceived(eventArgs);
|
||||
// //}
|
||||
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.BreakOut(default, false, ex.ToString());
|
||||
this.BreakOut(false, ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
internal Task AuthenticateAsync(ServiceSslOption sslOption)
|
||||
{
|
||||
return this.m_tcpCore.AuthenticateAsync(sslOption);
|
||||
}
|
||||
|
||||
internal Task BeginReceiveSsl()
|
||||
{
|
||||
return this.m_tcpCore.BeginSslReceive();
|
||||
@@ -220,13 +194,13 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(senderOption, this.MainSocket.AbsoluteSend);
|
||||
this.m_delaySender = new DelaySender(senderOption, this.GetTcpCore().Send);
|
||||
}
|
||||
|
||||
var tcpCore = this.Service.RentTcpCore();
|
||||
tcpCore.Reset(socket);
|
||||
tcpCore.OnReceived = this.HandleReceived;
|
||||
tcpCore.OnBreakOut = this.BreakOut;
|
||||
tcpCore.OnBreakOut = this.TcpCoreBreakOut;
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
|
||||
{
|
||||
tcpCore.MinBufferSize = minValue;
|
||||
@@ -239,7 +213,14 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
this.m_tcpCore = tcpCore;
|
||||
}
|
||||
|
||||
private void BreakOut(TcpCore core, bool manual, string 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 _))
|
||||
{
|
||||
@@ -282,7 +263,10 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
#endregion Internal
|
||||
|
||||
#region 事件&委托
|
||||
@@ -377,10 +361,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
|
||||
private Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
return this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
|
||||
private async Task PrivateOnDisconnected(object obj)
|
||||
{
|
||||
@@ -397,10 +377,13 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
var tcp = this.m_tcpCore;
|
||||
this.m_tcpCore = null;
|
||||
this.Service?.ReturnTcpCore(tcp);
|
||||
this.Service.ReturnTcpCore(tcp);
|
||||
}
|
||||
}
|
||||
|
||||
private Task PrivateOnDisconnecting(object obj)
|
||||
{
|
||||
return this.OnDisconnecting((DisconnectEventArgs)obj);
|
||||
}
|
||||
#endregion 事件&委托
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -424,7 +407,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
|
||||
this.MainSocket.TryClose();
|
||||
this.BreakOut(default, true, msg);
|
||||
this.BreakOut(true, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -505,30 +488,13 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
if (this.Online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
|
||||
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当Id更新的时候触发
|
||||
@@ -571,6 +537,24 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
|
||||
/// </summary>
|
||||
/// <param name="buffer">数据缓存区</param>
|
||||
/// <param name="offset">偏移</param>
|
||||
/// <param name="length">长度</param>
|
||||
/// <returns>返回值表示是否允许发送</returns>
|
||||
protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0)
|
||||
{
|
||||
var args = new SendingEventArgs(buffer, offset, length);
|
||||
await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false);
|
||||
return args.IsPermitOperation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
|
||||
/// </summary>
|
||||
@@ -625,6 +609,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetTcpCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -856,18 +845,19 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
|
||||
private Receiver m_receiver;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ClearReceiver()
|
||||
{
|
||||
this.m_receiver = null;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IReceiver CreateReceiver()
|
||||
{
|
||||
return this.m_receiver ??= new Receiver(this);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -280,7 +280,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
|
||||
this.MainSocket.TryClose();
|
||||
this.BreakOut(default, true, msg);
|
||||
this.BreakOut(true, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
if (this.m_online)
|
||||
{
|
||||
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
|
||||
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
|
||||
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
@@ -502,7 +502,17 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
return this.GetIPPort();
|
||||
}
|
||||
private void BreakOut(TcpCore core, bool manual, string msg)
|
||||
|
||||
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
|
||||
{
|
||||
this.BreakOut(manual, msg);
|
||||
}
|
||||
/// <summary>
|
||||
/// BreakOut。
|
||||
/// </summary>
|
||||
/// <param name="manual"></param>
|
||||
/// <param name="msg"></param>
|
||||
protected void BreakOut(bool manual, string msg)
|
||||
{
|
||||
lock (this.SyncRoot)
|
||||
{
|
||||
@@ -901,6 +911,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (this.SendingData(buffer, offset, length).GetFalseAwaitResult())
|
||||
{
|
||||
if (this.m_delaySender != null)
|
||||
{
|
||||
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
|
||||
return;
|
||||
}
|
||||
this.GetTcpCore().Send(buffer, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -931,11 +946,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
|
||||
if (delaySenderOption != null)
|
||||
{
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.MainSocket.AbsoluteSend);
|
||||
this.m_delaySender = new DelaySender(delaySenderOption, this.GetTcpCore().Send);
|
||||
}
|
||||
this.m_tcpCore.Reset(socket);
|
||||
this.m_tcpCore.OnReceived = this.HandleReceived;
|
||||
this.m_tcpCore.OnBreakOut = this.BreakOut;
|
||||
this.m_tcpCore.OnBreakOut = this.TcpCoreBreakOut;
|
||||
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
|
||||
{
|
||||
this.m_tcpCore.MinBufferSize = minValue;
|
||||
|
@@ -493,6 +493,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public override IService Stop()
|
||||
{
|
||||
foreach (var item in m_monitors)
|
||||
{
|
||||
Logger.Info($"{item.Option.IpHost}停止成功");
|
||||
}
|
||||
|
||||
foreach (var item in this.m_monitors)
|
||||
{
|
||||
item.Socket.SafeDispose();
|
||||
@@ -603,6 +608,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
foreach (var item in optionList)
|
||||
{
|
||||
this.AddListen(item);
|
||||
Logger.Info($"{item.IpHost}启动成功");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -204,7 +204,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public class UdpPackageAdapter : UdpDataHandlingAdapter
|
||||
{
|
||||
private readonly SnowflakeIdGenerator m_iDGenerator;
|
||||
private readonly ConcurrentDictionary<long, UdpPackage> revStore;
|
||||
private readonly ConcurrentDictionary<long, UdpPackage> m_revStore;
|
||||
private int m_mtu = 1472;
|
||||
|
||||
/// <summary>
|
||||
@@ -212,7 +212,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public UdpPackageAdapter()
|
||||
{
|
||||
this.revStore = new ConcurrentDictionary<long, UdpPackage>();
|
||||
this.m_revStore = new ConcurrentDictionary<long, UdpPackage>();
|
||||
this.m_iDGenerator = new SnowflakeIdGenerator(4);
|
||||
}
|
||||
|
||||
@@ -250,17 +250,17 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
var udpFrame = new UdpFrame();
|
||||
if (udpFrame.Parse(byteBlock.Buffer, 0, byteBlock.Len))
|
||||
{
|
||||
var udpPackage = this.revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.revStore));
|
||||
var udpPackage = this.m_revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.m_revStore));
|
||||
udpPackage.Add(udpFrame);
|
||||
if (udpPackage.Length > this.MaxPackageSize)
|
||||
{
|
||||
this.revStore.TryRemove(udpPackage.Id, out _);
|
||||
this.m_revStore.TryRemove(udpPackage.Id, out _);
|
||||
this.Logger?.Error("数据长度大于设定的最大值。");
|
||||
return;
|
||||
}
|
||||
if (udpPackage.IsComplated)
|
||||
{
|
||||
if (this.revStore.TryRemove(udpPackage.Id, out _))
|
||||
if (this.m_revStore.TryRemove(udpPackage.Id, out _))
|
||||
{
|
||||
using (var block = new ByteBlock(udpPackage.Length))
|
||||
{
|
||||
|
@@ -34,7 +34,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public NotConnectedException()
|
||||
public NotConnectedException() : this(TouchSocketResource.NotConnected.GetDescription())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
|
@@ -42,7 +42,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public async Task<ReceiverResult> ReadAsync(CancellationToken token)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
await this.m_resetEventForRead.WaitOneAsync(token);
|
||||
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
|
||||
return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public async ValueTask<ReceiverResult> ValueReadAsync(CancellationToken token)
|
||||
{
|
||||
this.ThrowIfDisposed();
|
||||
await this.m_resetEventForRead.WaitOneAsync(token);
|
||||
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
|
||||
return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo);
|
||||
}
|
||||
#endif
|
||||
|
@@ -28,7 +28,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
internal class WaitingClient<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, ISender
|
||||
{
|
||||
private readonly EasyLock m_semaphoreSlim = new();
|
||||
private volatile bool m_breaked;
|
||||
private CancellationTokenSource m_cancellationTokenSource;
|
||||
|
||||
|
||||
@@ -75,8 +74,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
try
|
||||
{
|
||||
this.m_semaphoreSlim.Wait();
|
||||
this.m_breaked = false;
|
||||
this.m_semaphoreSlim.Wait(token);
|
||||
if (token.CanBeCanceled)
|
||||
{
|
||||
this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
|
||||
@@ -85,7 +83,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
this.m_cancellationTokenSource = new CancellationTokenSource(5000);
|
||||
}
|
||||
using (m_cancellationTokenSource)
|
||||
using (this.m_cancellationTokenSource)
|
||||
{
|
||||
if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session)
|
||||
{
|
||||
@@ -113,7 +111,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (receiverResult.IsClosed)
|
||||
{
|
||||
this.m_breaked = true;
|
||||
this.Cancel();
|
||||
}
|
||||
var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo);
|
||||
@@ -135,10 +132,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException();
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_cancellationTokenSource = null;
|
||||
@@ -156,8 +149,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
try
|
||||
{
|
||||
await this.m_semaphoreSlim.WaitAsync();
|
||||
this.m_breaked = false;
|
||||
await this.m_semaphoreSlim.WaitAsync(token);
|
||||
if (token.CanBeCanceled)
|
||||
{
|
||||
this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
|
||||
@@ -166,7 +158,7 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
this.m_cancellationTokenSource = new CancellationTokenSource(5000);
|
||||
}
|
||||
using (m_cancellationTokenSource)
|
||||
using (this.m_cancellationTokenSource)
|
||||
{
|
||||
if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session)
|
||||
{
|
||||
@@ -194,7 +186,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
{
|
||||
if (receiverResult.IsClosed)
|
||||
{
|
||||
this.m_breaked = true;
|
||||
this.Cancel();
|
||||
}
|
||||
var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo);
|
||||
@@ -216,10 +207,6 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException();
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.m_cancellationTokenSource = null;
|
||||
|
@@ -91,8 +91,15 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
public static ResponsedData SendThenResponse<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
where TClient : IClient, ISender
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
if (token.CanBeCanceled)
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
return client.SendThenResponse(buffer, 0, buffer.Length, token);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送数据并等待
|
||||
@@ -105,11 +112,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// <exception cref="OverlengthException">发送数据超长</exception>
|
||||
/// <exception cref="Exception">其他异常</exception>
|
||||
/// <returns>返回的数据</returns>
|
||||
public static Task<ResponsedData> SendThenResponseAsync<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
public static async Task<ResponsedData> SendThenResponseAsync<TClient>(this IWaitingClient<TClient> client, byte[] buffer, int timeout, CancellationToken token)
|
||||
where TClient : IClient, ISender
|
||||
{
|
||||
using CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(timeout).Token, token);
|
||||
return client.SendThenResponseAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
return await client.SendThenResponseAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -30,22 +30,11 @@ namespace ThingsGateway.Foundation.Sockets
|
||||
/// </summary>
|
||||
public class WaitingOptions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 当Client为Tcp系时。是否在断开连接时立即触发结果。默认会返回null。当<see cref="ThrowBreakException"/>为<see langword="true"/>时,会触发异常。
|
||||
/// </summary>
|
||||
public bool BreakTrigger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 远程地址(仅在Udp模式下生效)
|
||||
/// </summary>
|
||||
public IPHost RemoteIPHost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当Client为Tcp系时。是否在断开连接时以异常返回结果。
|
||||
/// </summary>
|
||||
public bool ThrowBreakException { get; set; } = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 筛选函数
|
||||
|
@@ -75,7 +75,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
var bytes = new byte[stream.Length];
|
||||
stream.Read(bytes, 0, bytes.Length);
|
||||
var prefix = this.Prefix.IsNullOrEmpty() ? "/" : (this.Prefix.StartsWith("/") ? this.Prefix : $"/{this.Prefix}");
|
||||
var name = item.Replace("ThingsGateway.Foundation.WebApi.Swagger.api.", string.Empty);
|
||||
var name = item.Replace("ThingsGateway.Foundation.TouchSocket.WebApi.Swagger.api.", string.Empty);
|
||||
if (name == "openapi.json")
|
||||
{
|
||||
try
|
||||
@@ -251,7 +251,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
Summary = methodInstance.GetDescription()
|
||||
};
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
@@ -312,7 +312,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
};
|
||||
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ namespace ThingsGateway.Foundation.WebApi.Swagger
|
||||
openApiPathValue.Parameters = parameters.Count > 0 ? parameters : default;
|
||||
|
||||
ParameterInfo parameterInfo = null;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
if (methodInstance.Parameters.Length > 1)
|
||||
{
|
||||
|
@@ -63,7 +63,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
public override string GetInvokenKey(MethodInstance methodInstance)
|
||||
{
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
i = 1;
|
||||
}
|
||||
|
@@ -111,7 +111,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
{
|
||||
ps = new object[methodInstance.Parameters.Length];
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps[i] = callContext;
|
||||
i++;
|
||||
@@ -227,7 +227,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
int index;
|
||||
ps = new object[methodInstance.Parameters.Length];
|
||||
var i = 0;
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
ps[i] = callContext;
|
||||
i++;
|
||||
@@ -263,7 +263,7 @@ namespace ThingsGateway.Foundation.WebApi
|
||||
if (index >= 0)
|
||||
{
|
||||
var str = e.Context.Request.GetBody();
|
||||
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
|
||||
if (methodInstance.IncludeCallContext)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.0.20</Version>
|
||||
<Version>3.0.0.25</Version>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.2.0" />
|
||||
<PackageReference Include="Confluent.Kafka" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
@@ -20,6 +20,7 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
@@ -310,7 +311,9 @@ public class IotSharpClient : UpLoadBase
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(UploadDeviceRunTime device)
|
||||
{
|
||||
var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage));
|
||||
var log = new MqttNetEventLogger();
|
||||
log.LogMessagePublished += Log_LogMessagePublished;
|
||||
var mqttFactory = new MqttFactory(log);
|
||||
_mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
|
||||
.WithClientId(Guid.NewGuid().ToString())
|
||||
.WithCredentials(driverPropertys.Accesstoken)//账密
|
||||
@@ -355,6 +358,11 @@ public class IotSharpClient : UpLoadBase
|
||||
exDeviceTimerTick = new(driverPropertys.UploadInterval);
|
||||
}
|
||||
|
||||
private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
||||
{
|
||||
LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception);
|
||||
}
|
||||
|
||||
private void DeviceStatusChange(CollectDeviceRunTime collectDeviceRunTime)
|
||||
{
|
||||
if (driverPropertys?.IsInterval != true)
|
||||
|
@@ -18,6 +18,7 @@ using Microsoft.Extensions.Logging;
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text;
|
||||
@@ -300,7 +301,9 @@ public class MqttClient : UpLoadBase
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(UploadDeviceRunTime device)
|
||||
{
|
||||
var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage));
|
||||
var log = new MqttNetEventLogger();
|
||||
log.LogMessagePublished += Log_LogMessagePublished;
|
||||
var mqttFactory = new MqttFactory(log);
|
||||
_mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
|
||||
.WithClientId(driverPropertys.ConnectId)
|
||||
.WithCredentials(driverPropertys.UserName, driverPropertys.Password)//账密
|
||||
@@ -353,6 +356,11 @@ public class MqttClient : UpLoadBase
|
||||
|
||||
}
|
||||
|
||||
private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
||||
{
|
||||
LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception);
|
||||
}
|
||||
|
||||
private async Task AllPublishAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
//保留消息
|
||||
|
@@ -17,6 +17,7 @@ using Mapster;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
@@ -224,7 +225,9 @@ public class MqttServer : UpLoadBase
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(UploadDeviceRunTime device)
|
||||
{
|
||||
var mqttFactory = new MqttFactory(new PrivateLogger(LogMessage));
|
||||
var log = new MqttNetEventLogger();
|
||||
log.LogMessagePublished += Log_LogMessagePublished;
|
||||
var mqttFactory = new MqttFactory(log);
|
||||
var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder()
|
||||
.WithDefaultEndpointBoundIPAddress(string.IsNullOrEmpty(driverPropertys.IP) ? null : IPAddress.Parse(driverPropertys.IP))
|
||||
.WithDefaultEndpointPort(driverPropertys.Port)
|
||||
@@ -251,7 +254,11 @@ public class MqttServer : UpLoadBase
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
||||
{
|
||||
if (e.LogMessage.Exception is not ArgumentNullException)
|
||||
LogMessage.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception);
|
||||
}
|
||||
private void DeviceStatusChange(CollectDeviceRunTime collectDeviceRunTime)
|
||||
{
|
||||
_collectDeviceRunTimes.Enqueue(collectDeviceRunTime.Adapt<DeviceData>());
|
||||
|
@@ -12,10 +12,11 @@
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Plugin.Mqtt;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
|
||||
namespace ThingsGateway.Foundation.Demo;
|
||||
/// <summary>
|
||||
@@ -56,14 +57,19 @@ public partial class MqttClientPage
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
MqttFactory = new MqttFactory(new PrivateLogger(new EasyLogger(LogAction) { LogLevel = LogLevel.Trace }));
|
||||
var log = new MqttNetEventLogger();
|
||||
log.LogMessagePublished += Log_LogMessagePublished;
|
||||
MqttFactory = new MqttFactory(log);
|
||||
|
||||
|
||||
MqttClient = MqttFactory.CreateMqttClient();
|
||||
MqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
private void Log_LogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
|
||||
{
|
||||
new EasyLogger(LogAction) { LogLevel = LogLevel.Trace }.LogOut(e.LogMessage.Level, e.LogMessage.Source, e.LogMessage.Message, e.LogMessage.Exception);
|
||||
}
|
||||
private async Task Connect()
|
||||
{
|
||||
try
|
||||
|
@@ -1,49 +0,0 @@
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
namespace ThingsGateway.Plugin.Mqtt
|
||||
{
|
||||
internal class PrivateLogger : IMqttNetLogger
|
||||
{
|
||||
readonly ILog LogMessage;
|
||||
public PrivateLogger(ILog logger)
|
||||
{
|
||||
LogMessage = logger;
|
||||
}
|
||||
|
||||
public bool IsEnabled => true;
|
||||
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
|
||||
{
|
||||
switch (logLevel)
|
||||
{
|
||||
case MqttNetLogLevel.Verbose:
|
||||
LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Info:
|
||||
LogMessage?.Log(LogLevel.Info, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Warning:
|
||||
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
|
||||
case MqttNetLogLevel.Error:
|
||||
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#region copyright
|
||||
#region copyright
|
||||
//------------------------------------------------------------------------------
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
|
||||
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
|
||||
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
|
||||
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQȺ<EFBFBD><EFBFBD>605534569
|
||||
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
|
||||
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议
|
||||
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
|
||||
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
|
||||
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
|
||||
namespace ThingsGateway.Plugin.OPCUA;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@@ -0,0 +1,39 @@
|
||||
#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 Opc.Ua.Configuration;
|
||||
|
||||
namespace ThingsGateway.Plugin.OPCUA;
|
||||
|
||||
|
||||
public partial class OPCUAServer
|
||||
{
|
||||
public class ApplicationMessageDlg : IApplicationMessageDlg
|
||||
{
|
||||
private string message = string.Empty;
|
||||
private ILog _log;
|
||||
public ApplicationMessageDlg(ILog log)
|
||||
{
|
||||
_log = log;
|
||||
}
|
||||
public override void Message(string text, bool ask)
|
||||
{
|
||||
message = text;
|
||||
}
|
||||
|
||||
public override async Task<bool> ShowAsync()
|
||||
{
|
||||
_log.Warning(message);
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
#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;
|
||||
|
||||
namespace ThingsGateway.Plugin.OPCUA;
|
||||
|
||||
|
||||
public partial class OPCUAServer
|
||||
{
|
||||
private class OPCUALogger : ILogger
|
||||
{
|
||||
private ILog _log;
|
||||
public OPCUALogger(ILog log)
|
||||
{
|
||||
_log = log;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the log level
|
||||
/// </summary>
|
||||
public Microsoft.Extensions.Logging.LogLevel LogLevel { get; set; } = Microsoft.Extensions.Logging.LogLevel.Trace;
|
||||
/// <inheritdoc/>
|
||||
public IDisposable BeginScope<TState>(TState state) => default;
|
||||
/// <inheritdoc/>
|
||||
public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) => logLevel >= LogLevel;
|
||||
/// <inheritdoc/>
|
||||
public void Log<TState>(
|
||||
Microsoft.Extensions.Logging.LogLevel logLevel,
|
||||
EventId eventId,
|
||||
TState state,
|
||||
Exception exception,
|
||||
Func<TState, Exception, string> formatter)
|
||||
{
|
||||
if (!IsEnabled(logLevel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = formatter(state, exception);
|
||||
_log.Log((Foundation.Core.LogLevel)(byte)logLevel, state, message, exception);
|
||||
if (logLevel > Microsoft.Extensions.Logging.LogLevel.Information)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -63,7 +63,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
public override async Task BeforStartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// 启动服务器。
|
||||
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
|
||||
await m_application.CheckApplicationInstanceCertificate(false, 0, 1200);
|
||||
await m_application.Start(m_server);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
@@ -90,7 +90,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
}
|
||||
if (driverPropertys.CycleInterval > UploadDeviceThread.CycleInterval + 50)
|
||||
{
|
||||
@@ -138,9 +138,13 @@ public partial class OPCUAServer : UpLoadBase
|
||||
_uploadVariables = null;
|
||||
CollectVariableRunTimes.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Init(UploadDeviceRunTime device)
|
||||
{
|
||||
ApplicationInstance.MessageDlg = new ApplicationMessageDlg(LogMessage);//默认返回true
|
||||
|
||||
//Utils.SetLogger(new OPCUALogger(LogMessage)); //调试用途
|
||||
m_application = new ApplicationInstance();
|
||||
m_configuration = GetDefaultConfiguration();
|
||||
m_configuration.Validate(ApplicationType.Server).GetAwaiter().GetResult();
|
||||
@@ -169,7 +173,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
private ApplicationConfiguration GetDefaultConfiguration()
|
||||
{
|
||||
ApplicationConfiguration config = new();
|
||||
string url = driverPropertys.OpcUaStringUrl;
|
||||
var urls = driverPropertys.OpcUaStringUrl.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
// 签名及加密验证
|
||||
ServerSecurityPolicyCollection policies = new();
|
||||
var userTokens = new UserTokenPolicyCollection();
|
||||
@@ -242,13 +246,14 @@ public partial class OPCUAServer : UpLoadBase
|
||||
|
||||
config.ApplicationName = "ThingsGateway OPCUAServer";
|
||||
config.ApplicationType = ApplicationType.Server;
|
||||
config.ApplicationUri = Utils.Format(@"urn:{0}:thingsgatewayopcuaserver", System.Net.Dns.GetHostName());
|
||||
config.ApplicationUri = driverPropertys.ApplicationUri;
|
||||
|
||||
|
||||
config.ServerConfiguration = new ServerConfiguration()
|
||||
{
|
||||
// 配置登录的地址
|
||||
BaseAddresses = new string[] { url },
|
||||
BaseAddresses = urls,
|
||||
|
||||
SecurityPolicies = policies,
|
||||
UserTokenPolicies = userTokens,
|
||||
ShutdownDelay = 1,
|
||||
@@ -269,7 +274,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
MaxNotificationQueueSize = 100, // 为每个被监视项目保存在队列中的最大证书数
|
||||
MaxNotificationsPerPublish = 1000, // 每次发布的最大通知数
|
||||
MinMetadataSamplingInterval = 1000, // 元数据的最小采样间隔
|
||||
MaxRegistrationInterval = 30000, // 两次注册尝试之间的最大时间(以毫秒为单位)
|
||||
MaxRegistrationInterval = -1, // 两次注册尝试之间的最大时间(以毫秒为单位)//不提供注册
|
||||
|
||||
};
|
||||
config.SecurityConfiguration = new SecurityConfiguration()
|
||||
@@ -283,7 +288,8 @@ public partial class OPCUAServer : UpLoadBase
|
||||
{
|
||||
StoreType = CertificateStoreType.X509Store,
|
||||
StorePath = "CurrentUser\\UAServer_ThingsGateway",
|
||||
SubjectName = "CN=ThingsGateway OPCUAServer, C=CN, S=GUANGZHOU, O=ThingsGateway, DC=" + System.Net.Dns.GetHostName(),
|
||||
SubjectName = driverPropertys.SubjectName,
|
||||
//ValidationOptions = CertificateValidationOptions.SuppressHostNameInvalid,
|
||||
},
|
||||
|
||||
TrustedPeerCertificates = new CertificateTrustList()
|
||||
@@ -323,7 +329,7 @@ public partial class OPCUAServer : UpLoadBase
|
||||
|
||||
|
||||
config.CertificateValidator = new CertificateValidator();
|
||||
config.CertificateValidator.Update(config);
|
||||
config.CertificateValidator.Update(config).GetAwaiter().GetResult();
|
||||
config.Extensions = new XmlElementCollection();
|
||||
|
||||
return config;
|
||||
|
@@ -10,6 +10,8 @@
|
||||
//------------------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using Opc.Ua;
|
||||
|
||||
namespace ThingsGateway.Plugin.OPCUA;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -18,8 +20,21 @@ public class OPCUAServerProperty : UpDriverPropertyBase
|
||||
/// <summary>
|
||||
/// 服务地址
|
||||
/// </summary>
|
||||
[DeviceProperty("服务地址", "")]
|
||||
[DeviceProperty("服务地址", "分号分割数组,可设置多个url")]
|
||||
public string OpcUaStringUrl { get; set; } = "opc.tcp://127.0.0.1:49321";
|
||||
/// <summary>
|
||||
/// SubjectName
|
||||
/// </summary>
|
||||
[DeviceProperty("SubjectName", "")]
|
||||
public string SubjectName { get; set; } = "CN=ThingsGateway OPCUAServer, C=CN, S=GUANGZHOU, O=ThingsGateway, DC=" + System.Net.Dns.GetHostName();
|
||||
|
||||
/// <summary>
|
||||
/// ApplicationUri
|
||||
/// </summary>
|
||||
[DeviceProperty("ApplicationUri", "")]
|
||||
public string ApplicationUri { get; set; } = Utils.Format(@"urn:{0}:thingsgatewayopcuaserver", System.Net.Dns.GetHostName());
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 安全策略
|
||||
/// </summary>
|
||||
|
@@ -299,7 +299,7 @@ public class QuestDB : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ public class QuestDB : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
await CacheDb.AddCacheData("", dbInserts.ToJsonString(), driverPropertys.CacheMaxCount);
|
||||
}
|
||||
|
||||
|
@@ -67,6 +67,8 @@ public class SQLDB : UpLoadBase
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private bool readDBInitSuccess;
|
||||
|
||||
public override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var db = GetHisDbAsync();
|
||||
@@ -75,14 +77,33 @@ public class SQLDB : UpLoadBase
|
||||
{
|
||||
if (exRealTimerTick.IsTickHappen())
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var varList = _uploadVariables.ToList().Adapt<List<SQLRealValue>>();
|
||||
|
||||
if (!readDBInitSuccess)
|
||||
{
|
||||
//事务
|
||||
var result = db.UseTran(() =>
|
||||
{
|
||||
db.Storageable(varList).As(driverPropertys.ReadDBTableName).PageSize(10000).ExecuteSqlBulkCopy();
|
||||
//db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkMerge(varList);
|
||||
});
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
readDBInitSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new(result.ErrorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (varList?.Count != 0)
|
||||
{
|
||||
//var result = await db.Storageable(varList).As(driverPropertys.ReadDBTableName).ExecuteCommandAsync(cancellationToken);
|
||||
await db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdateAsync(varList);
|
||||
|
||||
db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdate(varList);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -180,6 +201,7 @@ public class SQLDB : UpLoadBase
|
||||
{
|
||||
try
|
||||
{
|
||||
readDBInitSuccess = false;
|
||||
_globalDeviceData?.AllVariables?.ForEach(a => a.VariableValueChange -= VariableValueChange);
|
||||
_uploadVariables = null;
|
||||
}
|
||||
@@ -307,7 +329,7 @@ public class SQLDB : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
}
|
||||
|
||||
|
||||
@@ -316,7 +338,7 @@ public class SQLDB : UpLoadBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogMessage.LogWarning(ex);
|
||||
LogMessage.LogWarning(ex);
|
||||
await CacheDb.AddCacheData("", dbInserts.ToJsonString(), driverPropertys.CacheMaxCount);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user