Compare commits

...

42 Commits

Author SHA1 Message Date
Kimdiego2098
7ba9ac7a5b 报文显示限长500 2023-10-27 14:53:19 +08:00
Kimdiego2098
85b8f26e8e tcpserver 报文输出 添加 ip端口 提示 2023-10-27 14:41:35 +08:00
Kimdiego2098
594a0f1410 update the tcpserver class and add log output for start and stop 2023-10-27 14:24:26 +08:00
Kimdiego2098
d317d757d7 优化线程上下文转换 2023-10-26 19:16:24 +08:00
Kimdiego2098
fdf0ba6318 添加ConfigureAwait 2023-10-26 18:06:33 +08:00
Kimdiego2098
15bf7de5fa 优化设备导出逻辑 2023-10-26 15:15:43 +08:00
Kimdiego2098
d3402b058e 优化设备导出逻辑 2023-10-26 15:10:26 +08:00
Kimdiego2098
e7dfdd4031 3.0.0.25 2023-10-26 13:21:40 +08:00
Kimdiego2098
b2dd7b6364 Merge branch 'master' of https://gitee.com/dotnetchina/ThingsGateway 2023-10-26 13:20:54 +08:00
Kimdiego2098
9bd6d9abbf 3.0.0.25 2023-10-26 13:20:31 +08:00
Kimdiego2098
cd14428fea update 2023-10-26 13:19:18 +08:00
Kimdiego2098
19d9f03c2b s7添加错误返回码提示,组包处理 2023-10-26 13:05:06 +08:00
Kimdiego2098
0d57e72bbf 增加硬件信息 相关json配置 2023-10-26 10:54:48 +08:00
Kimdiego2098
329516a61b 更新nuget依赖 2023-10-26 09:37:01 +08:00
Kimdiego2098
d566869589 硬件信息页面添加刷新条件 2023-10-26 09:20:25 +08:00
Kimdiego2098
9cb8d8e6c7 更新文档 2023-10-25 00:53:27 +08:00
Kimdiego2098
9de3c57e5d update touchsocket 2023-10-25 00:53:17 +08:00
Kimdiego2098
f32ff92b0b <Version>3.0.0.24</Version> 2023-10-24 23:48:20 +08:00
Kimdiego2098
88d71e271e 更改S7协议 设备属性,注意删除了DstTSAP,改为较直观的 机架号/槽位号 2023-10-24 23:47:35 +08:00
Kimdiego2098
fd9c14612a 添加属性识别 16进制写入 2023-10-24 23:46:50 +08:00
Kimdiego2098
e26e5a160f 添加nuget依赖包 2023-10-24 20:50:39 +08:00
Kimdiego2098
b836bfed22 更新nuget包 2023-10-24 00:37:46 +08:00
Kimdiego2098
a4b598c6d0 调整解决方案文件夹 2023-10-24 00:13:03 +08:00
Kimdiego2098
c9ab755839 暂时屏蔽mqttserver 遗留消息错误 2023-10-23 20:51:11 +08:00
Kimdiego2098
9920edba53 调整编码 2023-10-23 20:47:00 +08:00
Kimdiego2098
12bd7280d1 调整mqttlog 2023-10-23 20:46:17 +08:00
Kimdiego2098
d30ea7f63b 调整mqttlog 2023-10-23 20:43:58 +08:00
Kimdiego2098
ebd3390db6 添加部分兼容方法 2023-10-22 02:42:16 +08:00
Kimdiego2098
9a374a9ebc 添加部分兼容方法 2023-10-22 02:26:18 +08:00
Kimdiego2098
b1bc22cb08 update touchsocket 2023-10-22 02:26:04 +08:00
Kimdiego2098
4930d53890 调整代码格式 2023-10-21 19:15:26 +08:00
Kimdiego2098
c31327b5bc update touchsocket 2023-10-21 19:08:21 +08:00
Kimdiego2098
3f2aa1f1e1 调整代码格式 2023-10-21 19:03:15 +08:00
Kimdiego2098
6e78c00a96 调整代码格式 2023-10-21 19:02:58 +08:00
Kimdiego2098
c27dde085e 3.0.0.23 2023-10-20 21:38:22 +08:00
Kimdiego2098
d26cc308c0 优化SQLDB实时表模式,插入/更新 2023-10-20 21:38:07 +08:00
Kimdiego2098
fb1efdf290 sqlsugar提示默认中文 2023-10-20 21:37:42 +08:00
Kimdiego2098
3c99f2a472 update touchsocket 2023-10-20 21:03:29 +08:00
Kimdiego2098
affe9a44e0 优化 ModbusServer 内存占用 2023-10-20 01:53:48 +08:00
Kimdiego2098
43730fa519 3.0.0.21 2023-10-20 01:19:18 +08:00
Kimdiego2098
d39aa22b09 优化OPCUAServer,取消注册,提供多url写入 2023-10-20 01:19:05 +08:00
Kimdiego2098
e232a6b6ea 更新赞助名单 2023-10-19 21:15:35 +08:00
194 changed files with 3601 additions and 1942 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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",

View File

@@ -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>

View File

@@ -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>

View File

@@ -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/>

View File

@@ -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;
}

View File

@@ -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/>

View File

@@ -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

View File

@@ -1,5 +1,4 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -9,7 +8,6 @@
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Opc.Ua;

View File

@@ -11,5 +11,4 @@
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
</ItemGroup>
</Project>

View File

@@ -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);
}
}

View File

@@ -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
{

View File

@@ -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;
}
}

View File

@@ -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 成功

View File

@@ -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
无法为模块例如FMCP分配参数。系统数据无法链接
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
在RUNCiR中配置时发生错误
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错误; 资源集不存在

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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/>

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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();
}
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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()

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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);
}
}
}

View File

@@ -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>
/// 元数据

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -10,6 +10,9 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>

View File

@@ -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(

View File

@@ -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;

View File

@@ -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"/>

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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:
{

View File

@@ -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

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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);
}
}

View File

@@ -58,7 +58,7 @@ namespace ThingsGateway.Foundation.Dmtp
failedCount++;
if (failedCount > this.MaxFailCount)
{
client.DmtpActor.Close(true, "自动心跳失败次数达到最大,已断开连接。");
client.DmtpActor.Close("自动心跳失败次数达到最大,已断开连接。");
}
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
});
}
}
}

View File

@@ -20,6 +20,6 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 查找其他IDmtpActor
/// </summary>
Func<string, IDmtpActor> FindDmtpActor { get; set; }
Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; }
}
}

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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);

View File

@@ -302,7 +302,7 @@ namespace ThingsGateway.Foundation.Rpc
}
var i = 0;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
if (methodInstance.IncludeCallContext)
{
i = 1;
}

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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>

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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>
/// 发送

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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;

View File

@@ -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}启动成功");
}
}

View File

@@ -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))
{

View File

@@ -34,7 +34,7 @@ namespace ThingsGateway.Foundation.Sockets
/// <summary>
/// 构造函数
/// </summary>
public NotConnectedException()
public NotConnectedException() : this(TouchSocketResource.NotConnected.GetDescription())
{ }
/// <summary>

View File

@@ -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

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>
/// 筛选函数

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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++;
}

View File

@@ -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>

View File

@@ -6,7 +6,7 @@
</Target>
<ItemGroup>
<PackageReference Include="Confluent.Kafka" Version="2.2.0" />
<PackageReference Include="Confluent.Kafka" Version="2.3.0" />
</ItemGroup>
<PropertyGroup>

View File

@@ -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)

View File

@@ -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)
{
//保留消息

View File

@@ -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>());

View File

@@ -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

View File

@@ -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;
}
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Plugin.OPCUA;
/// <inheritdoc/>

View File

@@ -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);
}
}
}

View File

@@ -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)
{
}
}
}
}
}

View File

@@ -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;

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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