Compare commits

..

71 Commits

Author SHA1 Message Date
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
Kimdiego2098
71ebb36fe9 更新文档 2023-10-19 20:36:28 +08:00
Kimdiego2098
78a0b86327 更新版本:3.0.0.20 2023-10-19 20:27:31 +08:00
Kimdiego2098
2636c16a97 优化modbusServer内存管理 2023-10-19 20:24:39 +08:00
Kimdiego2098
fd77c0242d update touchsocket 2023-10-19 20:23:43 +08:00
Kimdiego2098
e74819a900 update toucksocket 2023-10-18 21:51:49 +08:00
Kimdiego2098
9b7f696c9b 更新文档 2023-10-18 20:42:10 +08:00
Kimdiego2098
0230d614e7 发布驱动包 2023-10-18 18:04:37 +08:00
Diego2098
252d99ad78 !12 【轻量级 PR】:修正心跳事件中的参数
Merge pull request !12 from youthalan/N/A
2023-10-18 06:59:17 +00:00
youthalan
1ffc200350 修正心跳事件中的参数
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 06:58:03 +00:00
Kimdiego2098
807d89b2b2 更新版本号 2023-10-18 13:13:03 +08:00
Kimdiego2098
4013afa1f1 初始化 采集/上传线程时 直接返回线程控制 2023-10-18 13:11:59 +08:00
Kimdiego2098
a580927ceb 更新OPCUAClient类库 2023-10-18 13:09:25 +08:00
Kimdiego2098
bf2cf52034 更新OPCUAClient类库 2023-10-18 12:45:26 +08:00
Kimdiego2098
81bb8b7c31 更新OPCUAClient类库 2023-10-18 12:44:58 +08:00
Kimdiego2098
a825007fb5 更新版本号与nuget发布 2023-10-18 12:39:42 +08:00
Kimdiego2098
988124d96a 更新OPCUAClient类库 2023-10-18 12:38:20 +08:00
Diego2098
f0de815296 !11 补充OPCClient类库事件的缺失文件
Merge pull request !11 from youthalan/N/A
2023-10-18 04:34:34 +00:00
youthalan
0e2d58c887 补充OPCClient类库事件的缺失文件
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 04:32:39 +00:00
Diego2098
b155382626 !10 添加连接或断开事件
Merge pull request !10 from youthalan/N/A
2023-10-18 04:20:22 +00:00
youthalan
f362d740af 修改OPCUAClient类添加连接或断开事件,修改注入时不需要带参数
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 03:48:05 +00:00
Kimdiego2098
4a85e31a4f update 3.0.0.16 2023-10-18 00:38:36 +08:00
Kimdiego2098
302c270ad5 opcuaClient浏览空间 添加是否显示子变量的选项 2023-10-18 00:36:44 +08:00
Kimdiego2098
3c1517d0f3 更改日志输出内容 2023-10-18 00:15:07 +08:00
Kimdiego2098
f9fb222044 update 3.0.0.15 2023-10-18 00:07:24 +08:00
Kimdiego2098
e8edc02ba3 增加不支持单文件发布的说明 2023-10-17 23:47:24 +08:00
Kimdiego2098
95a44e3053 update tdengineDB plugin 2023-10-17 23:43:48 +08:00
Kimdiego2098
74a9fe9a87 update touchsocket 2023-10-17 23:12:19 +08:00
Kimdiego2098
4d03f9ea1a TD时序库插件,创建时间更改为主键 2023-10-17 23:08:09 +08:00
Kimdiego2098
67c96ca991 update touchsocket 2023-10-17 23:06:21 +08:00
Kimdiego2098
88fb793c68 更新nuget包 2023-10-17 21:00:50 +08:00
Kimdiego2098
d6d02d8cc5 update SQLDB 2023-10-16 20:50:10 +08:00
Kimdiego2098
c5a3f8e2e3 update touchsocket and other 2023-10-16 20:36:51 +08:00
Kimdiego2098
27e8653a1a 3.0.0.13 2023-10-16 17:44:09 +08:00
Kimdiego2098
863beda82c 增加关系库存储插件; 2023-10-16 17:40:17 +08:00
Kimdiego2098
bac84c3ecd 增加时序库存储插件; 2023-10-16 17:40:13 +08:00
Kimdiego2098
2fca2ad9f8 更新pro用户列表 2023-10-16 17:39:14 +08:00
Kimdiego2098
dd75286fe0 3.0.0.12 2023-10-16 08:47:39 +08:00
Kimdiego2098
7f91792cf1 opcuaclient添加是否加载服务端数据类型的选项 2023-10-16 08:46:46 +08:00
Kimdiego2098
0e0ccad311 fix:tcpservice dispose err 2023-10-16 08:46:32 +08:00
Diego2098
0691f72e67 !9 增加可选择安全订阅
Merge pull request !9 from youthalan/N/A
2023-10-16 00:33:19 +00:00
youthalan
7e38a51720 增加可选择安全订阅,以加快订阅速度
Signed-off-by: youthalan <youthalan@126.com>
2023-10-16 00:26:59 +00:00
Kimdiego2098
34ca8243a3 更新3.0.0.11 2023-10-15 20:26:18 +08:00
Diego2098
112fea7632 读取数据类型方法改为批量 2023-10-15 20:21:23 +08:00
Kimdiego2098
378763e4ee 同步Pro版本 2023-10-13 20:14:35 +08:00
Kimdiego2098
517bd0394d update touchsocket 2023-10-13 19:16:12 +08:00
Kimdiego2098
70adb97fb5 update nuget 2023-10-13 16:14:42 +08:00
345 changed files with 21286 additions and 8185 deletions

View File

@@ -5,3 +5,99 @@ dotnet_diagnostic.CA1848.severity = none
# CA2254: 模板应为静态表达式
dotnet_diagnostic.CA2254.severity = suggestion
[*.cs]
#### 命名样式 ####
# 命名规则
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# 符号规范
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# 命名样式
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
[*.vb]
#### 命名样式 ####
# 命名规则
dotnet_naming_rule.interface_should_be_以_i_开始.severity = suggestion
dotnet_naming_rule.interface_should_be_以_i_开始.symbols = interface
dotnet_naming_rule.interface_should_be_以_i_开始.style = 以_i_开始
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.severity = suggestion
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.symbols = 类型
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.severity = suggestion
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.symbols = 非字段成员
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
# 符号规范
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.类型.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.类型.required_modifiers =
dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method
dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.非字段成员.required_modifiers =
# 命名样式
dotnet_naming_style.以_i_开始.required_prefix = I
dotnet_naming_style.以_i_开始.required_suffix =
dotnet_naming_style.以_i_开始.word_separator =
dotnet_naming_style.以_i_开始.capitalization = pascal_case
dotnet_naming_style.帕斯卡拼写法.required_prefix =
dotnet_naming_style.帕斯卡拼写法.required_suffix =
dotnet_naming_style.帕斯卡拼写法.word_separator =
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
dotnet_naming_style.帕斯卡拼写法.required_prefix =
dotnet_naming_style.帕斯卡拼写法.required_suffix =
dotnet_naming_style.帕斯卡拼写法.word_separator =
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.0.0.7</Version>
<Version>3.0.0.24</Version>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Authors>Diego</Authors>

View File

@@ -101,7 +101,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
catch (Exception ex)
{
Messages.Add((LogLevel.Error,
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex.Message}"));
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 错误:{ex}"));
}
}
@@ -126,7 +126,7 @@ public abstract class DriverDebugUIBase : ComponentBase, IDisposable
catch (Exception ex)
{
Messages.Add((LogLevel.Error,
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex.Message}"));
$"{DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)} - 写入前失败:{ex}"));
}
}

View File

@@ -49,7 +49,7 @@ public partial class DriverDebugUIPage : DriverDebugUIBase
}
catch (Exception ex)
{
Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex.Message));
Messages.Add((Microsoft.Extensions.Logging.LogLevel.Warning, DateTimeExtensions.CurrentDateTime.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset) + " - " + ex));
}
}

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" />
@@ -116,11 +116,19 @@
<ItemGroup>
<!--<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCUA" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Siemens" Version="*" />-->
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCDA\ThingsGateway.Foundation.Adapter.OPCDA.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" />
</ItemGroup>
@@ -132,10 +140,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Pages\Mqtt\" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" />

View File

@@ -1,9 +1,12 @@
<Project>
<PropertyGroup>
<Version>3.0.0.7</Version>
<Version>3.0.0.24</Version>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>
<Description>
ThingsGateway.Foundation是工业设备通讯类库归属于ThingsGateway边缘网关项目说明文档https://diego2098.gitee.io/thingsgateway-docs/
</Description>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>
@@ -16,7 +19,6 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>icon.png</PackageIcon>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl>
<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags>
@@ -42,5 +44,10 @@
</None>
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DebugSymbols>True</DebugSymbols>
<DebugType>Embedded</DebugType>
<EmbedAllSources>True</EmbedAllSources>
</PropertyGroup>
</Project>

View File

@@ -444,7 +444,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialSessionBase
if (Station.IsNullOrEmpty()) Station = string.Empty;
if (Station.Length < 12) Station = Station.PadLeft(12, '0');
string str = $"04000C{(level + 1):D2}";
string str = $"04000C{level + 1:D2}";
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword,
str.ByHexStringToBytes().Reverse().ToArray()

View File

@@ -92,15 +92,15 @@ public class DLT645_2007Address : DeviceAddressBase
StringBuilder stringGeter = new();
if (Station.Length > 0)
{
stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";");
stringGeter.Append($"s={Station.Reverse().ToArray().ToHexString()};");
}
if (DataId.Length > 0)
{
stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";");
stringGeter.Append($"{DataId.Reverse().ToArray().ToHexString()};");
}
if (!Reverse)
{
stringGeter.Append("s=" + Reverse.ToString() + ";");
stringGeter.Append($"s={Reverse.ToString()};");
}
return stringGeter.ToString();
}

View File

@@ -134,7 +134,7 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
if ((response[headCodeIndex + 8] != send[sendHeadCodeIndex + 8] + 0x80))//控制码不符合时,返回错误
{
request.Message = "返回控制码:" + $"0x{response[headCodeIndex + 8]:X2},请求控制码:" + $"0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
request.Message = $"返回控制码0x{response[headCodeIndex + 8]:X2}请求控制码0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
request.ErrorCode = 999;
return FilterResult.Success;
}
@@ -146,7 +146,7 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
{
byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33);
var error = DLT645Helper.Get2007ErrorMessage(byte1);
request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
request.Message = $"异常控制码0x{response[headCodeIndex + 8]:X2},错误信息:{error}";
request.ErrorCode = 999;
return FilterResult.Success;
}

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Adapter.DLT645;
internal static class PackHelper

View File

@@ -1,442 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ThingsGateway.Foundation.Adapter.DLT645</name>
</assembly>
<members>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DataInfo">
<summary>
解析参数
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.ByteLength">
<summary>
解析长度
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.Digtal">
<summary>
小数位
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.IsSigned">
<summary>
有符号解析
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDataInfos(System.Byte[])">
<summary>
获取返回的解析信息
</summary>
<param name="buffer"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDLT645_2007Command(System.String,System.Int32,System.Byte,System.String,System.Byte[],System.String[])">
<summary>
获取DLT645报文
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007">
<summary>
DLT645_2007
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialSession)">
<summary>
DLT645_2007
</summary>
<param name="serialSession"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.EnableFEHead">
<summary>
增加FE FE FE FE的报文头部
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.OperCode">
<summary>
写入需操作员代码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Password">
<summary>
写入密码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Station">
<summary>
通讯地址BCD码一般应该是12个字符
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.GetAddressDescription">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.SetDataAdapter">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
<summary>
广播校时
</summary>
<param name="dateTime"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
<summary>
冻结
</summary>
<param name="dateTime"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadDeviceStationAsync(System.Threading.CancellationToken)">
<summary>
读取通信地址
</summary>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
<summary>
修改波特率
</summary>
<param name="baudRate"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
<summary>
更新通信地址
</summary>
<param name="station"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
<summary>
修改密码
</summary>
<param name="level"></param>
<param name="oldPassword"></param>
<param name="newPassword"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.ControlCode">
<summary>
控制码
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Read">
<summary>
读数据
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadSub">
<summary>
读后续数据
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadStation">
<summary>
读站号
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Write">
<summary>
写数据
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteStation">
<summary>
写站号
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.BroadcastTime">
<summary>
广播校时
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Freeze">
<summary>
冻结
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteBaudRate">
<summary>
更新波特率
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WritePassword">
<summary>
更新密码
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address">
<summary>
DLT645_2007Address
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.UInt16)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.Byte[])">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.DataId">
<summary>
数据标识
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Reverse">
<summary>
反转解析
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Station">
<summary>
站号信息
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Parse(System.String,System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ParseFrom(System.String,System.Int32)">
<summary>
解析地址
</summary>
<param name="address"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ToString">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter">
<summary>
DLT645_2007
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.#ctor(ThingsGateway.Foundation.Core.EndianType)">
<summary>
DLT645_2007
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToDouble(System.Byte[],System.Int32)">
<summary>
DLT645协议转换double
</summary>
<param name="buffer">带数据项标识</param>
<param name="offset"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[])">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[],System.Int32,System.Int32)">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter">
<summary>
DLT645_2007DataHandleAdapter
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.EnableFEHead">
<summary>
增加FE FE FE FE的报文头部
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.PackCommand(System.Byte[])">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.GetInstance">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message,System.Byte[],System.Byte[],System.Byte[])">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp">
<summary>
DLT645_2007
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.#ctor(ThingsGateway.Foundation.Core.TcpClient)">
<summary>
DLT645_2007
</summary>
<param name="tcpClient"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.EnableFEHead">
<summary>
增加FE FE FE FE的报文头部
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.OperCode">
<summary>
写入需操作员代码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Password">
<summary>
写入密码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Station">
<summary>
通讯地址BCD码一般应该是12个字符
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.GetAddressDescription">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.SetDataAdapter">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.BroadcastTime(System.DateTime,System.Threading.CancellationToken)">
<summary>
广播校时
</summary>
<param name="dateTime"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.FreezeAsync(System.DateTime,System.Threading.CancellationToken)">
<summary>
冻结
</summary>
<param name="dateTime"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadDeviceStationAsync(System.Threading.CancellationToken)">
<summary>
读取通信地址
</summary>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)">
<summary>
修改波特率
</summary>
<param name="baudRate"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)">
<summary>
更新通信地址
</summary>
<param name="station"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)">
<summary>
修改密码
</summary>
<param name="level"></param>
<param name="oldPassword"></param>
<param name="newPassword"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.HeadBytesLength">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.CheckHeadBytes(System.Byte[])">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.SendBytesThen">
<inheritdoc/>
</member>
</members>
</doc>

View File

@@ -147,15 +147,15 @@ public class ModbusAddress : DeviceAddressBase
StringBuilder stringGeter = new();
if (Station > 0)
{
stringGeter.Append("s=" + Station.ToString() + ";");
stringGeter.Append($"s={Station.ToString()};");
}
if (WriteFunction > 0)
{
stringGeter.Append("w=" + WriteFunction.ToString() + ";");
stringGeter.Append($"w={WriteFunction.ToString()};");
}
if (!string.IsNullOrEmpty(SocketId))
{
stringGeter.Append("id=" + SocketId + ";");
stringGeter.Append($"id={SocketId};");
}
stringGeter.Append(GetFunctionString(ReadFunction) + (AddressStart + 1).ToString());
return stringGeter.ToString();

View File

@@ -117,7 +117,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[], FilterResult>(ex.Message) { Content2 = FilterResult.Success };
return new OperResult<byte[], FilterResult>(ex) { Content2 = FilterResult.Success };
}
}
/// <summary>
@@ -165,7 +165,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}
/// <summary>
@@ -185,7 +185,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}
@@ -207,7 +207,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}
/// <summary>
@@ -244,7 +244,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}
@@ -296,7 +296,7 @@ internal class ModbusHelper
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}

View File

@@ -24,7 +24,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
/// <summary>
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
/// </summary>
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, OperResult> WriteData;
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, Task<OperResult>> WriteData;
/// <summary>
/// 继电器
@@ -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/>
@@ -267,12 +302,13 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
{
return Task.FromResult(Write(address, value));
}
/// <inheritdoc/>
protected override void Received(ByteBlock byteBlock, IRequestInfo requestInfo)
protected override async Task Received(SerialSession client, ReceivedDataEventArgs e)
{
try
{
var requestInfo = e.RequestInfo;
//接收外部报文
if (requestInfo is ModbusSerialServerMessage modbusServerMessage)
{
@@ -312,7 +348,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
if (WriteData != null)
{
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
{
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
if (result.IsSuccess)
@@ -349,7 +385,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
if (WriteData != null)
{
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess)
{
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
if (result.IsSuccess)
@@ -408,13 +444,9 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
private void Init(ModbusAddress mAddress)
{
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
}
}

View File

@@ -57,7 +57,7 @@ public class ModbusSerialServerDataHandleAdapter : ReadWriteDevicesTcpDataHandle
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}

View File

@@ -84,15 +84,6 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
return new OperResult<byte[]>(ex);
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
protected override void Connecting(SocketClient client, ConnectingEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "正在连接");
}
/// <inheritdoc/>
public override void SetDataAdapter(object socketClient = null)
@@ -195,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
var item = commandResult.Content;
if (FrameTime != 0)
Thread.Sleep(FrameTime);
var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true });
var WaitingClientEx = client.CreateWaitingClient(new() { });
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
return (MessageBase)result.RequestInfo;
}
@@ -222,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
var item = commandResult.Content;
await Task.Delay(FrameTime, cancellationToken);
var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true });
var WaitingClientEx = client.CreateWaitingClient(new() { });
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
return (MessageBase)result.RequestInfo;
}

View File

@@ -25,7 +25,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
/// <summary>
/// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
/// </summary>
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, OperResult> WriteData;
public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, Task<OperResult>> WriteData;
/// <summary>
/// 继电器
@@ -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/>
@@ -284,12 +317,13 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
{
return Task.FromResult(Write(address, value));
}
/// <inheritdoc/>
protected override void Received(SocketClient client, IRequestInfo requestInfo)
protected override async Task Received(SocketClient client, ReceivedDataEventArgs e)
{
try
{
var requestInfo = e.RequestInfo;
//接收外部报文
if (requestInfo is ModbusTcpServerMessage modbusServerMessage)
{
@@ -330,7 +364,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
if (WriteData != null)
{
// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
{
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length));
if (result.IsSuccess)
@@ -367,7 +401,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
if (WriteData != null)
{
if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess)
{
var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData);
if (result.IsSuccess)
@@ -428,13 +462,9 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
private void Init(ModbusAddress mAddress)
{
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
}
}

View File

@@ -57,7 +57,7 @@ public class ModbusTcpServerDataHandleAdapter : ReadWriteDevicesTcpDataHandleAda
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex.Message);
return new OperResult<byte[]>(ex);
}
}

View File

@@ -176,7 +176,7 @@ internal class OpcServer : IDisposable
{
status = (OPCSERVERSTATUS)o;
serverStatus = new();
serverStatus.Version = status.wMajorVersion.ToString() + "." + status.wMinorVersion.ToString() + "." + status.wBuildNumber.ToString();
serverStatus.Version = $"{status.wMajorVersion.ToString()}.{status.wMinorVersion.ToString()}.{status.wBuildNumber.ToString()}";
serverStatus.ServerState = status.dwServerState;
serverStatus.StartTime = Comn.Convert.FileTimeToDateTime(status.ftStartTime);
serverStatus.CurrentTime = Comn.Convert.FileTimeToDateTime(status.ftCurrentTime);

View File

@@ -1,3 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
</Project>

View File

@@ -1,579 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ThingsGateway.Foundation.Adapter.OPCDA</name>
</assembly>
<members>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})">
<summary>
移除符合条件的元素
</summary>
<typeparam name="T"></typeparam>
<param name="this"></param>
<param name="where"></param>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_SYSTEM_DEFAULT">
<summary>
The WIN32 system default locale.
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_USER_DEFAULT">
<summary>
The WIN32 user default locale.
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.CreateInstance(System.Guid,System.String)">
<summary>
创建一个COM服务器的实例。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.GetSystemMessage(System.Int32)">
<summary>
指定错误消息文本检索系统。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.InitializeSecurity">
<summary>
初始化COM安全。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID)">
<summary>
从枚举器读取guid。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID)">
<summary>
从枚举器读取guid。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.RealseComServer(System.Object)">
<summary>
释放 COM 对象
</summary>
<param name="m_server"></param>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.Convert.FILETIME_BaseTime">
<summary>
windows的filetime是从1601-1-1 00:00:00开始的datetime是从1-1-1 00:00:00开始的
datetime和filetime的滴答单位都是100ns100纳秒千万分之一秒所以转换时只需要考虑开始时间即可
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnDataChangedHandler">
<summary>
值变化
</summary>
<param name="opcItems"></param>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnReadCompletedHandler">
<summary>
读取
</summary>
<param name="opcItems"></param>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnWriteCompletedHandler">
<summary>
写入
</summary>
<param name="opcItems"></param>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult">
<summary>
返回结果
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Name">
<summary>
ID
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Quality">
<summary>
Quality
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.TimeStamp">
<summary>
TimeStamp
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Value">
<summary>
Value
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.InitIoInterfaces(System.Object)">
<summary>
建立连接
</summary>
<param name="handle"></param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.ReadAsync">
<summary>
组读取
</summary>
<exception cref="T:System.Runtime.InteropServices.ExternalException"></exception>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem">
<summary>
OpcItem
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.#ctor(System.String)">
<summary>
OpcItem
</summary>
<param name="itemId"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.AccessPath">
<summary>
AccessPath
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Blob">
<summary>
Blob
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.BlobSize">
<summary>
BlobSize
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ClientHandle">
<summary>
ClientHandle
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.IsActive">
<summary>
active(1) or not(0)
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ItemID">
<summary>
数据项在opc server的完全名称
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Quality">
<summary>
Quality
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.RunTimeDataType">
<summary>
RunTimeDataType
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ServerHandle">
<summary>
ServerHandle
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.TimeStamp">
<summary>
TimeStamp
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Value">
<summary>
Value
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.AddGroup(System.String,System.Boolean,System.Int32,System.Single)">
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.Browse(System.String)">
<summary>
获取节点
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.GetServerStatus">
<summary>
服务器状态
</summary>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus">
<summary>
ServerStatus
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.CurrentTime">
<summary>
CurrentTime
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.LastUpdateTime">
<summary>
LastUpdateTime
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.ServerState">
<summary>
ServerState
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.StartTime">
<summary>
StartTime
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.VendorInfo">
<summary>
VendorInfo
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.Version">
<summary>
Version
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery">
<summary>
OpcDiscovery
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery.GetOpcServer(System.String,System.String)">
<summary>
GetOpcServer
</summary>
<param name="serverName"></param>
<param name="host"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPoint">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPointContainer">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnectionPoints">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnections">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumString">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumUnknown">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCCommon">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList2">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCShutdown">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CONNECTDATA">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEDIRECTION">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEFILTER">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSETYPE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCDATASOURCE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCENUMSCOPE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCEUTYPE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCNAMESPACETYPE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer10">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer20">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer30">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_XMLDAServer10">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumOPCItemAttributes">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO2">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO3">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowse">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowseServerAddressSpace">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCDataCallback">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt2">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemDeadbandMgt">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemIO">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemMgt">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemProperties">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemSamplingMgt">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCPublicGroupStateMgt">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServer">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerPublicGroups">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO2">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEELEMENT">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADER">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADERWRITE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMATTRIBUTES">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMDEF">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER1">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER2">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADERWRITE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTIES">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTY">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMRESULT">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMSTATE">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMVQT">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATUS">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Constants">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Qualities">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Properties">
<exclude />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.DataChangedEventHandler">
<summary>
订阅变化项
</summary>
<param name="values"></param>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient">
<summary>
OPCDAClient
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ItemDicts">
<summary>
当前保存的需订阅列表
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.#ctor(ThingsGateway.Foundation.Core.ILog)">
<summary>
<inheritdoc/>
</summary>
<param name="logger"></param>
</member>
<member name="E:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.DataChangedHandler">
<summary>
数据变化事件
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.IsConnected">
<summary>
是否连接成功
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.OPCNode">
<summary>
当前配置
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItems(System.Collections.Generic.Dictionary{System.String,System.Collections.Generic.List{ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem}})">
<summary>
添加节点,需要在连接成功后执行
</summary>
<param name="items">组名称/变量节点,注意每次添加的组名称不能相同</param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItemsWithSave(System.Collections.Generic.List{System.String})">
<summary>
设置节点并保存,每次重连会自动添加节点
</summary>
<param name="items"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Connect">
<summary>
连接服务器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Disconnect">
<summary>
断开连接
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetBrowseElements(System.String)">
<summary>
浏览节点
</summary>
<param name="itemId"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetServerStatus">
<summary>
获取服务状态
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Init(ThingsGateway.Foundation.Adapter.OPCDA.OPCNode)">
<summary>
初始化设置
</summary>
<param name="node"></param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ReadItemsWithGroup(System.String)">
<summary>
按OPC组读取组内变量结果会在订阅事件中返回
</summary>
<param name="groupName">组名称值为null时读取全部组</param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.RemoveItems(System.Collections.Generic.List{System.String})">
<summary>
移除节点
</summary>
<param name="items"></param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ToString">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.WriteItem(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken})">
<summary>
批量写入值
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode">
<summary>
OPCDA连接配置项
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ActiveSubscribe">
<summary>
是否订阅
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.CheckRate">
<summary>
内部检测重连间隔/min
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.DeadBand">
<summary>
死区
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.GroupSize">
<summary>
分组大小
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCIP">
<summary>
OPCIP
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCName">
<summary>
OPCNAME
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.UpdateRate">
<summary>
订阅间隔
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ToString">
<summary>
<inheritdoc/>
</summary>
<returns></returns>
</member>
</members>
</doc>

View File

@@ -1,4 +1,4 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -70,6 +70,11 @@ public class OPCNode
/// </summary>
[Description("安全策略")]
public bool IsUseSecurity { get; set; } = false;
/// <summary>
/// 加载服务端数据类型
/// </summary>
[Description("加载服务端数据类型")]
public bool LoadType { get; set; } = true;
/// <inheritdoc/>
public override string ToString()
{

View File

@@ -1,4 +1,4 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -13,6 +13,33 @@
using Opc.Ua;
namespace ThingsGateway.Foundation.Adapter.OPCUA;
/// <summary>
/// OPC UA的状态更新消息
/// </summary>
public class OpcUaStatusEventArgs
{
/// <summary>
/// 日志等级,<br></br>
/// 更为详细的步骤型日志输出 Trace = 0,<br></br>
/// 调试信息日志Debug = 1,<br></br>
/// 消息类日志输出 Info = 2,<br></br>
/// 警告类日志输出 Warning = 3,<br></br>
/// 错误类日志输出 Error = 4,<br></br>
/// 不可控中断类日输出Critical = 5,
/// </summary>
public int LogLevel { get; set; }
/// <summary>
/// 时间
/// </summary>
public DateTime Time { get; set; }
/// <summary>
/// 文本
/// </summary>
public string Text { get; set; }
}
/// <summary>
/// 读取属性过程中用于描述的
/// </summary>
@@ -22,6 +49,7 @@ public class OPCNodeAttribute
/// 属性的名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 操作结果状态描述
/// </summary>
@@ -31,10 +59,9 @@ public class OPCNodeAttribute
/// 属性的类型描述
/// </summary>
public string Type { get; set; }
/// <summary>
/// 属性的值,如果读取错误,返回文本描述
/// </summary>
public object Value { get; set; }
}
}

View File

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

View File

@@ -1,468 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ThingsGateway.Foundation.Adapter.OPCUA</name>
</assembly>
<members>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})">
<summary>
移除符合条件的元素
</summary>
<typeparam name="T"></typeparam>
<param name="this"></param>
<param name="where"></param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.SelectAsync``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Threading.Tasks.Task{``1}})">
<summary>
异步Select
</summary>
<typeparam name="T"></typeparam>
<typeparam name="TResult"></typeparam>
<param name="source"></param>
<param name="selector"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils">
<summary>
辅助类
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.Browse(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean)">
<summary>
Browses the address space and returns the references found.
</summary>
<param name="session">The session.</param>
<param name="nodesToBrowse">The set of browse operations to perform.</param>
<param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param>
<returns>
The references found. Null if an error occurred.
</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.PrepareBrowseNext(Opc.Ua.BrowseResultCollection)">
<summary>
Create the continuation point collection from the browse result
collection for the BrowseNext service.
</summary>
<param name="browseResultCollection">The browse result collection to use.</param>
<returns>The collection of continuation points for the BrowseNext service.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean,System.Threading.CancellationToken)">
<summary>
浏览地址空间
</summary>
<param name="session"></param>
<param name="nodesToBrowse"></param>
<param name="throwOnError"></param>
<param name="cancellationToken"></param>
<returns></returns>
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescription,System.Boolean,System.Threading.CancellationToken)">
<summary>
浏览地址空间
</summary>
<param name="session"></param>
<param name="nodeToBrowse"></param>
<param name="throwOnError"></param>
<param name="cancellationToken"></param>
<returns></returns>
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseSuperTypesAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,System.Boolean)">
<summary>
浏览地址空间并返回指定类型的所有节点
</summary>
<param name="session"></param>
<param name="typeId"></param>
<param name="throwOnError"></param>
<returns></returns>
<exception cref="T:Opc.Ua.ServiceResultException"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForInstanceAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})">
<summary>
Collects the fields for the instance.
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForType(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})">
<summary>
Collects the fields for the type.
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ConstructEventAsync(Opc.Ua.Client.ISession,Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList,System.Collections.Generic.Dictionary{Opc.Ua.NodeId,System.Type},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.NodeId})">
<summary>
Constructs an event object from a notification.
</summary>
<param name="session">The session.</param>
<param name="monitoredItem">The monitored item that produced the notification.</param>
<param name="notification">The notification.</param>
<param name="knownEventTypes">The known event types.</param>
<param name="eventTypeMappings">Mapping between event types and known event types.</param>
<returns>
The event object. Null if the notification is not a valid event type.
</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.DiscoverServers(Opc.Ua.ApplicationConfiguration)">
<summary>
Discovers the servers on the local machine.
</summary>
<param name="configuration">The configuration.</param>
<returns>A list of server urls.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.FindEventType(Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList)">
<summary>
Finds the type of the event for the notification.
</summary>
<param name="monitoredItem">The monitored item.</param>
<param name="notification">The notification.</param>
<returns>The NodeId of the EventType.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAttributeDisplayText(Opc.Ua.Client.ISession,System.UInt32,Opc.Ua.Variant)">
<summary>
指定的属性的显示文本。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.SelectEndpoint(System.String,System.Boolean)">
<summary>
Finds the endpoint that best matches the current settings.
</summary>
<param name="discoveryUrl">The discovery URL.</param>
<param name="useSecurity">if set to <c>true</c> select an endpoint that uses security.</param>
<returns>The best available endpoint.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.TranslateBrowsePaths(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.NamespaceTable,System.Threading.CancellationToken,System.String[])">
<summary>
返回一组相对路径的节点id
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection})">
<summary>
Collects the fields for the instance node.
</summary>
<param name="session">The session.</param>
<param name="nodeId">The node id.</param>
<param name="parentPath">The parent path.</param>
<param name="fields">The event fields.</param>
<param name="fieldNodeIds">The node id for the declaration of the field.</param>
<param name="foundNodes">The table of found nodes.</param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ContainsPath(Opc.Ua.SimpleAttributeOperandCollection,Opc.Ua.QualifiedNameCollection)">
<summary>
判断指定的select子句包含的浏览路径。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAccessLevelDisplayText(System.Byte)">
<summary>
访问级别属性的显示文本。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetEventNotifierDisplayText(System.Byte)">
<summary>
事件通知属性的显示文本
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils">
<summary>
扩展方法
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Decode(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)">
<summary>
解析获取DataValue
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecoderObject(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)">
<summary>
解析获取object
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecodeRawData(Opc.Ua.JsonDecoder,Opc.Ua.BuiltInType,System.Int32,System.String)">
<summary>
DecodeRawData
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Encode(Opc.Ua.IServiceMessageContext,Opc.Ua.BuiltInType,System.Object)">
<summary>
OPCUAValue解析为Jtoken
</summary>
<param name="Context"></param>
<param name="type"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CreateEncoder(Opc.Ua.IServiceMessageContext,System.IO.Stream,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
<summary>
CreateEncoder
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CalculateActualValueRank(Newtonsoft.Json.Linq.JToken)">
<summary>
维度
</summary>
<param name="jToken"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode">
<summary>
OPCUAClient配置项
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.OPCUrl">
<summary>
OPCUrl
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UserName">
<summary>
登录账号
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.Password">
<summary>
登录密码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.CheckDomain">
<summary>
检查域
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UpdateRate">
<summary>
更新间隔
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ActiveSubscribe">
<summary>
是否订阅
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.GroupSize">
<summary>
分组大小
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.DeadBand">
<summary>
死区
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.KeepAliveInterval">
<summary>
KeepAliveInterval/ms
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.IsUseSecurity">
<summary>
安全策略
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ToString">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.DataChangedEventHandler">
<summary>
订阅委托
</summary>
<param name="value"></param>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient">
<summary>
OPCUAClient
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCNode">
<summary>
当前配置
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ProductUri">
<summary>
ProductUri
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Variables">
<summary>
当前保存的变量名称列表
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient._variableDicts">
<summary>
当前的变量名称/OPC变量节点
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.dic_subscriptions">
<summary>
当前的订阅组,组名称/组
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReConnectHandler">
<summary>
SessionReconnectHandler
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.#ctor(ThingsGateway.Foundation.Core.ILog)">
<summary>
默认的构造函数实例化一个新的OPC UA类
</summary>
</member>
<member name="E:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.DataChangedHandler">
<summary>
订阅
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AppConfig">
<summary>
配置信息
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Connected">
<summary>
连接状态
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCUAName">
<summary>
OPCUAClient
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Session">
<summary>
当前活动会话。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AddSubscriptionAsync(System.String,System.String[])">
<summary>
新增订阅需要指定订阅组名称订阅的tag名数组
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveAllSubscription">
<summary>
移除所有的订阅消息
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveSubscription(System.String)">
<summary>
移除订阅消息
</summary>
<param name="subscriptionName">组名称</param>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.BrowseNodeReferenceAsync(System.String)">
<summary>
浏览一个节点的引用
</summary>
<param name="tag">节点值</param>
<returns>引用节点描述</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.CallMethodByNodeId(System.String,System.String,System.Object[])">
<summary>
调用服务器的方法
</summary>
<param name="tagParent">方法的父节点tag</param>
<param name="tag">方法的节点tag</param>
<param name="args">传递的参数</param>
<returns>输出的结果值</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadHistoryRawDataValues(System.String,System.DateTime,System.DateTime,System.UInt32,System.Boolean,System.Threading.CancellationToken)">
<summary>
读取历史数据
</summary>
<param name="tag">节点的索引</param>
<param name="start">开始时间</param>
<param name="end">结束时间</param>
<param name="count">读取的个数</param>
<param name="containBound">是否包含边界</param>
<param name="cancellationToken">cancellationToken</param>
<returns>读取的数据列表</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync">
<summary>
连接到服务器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Disconnect">
<summary>
断开连接。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync(System.String)">
<summary>
Creates a new session.
</summary>
<returns>The new session object.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(System.String[],System.Threading.CancellationToken)">
<summary>
从服务器读取值
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.WriteNodeAsync(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)">
<summary>
异步写opc标签
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(Opc.Ua.NodeId[],System.Threading.CancellationToken)">
<summary>
从服务器读取值
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNodeAsync(System.String,System.Boolean,System.Threading.CancellationToken)">
<summary>
从服务器或缓存读取节点
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.String,System.UInt32,System.Threading.CancellationToken)">
<summary>
读取一个节点的所有属性
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.Collections.Generic.List{System.String},System.Threading.CancellationToken)">
<summary>
读取节点的所有属性
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributes(System.String)">
<summary>
读取一个节点的所有属性
</summary>
<param name="tag">节点信息</param>
<returns>节点的特性值</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Server_ReconnectComplete(System.Object,System.EventArgs)">
<summary>
连接处理器连接事件处理完成。
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute">
<summary>
读取属性过程中用于描述的
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Name">
<summary>
属性的名称
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.StatusCode">
<summary>
操作结果状态描述
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Type">
<summary>
属性的类型描述
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Value">
<summary>
属性的值,如果读取错误,返回文本描述
</summary>
</member>
</members>
</doc>

View File

@@ -250,44 +250,44 @@ public class SiemensAddress : DeviceAddressBase
{
if (DataCode == (byte)S7Area.TM)
{
return "T" + Address.ToString() + (IsWString ? ";W=true;" : ";W=false;");
return $"T{Address.ToString()}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.CT)
{
return "C" + Address.ToString() + (IsWString ? ";W=true;" : ";W=false;");
return $"C{Address.ToString()}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.AI)
{
return "AI" + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;");
return $"AI{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.AQ)
{
return "AQ" + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;");
return $"AQ{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.PE)
{
return "I" + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;");
return $"I{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.PA)
{
return "Q" + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;");
return $"Q{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
}
if (DataCode == (byte)S7Area.MK)
{
return "M" + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;");
return $"M{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}";
}
return DataCode == (byte)S7Area.DB ? "DB" + DbBlock.ToString() + "." + GetStringAddress(AddressStart) + (IsWString ? ";W=true;" : ";W=false;") : Address.ToString() + (IsWString ? ";W=true;" : ";W=false;");
return DataCode == (byte)S7Area.DB ? $"DB{DbBlock.ToString()}.{GetStringAddress(AddressStart)}{(IsWString ? ";W=true;" : ";W=false;")}" : Address.ToString() + (IsWString ? ";W=true;" : ";W=false;");
}
private static string GetStringAddress(int addressStart)
{
return addressStart % 8 == 0 ? (addressStart / 8).ToString() : string.Format("{0}.{1}", addressStart / 8, addressStart % 8);
return addressStart % 8 == 0 ? (addressStart / 8).ToString() : $"{addressStart / 8}.{addressStart % 8}";
}
}

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Adapter.Siemens;
/// <summary>

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Adapter.Siemens;
internal static class PackHelper

View File

@@ -67,7 +67,6 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
break;
}
tcpClient.Connected += Connected;
}
/// <summary>
@@ -124,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
{
@@ -293,8 +265,8 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
/// <inheritdoc/>
public override void SetDataAdapter(object socketClient = null)
{
SiemensS7PLCDataHandleAdapter DataHandleAdapter = new();
TcpClient.SetDataHandlingAdapter(DataHandleAdapter);
SiemensS7PLCDataHandleAdapter dataHandleAdapter = new();
TcpClient.SetDataHandlingAdapter(dataHandleAdapter);
}
@@ -476,17 +448,20 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
}
#endregion
private void Connected(ITcpClient client, ConnectedEventArgs e)
/// <inheritdoc/>
protected override async Task Connected(ITcpClient client, ConnectedEventArgs e)
{
try
{
var result1 = SendThenResponse(ISO_CR);
NormalDataHandlingAdapter dataHandleAdapter = new();
TcpClient.SetDataHandlingAdapter(dataHandleAdapter);
var result1 = await SendThenResponseAsync(ISO_CR);
if (!result1.IsSuccess)
{
Logger?.Warning($"{client.IP} : {client.Port}ISO_TP握手失败-{result1.Message}");
return;
}
var result2 = SendThenResponse(S7_PN);
var result2 = await SendThenResponseAsync(S7_PN);
if (!result2.IsSuccess)
{
Logger?.Warning($"{client.IP} : {client.Port}PDU初始化失败-{result2.Message}");
@@ -499,7 +474,11 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
{
Logger.Exception(ex);
}
finally
{
SetDataAdapter();
}
await base.Connected(client, e);
}
}
}

View File

@@ -1,336 +0,0 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ThingsGateway.Foundation.Adapter.Siemens</name>
</assembly>
<members>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7Area">
<summary>
区域
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PE">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PA">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.MK">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.DB">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.CT">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.TM">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AI">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AQ">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress">
<summary>
西门子PLC地址数据信息
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.BitCode">
<summary>
bit位偏移
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DataCode">
<summary>
数据块代码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DbBlock">
<summary>
DB块数据信息
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetAddressStart(System.String,System.Boolean)">
<summary>
获取起始地址
</summary>
<param name="address"></param>
<param name="isCounterOrTimer"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetBitCode(System.String)">
<summary>
获取bit
</summary>
<param name="address"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String)">
<summary>
解析地址
</summary>
<param name="address"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String,System.Int32)">
<summary>
解析地址
</summary>
<param name="address"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.Parse(System.String,System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ToString">
<inheritdoc />
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.DateTime">
<summary>
https://github.com/S7NetPlus/s7netplus/blob/develop/S7.Net/Types/DateTime.cs
Contains the methods to convert between <see cref="T:System.DateTime"/> and S7 representation of datetime values.
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMaximumDateTime">
<summary>
The maximum <see cref="T:System.DateTime"/> value supported by the specification.
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMinimumDateTime">
<summary>
The minimum <see cref="T:System.DateTime"/> value supported by the specification.
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.FromByteArray(System.Byte[])">
<summary>
Parses a <see cref="T:System.DateTime"/> value from bytes.
</summary>
<param name="bytes">Input bytes read from PLC.</param>
<returns>A <see cref="T:System.DateTime"/> object representing the value read from PLC.</returns>
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of
<paramref name="bytes"/> is not 8 or any value in <paramref name="bytes"/>
is outside the valid range of values.</exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToArray(System.Byte[])">
<summary>
Parses an array of <see cref="T:System.DateTime"/> values from bytes.
</summary>
<param name="bytes">Input bytes read from PLC.</param>
<returns>An array of <see cref="T:System.DateTime"/> objects representing the values read from PLC.</returns>
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of
<paramref name="bytes"/> is not a multiple of 8 or any value in
<paramref name="bytes"/> is outside the valid range of values.</exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime)">
<summary>
Converts a <see cref="T:System.DateTime"/> value to a byte array.
</summary>
<param name="dateTime">The DateTime value to convert.</param>
<returns>A byte array containing the S7 date time representation of <paramref name="dateTime"/>.</returns>
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when the value of
<paramref name="dateTime"/> is before <see cref="P:SpecMinimumDateTime"/>
or after <see cref="P:SpecMaximumDateTime"/>.</exception>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime[])">
<summary>
Converts an array of <see cref="T:System.DateTime"/> values to a byte array.
</summary>
<param name="dateTimes">The DateTime values to convert.</param>
<returns>A byte array containing the S7 date time representations of <paramref name="dateTimes"/>.</returns>
<exception cref="T:System.ArgumentOutOfRangeException">Thrown when any value of
<paramref name="dateTimes"/> is before <see cref="P:SpecMinimumDateTime"/>
or after <see cref="P:SpecMaximumDateTime"/>.</exception>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensHelper.S7_MULRW_HEADER">
<summary>
S7连读写请求头(包含ISO头和COTP头)
</summary>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Bit">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Byte">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Char">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Word">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Int">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DWord">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DInt">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Real">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Counter">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Timer">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.HeadBytesLength">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.CheckHeadBytes(System.Byte[])">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200Smart">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S300">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S400">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1200">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1500">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC">
<summary>
相关命令含义源自网络资料/Shrap7/s7netplus
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.#ctor(ThingsGateway.Foundation.Core.TcpClient,ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum)">
<summary>
传入PLC类型程序内会改变相应PLC类型的S7协议LocalTSAP RemoteTSAP等
</summary>
<param name="tcpClient"></param>
<param name="siemensPLCEnum"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.CurrentPlc">
<summary>
当前PLC类型
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetAddressDescription">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetBitOffset(System.String)">
<summary>
<inheritdoc/>
</summary>
<param name="address"></param>
<returns></returns>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.DestTSAP">
<summary>
远程TSAP需重新连接
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.LocalTSAP">
<summary>
本地TSAP需重新连接
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.PDULength">
<summary>
PDULength
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Rack">
<summary>
机架号,需重新连接
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Slot">
<summary>
槽号,需重新连接
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateAsync(System.String,System.Threading.CancellationToken)">
<summary>
读取日期
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateTimeAsync(System.String,System.Threading.CancellationToken)">
<summary>
读取时间
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadStringAsync(System.String,System.Text.Encoding,System.Threading.CancellationToken)">
<summary>
读取变长字符串
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.SetDataAdapter">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.String,System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateAsync(System.String,System.DateTime,System.Threading.CancellationToken)">
<summary>
写入日期
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateTimeAsync(System.String,System.DateTime,System.Threading.CancellationToken)">
<summary>
写入时间
</summary>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter">
<summary>
SiemensS7PLCDataHandleAdapter
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.PackCommand(System.Byte[])">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.GetInstance">
<summary>
<inheritdoc/>
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage,System.Byte[],System.Byte[],System.Byte[])">
<inheritdoc/>
</member>
</members>
</doc>

View File

@@ -24,7 +24,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
{
SerialSession = serialSession;
WaitingClientEx = SerialSession.GetWaitingClientEx(new() { BreakTrigger = true });
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
SerialSession.Received -= Received;
SerialSession.Connecting -= Connecting;
SerialSession.Connected -= Connected;
@@ -40,21 +40,15 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
/// <summary>
/// 接收解析
/// </summary>
protected virtual void Received(ByteBlock byteBlock, IRequestInfo requestInfo)
/// <param name="client"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e)
{
return EasyTask.CompletedTask;
}
}
private void Received(SerialSession client, ByteBlock byteBlock, IRequestInfo requestInfo)
{
try
{
Received(byteBlock, requestInfo);
}
catch (Exception ex)
{
Logger.Exception(this, ex);
}
}
/// <summary>
/// 串口管理对象
@@ -102,8 +96,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = SerialSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -117,8 +111,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = await SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = await SerialSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -132,24 +126,34 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
{
return SerialSession.SerialProperty.ToString();
}
private void Connected(ISerialSession client, ConnectedEventArgs e)
/// <summary>
/// Connected
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task Connected(ISerialSession client, ConnectedEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
SetDataAdapter();
return EasyTask.CompletedTask;
}
private void Connecting(ISerialSession client, SerialConnectingEventArgs e)
private Task Connecting(ISerialSession client, SerialConnectingEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
SetDataAdapter();
return EasyTask.CompletedTask;
}
private void Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
private Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
return EasyTask.CompletedTask;
}
private void Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
private Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
return EasyTask.CompletedTask;
}
}

View File

@@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
public ReadWriteDevicesTcpClientBase(TcpClient tcpClient)
{
TcpClient = tcpClient;
WaitingClientEx = TcpClient.GetWaitingClientEx(new() { BreakTrigger = true });
WaitingClientEx = TcpClient.CreateWaitingClient(new() { });
TcpClient.Connecting -= Connecting;
TcpClient.Connected -= Connected;
TcpClient.Disconnecting -= Disconnecting;
@@ -59,7 +59,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken cancellationToken)
{
return TcpClient.ConnectAsync(ConnectTimeOut);
return TcpClient.ConnectAsync(ConnectTimeOut, cancellationToken);
}
/// <inheritdoc/>
@@ -86,8 +86,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = TcpClient.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -101,8 +101,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = await TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = await TcpClient.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -116,24 +116,34 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
{
return TcpClient.RemoteIPHost.ToString();
}
private void Connected(ITcpClient client, ConnectedEventArgs e)
/// <summary>
/// Connected
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task Connected(ITcpClient client, ConnectedEventArgs e)
{
Logger?.Debug(client.RemoteIPHost.ToString() + "连接成功");
SetDataAdapter();
return EasyTask.CompletedTask;
}
private void Connecting(ITcpClient client, ConnectingEventArgs e)
private Task Connecting(ITcpClient client, ConnectingEventArgs e)
{
Logger?.Debug(client.RemoteIPHost.ToString() + "正在连接");
SetDataAdapter();
return EasyTask.CompletedTask;
}
private void Disconnected(ITcpClientBase client, DisconnectEventArgs e)
private Task Disconnected(ITcpClientBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message);
Logger?.Debug($"{client.IP}:{client.Port}断开连接-{e.Message}");
return EasyTask.CompletedTask;
}
private void Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
private Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message);
Logger?.Debug($"{client.IP}:{client.Port}正在主动断开连接-{e.Message}");
return EasyTask.CompletedTask;
}
}

View File

@@ -77,57 +77,54 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
if (CascadeDisposal)
TcpService.SafeDispose();
}
/// <summary>
/// 接收解析
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task Received(SocketClient client, ReceivedDataEventArgs e)
{
return EasyTask.CompletedTask;
}
/// <inheritdoc/>
public override string ToString()
{
return TcpService.ServerName;
}
/// <summary>
/// 接收解析
/// </summary>
protected virtual void Received(SocketClient client, IRequestInfo requestInfo)
{
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="client"></param>
/// <param name="e"></param>
protected virtual void Connected(SocketClient client, ConnectedEventArgs e)
protected virtual Task Connected(SocketClient client, ConnectedEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "连接成功");
Logger?.Debug($"{client.IP}:{client.Port}连接成功");
return EasyTask.CompletedTask;
}
/// <inheritdoc/>
protected virtual void Connecting(SocketClient client, ConnectingEventArgs e)
protected virtual Task Connecting(SocketClient client, ConnectingEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "正在连接");
Logger?.Debug($"{client.IP}:{client.Port}正在连接");
SetDataAdapter(client);
return EasyTask.CompletedTask;
}
/// <inheritdoc/>
protected virtual void Disconnected(ITcpClientBase client, DisconnectEventArgs e)
protected virtual Task Disconnected(ITcpClientBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message);
Logger?.Debug($"{client.IP}:{client.Port}断开连接-{e.Message}");
return EasyTask.CompletedTask;
}
/// <inheritdoc/>
protected virtual void Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
protected virtual Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message);
Logger?.Debug($"{client.IP}:{client.Port}正在主动断开连接-{e.Message}");
return EasyTask.CompletedTask;
}
private void Received(SocketClient client, ByteBlock byteBlock, IRequestInfo requestInfo)
{
try
{
Received(client, requestInfo);
}
catch (Exception ex)
{
Logger.Exception(this, ex);
}
}
}

View File

@@ -22,7 +22,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
{
UdpSession = udpSession;
SetDataAdapter();
WaitingClientEx = UdpSession.GetWaitingClientEx(new() { BreakTrigger = true });
WaitingClientEx = UdpSession.CreateWaitingClient(new() { });
}
/// <summary>
@@ -64,8 +64,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = UdpSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -79,8 +79,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = await UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
waitingOptions ??= new WaitingOptions { };
ResponsedData result = await UdpSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)

View File

@@ -20,6 +20,12 @@ public sealed class EasyLock
private static long lockWaitCount;
private readonly SemaphoreSlim m_waiterLock = new SemaphoreSlim(1);
/// <inheritdoc/>
public EasyLock(bool initialState = true)
{
if (!initialState)
m_waiterLock.Wait();
}
/// <inheritdoc/>
~EasyLock()
{
m_waiterLock.SafeDispose();
@@ -45,39 +51,41 @@ 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>
/// 进入锁
/// </summary>
public void Wait(TimeSpan timeSpan, CancellationToken cancellationToken)
public bool Wait(TimeSpan timeSpan, CancellationToken cancellationToken)
{
Interlocked.Increment(ref lockWaitCount);
m_waiterLock.Wait(timeSpan, cancellationToken);
var data = m_waiterLock.Wait(timeSpan, cancellationToken);
Interlocked.Decrement(ref lockWaitCount);
return data;
}
/// <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>
/// 进入锁
/// </summary>
public async Task WaitAsync(TimeSpan timeSpan, CancellationToken cancellationToken)
public async Task<bool> WaitAsync(TimeSpan timeSpan, CancellationToken cancellationToken)
{
Interlocked.Increment(ref lockWaitCount);
await m_waiterLock.WaitAsync(timeSpan, cancellationToken);
var data = await m_waiterLock.WaitAsync(timeSpan, cancellationToken);
Interlocked.Decrement(ref lockWaitCount);
return data;
}
}

View File

@@ -143,6 +143,21 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
GoSend(bytes, 0, bytes.Length);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
}
/// <summary>
/// 发送方法,会重新建立<see cref="Request"/>
/// </summary>
protected async Task GoSendAsync(byte[] item)
{
byte[] bytes;
if (IsSendPackCommand)
bytes = PackCommand(item);
else
bytes = item;
Request = GetInstance();
Request.SendBytes = bytes;
await GoSendAsync(bytes, 0, bytes.Length);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
}
/// <inheritdoc/>
protected override void PreviewSend(byte[] buffer, int offset, int length)
@@ -150,6 +165,12 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
GoSend(buffer);
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
return GoSendAsync(buffer);
}
/// <summary>
/// 报文拆包
/// </summary>

View File

@@ -128,11 +128,6 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
{
throw new System.NotImplementedException();//因为设置了不支持拼接发送,所以该方法可以不实现。
}
/// <inheritdoc/>
protected override void PreviewSend(IRequestInfo requestInfo)
{
throw new System.NotImplementedException();//因为设置了不支持,所以该方法可以不实现。
}
/// <inheritdoc/>
protected override void Reset()

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

@@ -28,7 +28,7 @@ public class ByteTransformUtil
}
catch (Exception ex)
{
return new OperResult<TResult>(string.Format("{0} {1} : Length({2}) {3}", "转换失败", result.Content.ToHexString(), result.Content.Length, ex.Message));
return new OperResult<TResult>(string.Format("{0} {1} : Length({2}) {3}", "转换失败", result.Content.ToHexString(), result.Content.Length, ex));
}
}

View File

@@ -32,7 +32,7 @@ public static class JTokenUtil
}
catch (Exception)
{
tagValue = JToken.Parse("\"" + item + "\"");
tagValue = JToken.Parse($"\"{item}\"");
}
return tagValue;

View File

@@ -19,5 +19,20 @@
<PackageReference Include="System.IO.Ports" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\favicon-16x16.png" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\favicon-32x32.png" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\index.html" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\oauth2-redirect.html" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\openapi.json" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-bundle.js" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-es-bundle-core.js" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-es-bundle.js" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-standalone-preset.js" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui.css" />
<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui.js" />
</ItemGroup>
</Project>

View File

@@ -27,10 +27,9 @@ using System.Runtime.CompilerServices;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 具有释放的对象。
/// 并未实现析构函数相关。
/// 具有释放的对象。内部实现了GC.SuppressFinalize但不包括析构函数相关。
/// </summary>
public class DisposableObject : IDisposable
public partial class DisposableObject : IDisposable
{
/// <summary>
/// 判断是否已释放。
@@ -65,11 +64,12 @@ namespace ThingsGateway.Foundation.Core
}
/// <summary>
/// 释放资源。
/// 释放资源。内部已经处理了<see cref="GC.SuppressFinalize(object)"/>
/// </summary>
public void Dispose()
{
this.Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -72,7 +72,7 @@ namespace ThingsGateway.Foundation.Core
}
catch (Exception ex)
{
this.OnError(ex.Message, false, true);
this.OnError(ex.ToString(), false, true);
}
}
return FilterResult.GoOn;
@@ -121,7 +121,7 @@ namespace ThingsGateway.Foundation.Core
}
catch (Exception ex)
{
this.OnError(ex.Message, false, true);
this.OnError(ex.ToString(), false, true);
}
}
return FilterResult.GoOn;

View File

@@ -69,14 +69,6 @@ namespace ThingsGateway.Foundation.Core
this.Owner = owner;
}
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
/// <param name="requestInfo"></param>
public void SendInput(IRequestInfo requestInfo)
{
this.PreviewSend(requestInfo);
}
/// <summary>
/// 在解析时发生错误。
@@ -96,11 +88,6 @@ namespace ThingsGateway.Foundation.Core
}
}
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="requestInfo"></param>
protected abstract void PreviewSend(IRequestInfo requestInfo);
/// <summary>
/// 重置解析器到初始状态,一般在<see cref="OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。

View File

@@ -78,6 +78,24 @@ namespace ThingsGateway.Foundation.Core
throw new System.NotImplementedException();
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
return this.GoSendAsync(buffer, offset, length);
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
{
throw new NotImplementedException();
}
/// <summary>
/// <inheritdoc/>
/// </summary>

View File

@@ -242,6 +242,131 @@ namespace ThingsGateway.Foundation.Core
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
if (length < this.MinPackageSize)
{
throw new Exception("发送数据小于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
if (length > this.MaxPackageSize)
{
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
ByteBlock byteBlock = null;
byte[] lenBytes = null;
switch (this.FixedHeaderType)
{
case FixedHeaderType.Byte:
{
var dataLen = (byte)(length - offset);
byteBlock = new ByteBlock(dataLen + 1);
lenBytes = new byte[] { dataLen };
break;
}
case FixedHeaderType.Ushort:
{
var dataLen = (ushort)(length - offset);
byteBlock = new ByteBlock(dataLen + 2);
lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen);
break;
}
case FixedHeaderType.Int:
{
var dataLen = length - offset;
byteBlock = new ByteBlock(dataLen + 4);
lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen);
break;
}
}
try
{
byteBlock.Write(lenBytes);
byteBlock.Write(buffer, offset, length);
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
/// <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.MinPackageSize)
{
throw new Exception("发送数据小于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
if (length > this.MaxPackageSize)
{
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
ByteBlock byteBlock = null;
byte[] lenBytes = null;
switch (this.FixedHeaderType)
{
case FixedHeaderType.Byte:
{
var dataLen = (byte)length;
byteBlock = new ByteBlock(dataLen + 1);
lenBytes = new byte[] { dataLen };
break;
}
case FixedHeaderType.Ushort:
{
var dataLen = (ushort)length;
byteBlock = new ByteBlock(dataLen + 2);
lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen);
break;
}
case FixedHeaderType.Int:
{
byteBlock = new ByteBlock(length + 4);
lenBytes = TouchSocketBitConverter.Default.GetBytes(length);
break;
}
}
try
{
byteBlock.Write(lenBytes);
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>

View File

@@ -183,6 +183,70 @@ namespace ThingsGateway.Foundation.Core
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
var dataLen = length - offset;
if (dataLen > this.FixedSize)
{
throw new OverlengthException("发送的数据包长度大于FixedSize");
}
var byteBlock = new ByteBlock(this.FixedSize);
byteBlock.Write(buffer, offset, length);
for (var i = byteBlock.Pos; i < this.FixedSize; i++)
{
byteBlock.Buffer[i] = 0;
}
byteBlock.SetLength(this.FixedSize);
try
{
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
{
var length = 0;
foreach (var item in transferBytes)
{
length += item.Count;
}
if (length > this.FixedSize)
{
throw new OverlengthException("发送的数据包长度大于FixedSize");
}
var byteBlock = new ByteBlock(this.FixedSize);
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
Array.Clear(byteBlock.Buffer, byteBlock.Pos, this.FixedSize);
byteBlock.SetLength(this.FixedSize);
try
{
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>

View File

@@ -240,5 +240,64 @@ namespace ThingsGateway.Foundation.Core
byteBlock.Dispose();
}
}
/// <inheritdoc/>
protected override Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
if (length > this.MaxPackageSize)
{
throw new Exception("发送的数据长度大于适配器设定的最大值,接收方可能会抛弃。");
}
var dataLen = length - offset + this.m_terminatorCode.Length;
var byteBlock = new ByteBlock(dataLen);
byteBlock.Write(buffer, offset, length);
byteBlock.Write(this.m_terminatorCode);
try
{
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
{
var length = 0;
foreach (var item in transferBytes)
{
length += item.Count;
}
if (length > this.MaxPackageSize)
{
throw new Exception("发送的数据长度大于适配器设定的最大值,接收方可能会抛弃。");
}
var dataLen = length + this.m_terminatorCode.Length;
var byteBlock = new ByteBlock(dataLen);
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
byteBlock.Write(this.m_terminatorCode);
try
{
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
finally
{
byteBlock.Dispose();
}
}
}
}

View File

@@ -10,6 +10,19 @@
//------------------------------------------------------------------------------
#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.Core
{
/// <summary>
@@ -37,4 +50,4 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public bool? UpdateCacheTimeWhenRev { get; set; }
}
}
}

View File

@@ -36,9 +36,9 @@ namespace ThingsGateway.Foundation.Core
public TimeSpan CacheTimeout { get; set; } = TimeSpan.FromSeconds(1);
/// <summary>
/// 是否启用缓存超时。默认true。
/// 是否启用缓存超时。默认false。
/// </summary>
public bool CacheTimeoutEnable { get; set; } = true;
public bool CacheTimeoutEnable { get; set; } = false;
/// <summary>
/// 当接收数据处理完成后,回调该函数执行接收
@@ -46,10 +46,15 @@ namespace ThingsGateway.Foundation.Core
public Action<ByteBlock, IRequestInfo> ReceivedCallBack { get; set; }
/// <summary>
/// 当接收数据处理完成后,回调该函数执行发送
/// 当发送数据处理完成后,回调该函数执行发送
/// </summary>
public Action<byte[], int, int> SendCallBack { get; set; }
/// <summary>
/// 当发送数据处理完成后,回调该函数执行异步发送
/// </summary>
public Func<byte[], int, int, Task> SendAsyncCallBack { get; set; }
/// <summary>
/// 是否在收到数据时即刷新缓存时间。默认true。
/// <list type="number">
@@ -64,6 +69,12 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
protected DateTime LastCacheTime { get; set; }
/// <inheritdoc/>
public override bool CanSendRequestInfo => false;
/// <inheritdoc/>
public override bool CanSplicingSend => false;
/// <summary>
/// 收到数据的切入点,该方法由框架自动调用。
/// </summary>
@@ -76,10 +87,21 @@ namespace ThingsGateway.Foundation.Core
}
catch (Exception ex)
{
this.OnError(ex.Message);
this.OnError(ex.ToString());
}
}
#region SendInput
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
/// <param name="requestInfo"></param>
public void SendInput(IRequestInfo requestInfo)
{
this.PreviewSend(requestInfo);
}
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
@@ -100,6 +122,98 @@ namespace ThingsGateway.Foundation.Core
this.PreviewSend(transferBytes);
}
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
/// <param name="requestInfo"></param>
/// <returns></returns>
public Task SendInputAsync(IRequestInfo requestInfo)
{
return this.PreviewSendAsync(requestInfo);
}
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public Task SendInputAsync(byte[] buffer, int offset, int length)
{
return this.PreviewSendAsync(buffer, offset, length);
}
/// <summary>
/// 发送数据的切入点,该方法由框架自动调用。
/// </summary>
/// <param name="transferBytes"></param>
public Task SendInputAsync(IList<ArraySegment<byte>> transferBytes)
{
return this.PreviewSendAsync(transferBytes);
}
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="requestInfo"></param>
protected virtual void PreviewSend(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="buffer">数据</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
protected virtual void PreviewSend(byte[] buffer, int offset, int length)
{
this.GoSend(buffer, offset, length);
}
/// <summary>
/// 组合发送预处理数据,
/// 当属性SplicingSend实现为True时系统才会调用该方法。
/// </summary>
/// <param name="transferBytes">代发送数据组合</param>
protected virtual void PreviewSend(IList<ArraySegment<byte>> transferBytes)
{
throw new NotImplementedException();
}
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="requestInfo"></param>
protected virtual Task PreviewSendAsync(IRequestInfo requestInfo)
{
throw new NotImplementedException();
}
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="buffer">数据</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
protected virtual Task PreviewSendAsync(byte[] buffer, int offset, int length)
{
return this.GoSendAsync(buffer, offset, length);
}
/// <summary>
/// 组合发送预处理数据,
/// 当属性SplicingSend实现为True时系统才会调用该方法。
/// </summary>
/// <param name="transferBytes">代发送数据组合</param>
protected virtual Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
{
throw new NotImplementedException();
}
#endregion SendInput
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -130,27 +244,24 @@ namespace ThingsGateway.Foundation.Core
this.SendCallBack.Invoke(buffer, offset, length);
}
/// <summary>
/// 异步发送已经经过预先处理后的数据
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <returns></returns>
protected Task GoSendAsync(byte[] buffer, int offset, int length)
{
return this.SendAsyncCallBack.Invoke(buffer, offset, length);
}
/// <summary>
/// 当接收到数据后预先处理数据,然后调用<see cref="GoReceived(ByteBlock, IRequestInfo)"/>处理数据
/// </summary>
/// <param name="byteBlock"></param>
protected abstract void PreviewReceived(ByteBlock byteBlock);
/// <summary>
/// 当发送数据前预先处理数据
/// </summary>
/// <param name="buffer">数据</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
protected abstract void PreviewSend(byte[] buffer, int offset, int length);
/// <summary>
/// 组合发送预处理数据,
/// 当属性SplicingSend实现为True时系统才会调用该方法。
/// </summary>
/// <param name="transferBytes">代发送数据组合</param>
protected abstract void PreviewSend(IList<ArraySegment<byte>> transferBytes);
/// <summary>
/// 重置解析器到初始状态,一般在<see cref="DataHandlingAdapter.OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。
/// </summary>

View File

@@ -63,9 +63,11 @@ namespace ThingsGateway.Foundation.Core
/// <returns></returns>
public static SingleStreamDataAdapterTester CreateTester(SingleStreamDataHandlingAdapter adapter, int bufferLength = 1024, Action<ByteBlock, IRequestInfo> receivedCallBack = default)
{
var tester = new SingleStreamDataAdapterTester();
tester.m_adapter = adapter;
tester.m_bufferLength = bufferLength;
var tester = new SingleStreamDataAdapterTester
{
m_adapter = adapter,
m_bufferLength = bufferLength
};
adapter.SendCallBack = tester.SendCallback;
adapter.ReceivedCallBack = tester.OnReceived;
tester.m_receivedCallBack = receivedCallBack;
@@ -129,7 +131,7 @@ namespace ThingsGateway.Foundation.Core
{
while (!this.m_dispose)
{
if (this.tryGet(out var byteBlocks))
if (this.TryGet(out var byteBlocks))
{
foreach (var block in byteBlocks)
{
@@ -163,7 +165,7 @@ namespace ThingsGateway.Foundation.Core
this.m_asyncBytes.Enqueue(asyncByte);
}
private bool tryGet(out List<ByteBlock> byteBlocks)
private bool TryGet(out List<ByteBlock> byteBlocks)
{
byteBlocks = new List<ByteBlock>();
ByteBlock block = null;

View File

@@ -70,10 +70,9 @@ namespace ThingsGateway.Foundation.Core
/// <inheritdoc/>
/// </summary>
/// <param name="fromType"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
public object Resolve(Type fromType, object[] ps = null, string key = "")
public object Resolve(Type fromType, string key = "")
{
if (fromType == typeof(IContainer))
{
@@ -108,11 +107,11 @@ namespace ThingsGateway.Foundation.Core
{
if (descriptor.ToType.IsGenericType)
{
return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()), ps));
return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments())));
}
else
{
return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType, ps));
return descriptor.ToInstance = this.Create(descriptor, descriptor.ToType);
}
}
}
@@ -120,11 +119,11 @@ namespace ThingsGateway.Foundation.Core
if (descriptor.ToType.IsGenericType)
{
return this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()), ps);
return this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()));
}
else
{
return this.Create(descriptor, descriptor.ToType, ps);
return this.Create(descriptor, descriptor.ToType);
}
}
}
@@ -143,10 +142,10 @@ namespace ThingsGateway.Foundation.Core
}
lock (descriptor)
{
return descriptor.ToInstance ??= this.Create(descriptor, descriptor.ToType, ps);
return descriptor.ToInstance ??= this.Create(descriptor, descriptor.ToType);
}
}
return this.Create(descriptor, descriptor.ToType, ps);
return this.Create(descriptor, descriptor.ToType);
}
else
{
@@ -172,7 +171,7 @@ namespace ThingsGateway.Foundation.Core
this.m_registrations.TryRemove(k, out _);
}
private object Create(DependencyDescriptor descriptor, Type toType, object[] ops)
private object Create(DependencyDescriptor descriptor, Type toType)
{
var ctor = toType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true));
if (ctor is null)
@@ -198,28 +197,21 @@ namespace ThingsGateway.Foundation.Core
{
for (var i = 0; i < parameters.Length; i++)
{
if (ops != null && ops.Length - 1 >= i)
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
{
ps[i] = ops[i];
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
}
else
{
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = this.Resolve(type, attribute.Key);
}
else
{
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = this.Resolve(type, default, attribute.Key);
}
else
{
ps[i] = this.Resolve(parameters[i].ParameterType, null);
}
ps[i] = this.Resolve(parameters[i].ParameterType, null);
}
}
}
@@ -239,7 +231,7 @@ namespace ThingsGateway.Foundation.Core
{
var attribute = item.GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? item.PropertyType;
obj = this.Resolve(type, default, attribute.Key);
obj = this.Resolve(type, attribute.Key);
}
else
{
@@ -259,28 +251,21 @@ namespace ThingsGateway.Foundation.Core
ps = new object[parameters.Length];
for (var i = 0; i < ps.Length; i++)
{
if (ops != null && ops.Length - 1 >= i)
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
{
ps[i] = ops[i];
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
}
else
{
if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string))
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default;
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = this.Resolve(type, attribute.Key);
}
else
{
if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true))
{
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = this.Resolve(type, default, attribute.Key);
}
else
{
ps[i] = this.Resolve(parameters[i].ParameterType, null);
}
ps[i] = this.Resolve(parameters[i].ParameterType, null);
}
}
}

View File

@@ -381,35 +381,11 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Resolve<T>(this IContainer container, object[] ps, string key = "")
public static T Resolve<T>(this IContainer container, string key = "")
{
return (T)container.Resolve(typeof(T), ps, key);
}
/// <summary>
/// 创建类型对应的实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <returns></returns>
public static T Resolve<T>(this IContainer container)
{
return Resolve<T>(container, null);
}
/// <summary>
/// 创建类型对应的实例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T Resolve<T>(this IContainer container, string key)
{
return Resolve<T>(container, null, key);
return (T)container.Resolve(typeof(T), key);
}
/// <summary>
@@ -461,7 +437,7 @@ namespace ThingsGateway.Foundation.Core
{
var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>();
var type = attribute.Type ?? parameters[i].ParameterType;
ps[i] = container.Resolve(type, default, attribute.Key);
ps[i] = container.Resolve(type, attribute.Key);
}
else
{
@@ -489,47 +465,22 @@ namespace ThingsGateway.Foundation.Core
return (T)ResolveWithoutRoot(container, typeof(T));
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T TryResolve<T>(this IContainer container, object[] ps, string key = "")
{
return (T)container.TryResolve(typeof(T), ps, key);
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <param name="container"></param>
/// <param name="fromType"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
public static object TryResolve(this IContainer container, Type fromType, object[] ps, string key = "")
public static object TryResolve(this IContainer container, Type fromType, string key = "")
{
if (container.IsRegistered(fromType))
{
return container.Resolve(fromType, ps, key);
return container.Resolve(fromType, key);
}
return default;
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="container"></param>
/// <returns></returns>
public static T TryResolve<T>(this IContainer container)
{
return TryResolve<T>(container, null);
}
/// <summary>
/// 尝试创建类型对应的实例如果类型没有注册则会返回null或者默认值类型。
/// </summary>
@@ -537,9 +488,9 @@ namespace ThingsGateway.Foundation.Core
/// <param name="container"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T TryResolve<T>(this IContainer container, string key)
public static T TryResolve<T>(this IContainer container, string key = "")
{
return TryResolve<T>(container, null, key);
return (T)TryResolve(container, typeof(T), key);
}
#endregion Resolve

View File

@@ -34,10 +34,9 @@ namespace ThingsGateway.Foundation.Core
/// 创建目标类型的对应实例。
/// </summary>
/// <param name="fromType"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
object Resolve(Type fromType, object[] ps = null, string key = "");
object Resolve(Type fromType, string key = "");
/// <summary>
/// 判断某类型是否已经注册

View File

@@ -67,13 +67,13 @@ namespace ThingsGateway.Foundation.Core
/// <inheritdoc/>
/// <exception cref="Exception"></exception>
public object Resolve(Type fromType, object[] ps = null, string key = "")
public object Resolve(Type fromType, string key = "")
{
if (fromType.FullName == "ThingsGateway.Foundation.Core.IContainer")
{
return this;
}
if (this.TryResolve(fromType, out var instance, ps, key))
if (this.TryResolve(fromType, out var instance, key))
{
return instance;
}
@@ -100,10 +100,9 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
/// <param name="fromType"></param>
/// <param name="instance"></param>
/// <param name="ps"></param>
/// <param name="key"></param>
/// <returns></returns>
protected virtual bool TryResolve(Type fromType, out object instance, object[] ps = null, string key = "")
protected virtual bool TryResolve(Type fromType, out object instance, string key = "")
{
if (key.IsNullOrEmpty())
{

View File

@@ -182,7 +182,7 @@ namespace ThingsGateway.Foundation.Core
}
if (!flag && !converter.CanConvertTo(destinationType))
{
throw new InvalidOperationException("无法转换成类型:" + value.ToString() + "==>" + destinationType);
throw new InvalidOperationException($"无法转换成类型:{value.ToString()}==>{destinationType}");
}
try
{
@@ -190,7 +190,7 @@ namespace ThingsGateway.Foundation.Core
}
catch (Exception e)
{
throw new InvalidOperationException(" 类型转换出错:" + value.ToString() + "==>" + destinationType, e);
throw new InvalidOperationException($" 类型转换出错:{value.ToString()}==>{destinationType}", e);
}
return returnValue;
}

View File

@@ -22,6 +22,9 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Runtime.CompilerServices;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
@@ -29,5 +32,46 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public static class TaskExtension
{
/// <summary>
/// 同步获取配置ConfigureAwait为false时的结果。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="task"></param>
/// <returns></returns>
public static T GetFalseAwaitResult<T>(this Task<T> task)
{
return task.ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>
/// 同步配置ConfigureAwait为false时的执行。
/// </summary>
/// <param name="task"></param>
public static void GetFalseAwaitResult(this Task task)
{
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

@@ -70,6 +70,15 @@ namespace ThingsGateway.Foundation.Core
return isPeriod;
}
/// <summary>
/// 累计增加一个计数
/// </summary>
/// <returns></returns>
public bool Increment()
{
return this.Increment(1);
}
/// <summary>
/// 重置<see cref="Count"/>和<see cref="LastIncrement"/>
/// </summary>

View File

@@ -47,14 +47,7 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public TimeSpan Period { get; set; }
/// <summary>
/// 重置<see cref="Count"/>和<see cref="LastIncrement"/>
/// </summary>
public void Reset()
{
this.m_count = 0;
this.m_lastIncrement = default;
}
/// <summary>
/// 累计增加计数
@@ -78,5 +71,26 @@ namespace ThingsGateway.Foundation.Core
Interlocked.Add(ref this.m_count, value);
return isPeriod;
}
/// <summary>
/// 累计增加一个计数
/// </summary>
/// <returns></returns>
public bool Increment()
{
return this.Increment(1);
}
/// <summary>
/// 重置<see cref="Count"/>和<see cref="LastIncrement"/>
/// </summary>
public void Reset()
{
this.m_count = 0;
this.m_lastIncrement = default;
}
}
}

View File

@@ -133,7 +133,7 @@ namespace ThingsGateway.Foundation.Core
catch (Exception ex)
{
fileStorage = null;
msg = ex.Message;
msg = ex.ToString();
return false;
}
}

View File

@@ -134,7 +134,7 @@ namespace ThingsGateway.Foundation.Core
string path = null;
while (true)
{
path = Path.Combine(dir, $"{count:0000}" + ".log");
path = Path.Combine(dir, $"{count:0000}.log");
if (!File.Exists(path))
{
this.m_writer = FilePool.GetWriter(path);

View File

@@ -292,7 +292,13 @@ public static class LoggerExtensions
{
logger.Log(ThingsGateway.Foundation.Core.LogLevel.Error, null, msg, ex);
}
/// <summary>
/// 输出错误日志
/// </summary>
public static void LogError(this ILog logger, Exception ex)
{
logger.Log(ThingsGateway.Foundation.Core.LogLevel.Error, null, ex.Message, ex);
}
/// <summary>
/// 输出警示日志
@@ -301,7 +307,13 @@ public static class LoggerExtensions
{
logger.Log(ThingsGateway.Foundation.Core.LogLevel.Warning, null, msg, ex);
}
/// <summary>
/// 输出警示日志
/// </summary>
public static void LogWarning(this ILog logger, Exception ex)
{
logger.Log(ThingsGateway.Foundation.Core.LogLevel.Warning, null, ex.Message, ex);
}
/// <summary>
/// 输出警示日志

View File

@@ -30,14 +30,6 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public interface IPlugin : IDisposable
{
/// <summary>
/// 插件执行顺序
/// <para>该属性值越大,越靠前执行。值相等时,按添加先后顺序</para>
/// <para>该属性效果,仅在<see cref="IPluginsManager.Add(IPlugin)"/>之前设置有效。</para>
/// </summary>
[Obsolete("该属性已被弃用,插件顺序将直接由添加顺序决定。本设置将在正式版发布时直接删除", true)]
int Order { get; set; }
/// <summary>
/// 在插件被成功添加在<see cref="IPluginsManager"/>时执行。
/// </summary>

View File

@@ -17,9 +17,6 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
public class PluginBase : DisposableObject, IPlugin
{
/// <inheritdoc/>
[Obsolete("该属性已被弃用,插件顺序将直接由添加顺序决定。本设置将在正式版发布时直接删除", true)]
public int Order { get; set; }
/// <inheritdoc cref="IPlugin.Loaded(IPluginsManager)"/>
protected virtual void Loaded(IPluginsManager pluginsManager)

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

@@ -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;
@@ -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,28 +215,56 @@ 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);
}
/// <inheritdoc/>
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public override void Close(string msg = "")
{
if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message)
if (this.IsHandshaked)
{
if (!this.m_smtpActor.InputReceivedData(message))
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 (!await this.m_dmtpActor.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
return false;
return;
}
return base.HandleReceivedData(byteBlock, requestInfo);
await base.ReceivedData(e);
}
/// <inheritdoc/>
@@ -250,25 +278,19 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
/// <inheritdoc/>
protected override void OnDisconnected(DisconnectEventArgs e)
{
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
@@ -62,23 +62,34 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
protected override void OnConnected(TClient socketClient, ConnectedEventArgs e)
protected override async Task OnConnected(TClient socketClient, ConnectedEventArgs e)
{
socketClient.m_internalOnRpcActorInit = this.PrivateOnRpcActorInit;
base.OnConnected(socketClient, e);
}
private IDmtpActor OnServiceFindDmtpActor(string id)
{
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
await base.OnConnected(socketClient, e);
}
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,89 +49,72 @@ 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);
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="e"></param>
protected override void OnDisconnected(DisconnectEventArgs e)
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.DmtpActor?.Close(false, e.Message);
base.OnDisconnected(e);
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>
/// <param name="request"></param>
protected override void OnReceivedHttpRequest(HttpRequest request)
protected override async Task OnReceivedHttpRequest(HttpRequest request)
{
if (request.IsMethod(DmtpUtility.Dmtp) && request.IsUpgrade() &&
string.Equals(request.Headers.Get(HttpHeaders.Upgrade), DmtpUtility.Dmtp, StringComparison.OrdinalIgnoreCase))
@@ -142,69 +125,76 @@ namespace ThingsGateway.Foundation.Dmtp
this.DefaultSend(new HttpResponse().SetStatus(101, "Switching Protocols").BuildAsBytes());
return;
}
base.OnReceivedHttpRequest(request);
await base.OnReceivedHttpRequest(request);
}
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
{
if (!await this.m_dmtpActor.InputReceivedData(message))
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
await base.ReceivedData(e);
}
private Task OnDmtpIdChanged(DmtpActor actor, IdChangedEventArgs e)
{
this.DirectResetId(e.NewId);
return EasyTask.CompletedTask;
}
private void SetRpcActor(DmtpActor actor)
{
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)
{
@@ -215,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
@@ -244,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

@@ -38,22 +38,25 @@ namespace ThingsGateway.Foundation.Dmtp
this.Protocol = DmtpUtility.DmtpProtocol;
}
/// <inheritdoc/>
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 bool m_allowRoute;
private Func<string, IDmtpActor> m_findDmtpActor;
private SealedDmtpActor m_smtpActor;
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
private bool m_allowRoute;
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;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
#region
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
@@ -62,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>
@@ -86,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;
}
@@ -106,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;
}
@@ -128,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
@@ -153,11 +178,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), 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
@@ -173,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
@@ -228,27 +252,6 @@ namespace ThingsGateway.Foundation.Dmtp
#endregion
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.DmtpActor.SafeDispose();
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
var message = (DmtpMessage)requestInfo;
if (!this.m_smtpActor.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
return false;
}
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)
{
@@ -259,82 +262,71 @@ 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 void OnDisconnected(DisconnectEventArgs e)
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
base.OnDisconnected(e);
this.DmtpActor.Close(false, e.Message);
var message = (DmtpMessage)e.RequestInfo;
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
await base.ReceivedData(e).ConfigureFalseAwait();
}
#region
private void OnDmtpActorClose(DmtpActor actor, string msg)
{
base.Close(msg);
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
this.OnRouting(e);
}
private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
base.Send(transferBytes);
}
private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
return base.SendAsync(transferBytes);
}
private Task OnDmtpActorClose(DmtpActor actor, string msg)
{
this.BreakOut(false, msg);
return EasyTask.CompletedTask;
}
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
return this.OnCreatedChannel(e);
}
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
return this.OnHandshaked(e);
}
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
return this.OnHandshaking(e);
}
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
return this.OnRouting(e);
}
#endregion
#region
@@ -343,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
@@ -68,19 +68,30 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
/// <param name="socketClient"></param>
/// <param name="e"></param>
protected override void OnConnecting(TClient socketClient, ConnectingEventArgs e)
protected override async Task OnConnecting(TClient socketClient, ConnectingEventArgs e)
{
socketClient.SetDmtpActor(new SealedDmtpActor(this.m_allowRoute)
{
Id = e.Id,
OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null
FindDmtpActor = this.FindDmtpActor
});
base.OnConnecting(socketClient, e);
await base.OnConnecting(socketClient, e);
}
private IDmtpActor OnServiceFindDmtpActor(string id)
private async Task<IDmtpActor> FindDmtpActor(string id)
{
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
if (this.m_allowRoute)
{
if (this.m_findDmtpActor != null)
{
return await this.m_findDmtpActor.Invoke(id);
}
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
}
else
{
return null;
}
}
}
}

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
@@ -40,12 +40,12 @@ namespace ThingsGateway.Foundation.Dmtp
this.Protocol = DmtpUtility.DmtpProtocol;
}
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
/// <summary>
/// 验证超时时间,默认为3000ms
/// </summary>
@@ -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,102 +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;
this.m_dmtpActor = actor;
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
this.DmtpActor.SafeDispose();
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
var message = (DmtpMessage)requestInfo;
if (!this.m_smtpActor.InputReceivedData(message))
var message = (DmtpMessage)e.RequestInfo;
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
if (this.PluginsManager.Enable)
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
return false;
await base.ReceivedData(e).ConfigureFalseAwait();
}
/// <inheritdoc/>
protected override void OnConnected(ConnectedEventArgs e)
protected override async Task OnConnected(ConnectedEventArgs e)
{
this.m_smtpActor.Id = this.Id;
base.OnConnected(e);
this.m_dmtpActor.Id = this.Id;
await base.OnConnected(e).ConfigureFalseAwait();
Task.Run(async () =>
_ = Task.Run(async () =>
{
await Task.Delay(this.VerifyTimeout);
await Task.Delay(this.VerifyTimeout).ConfigureFalseAwait();
if (!this.IsHandshaked)
{
this.TryShutdown();
@@ -231,23 +250,22 @@ namespace ThingsGateway.Foundation.Dmtp
});
}
/// <inheritdoc/>
protected override void OnDisconnected(DisconnectEventArgs e)
{
this.DmtpActor.Close(false, e.Message);
base.OnDisconnected(e);
}
private void ThisOnResetId(DmtpActor rpcActor, 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);
}
private Task ThisOnResetId(DmtpActor rpcActor, IdChangedEventArgs e)
{
this.DirectResetId(e.NewId);
return EasyTask.CompletedTask;
}
#region
/// <summary>

View File

@@ -75,20 +75,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
/// <inheritdoc/>
protected override void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo)
protected override async Task ReceivedData(UdpReceivedDataEventArgs e)
{
var client = this.PrivateGetUdpDmtpClient(remoteEndPoint);
var client = this.PrivateGetUdpDmtpClient(e.EndPoint);
if (client == null)
{
return;
}
var message = DmtpMessage.CreateFrom(byteBlock);
if (!client.InputReceivedData(message))
var message = DmtpMessage.CreateFrom(e.ByteBlock);
if (!await client.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message));
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message));
}
}
}

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

@@ -49,16 +49,18 @@ namespace ThingsGateway.Foundation.Dmtp
}
#region
#pragma warning disable CS0414
private bool m_allowRoute;
#pragma warning restore CS0414
private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim m_semaphoreForSend = new SemaphoreSlim(1, 1);
private ClientWebSocket m_client;
private Func<string, IDmtpActor> m_findDmtpActor;
private ValueCounter m_receiveCounter;
private ValueCounter m_sendCounter;
private SealedDmtpActor m_dmtpActor;
private TcpDmtpAdapter m_smtpAdapter;
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
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_dmtpAdapter;
#endregion
/// <inheritdoc/>
@@ -92,25 +94,21 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public DateTime LastSendTime => this.m_sendCounter.LastIncrement;
/// <summary>
/// 未实现
/// </summary>
public Func<ByteBlock, bool> OnHandleRawBuffer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
/// <summary>
/// 未实现
/// </summary>
public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
/// <inheritdoc/>
public IPluginsManager PluginsManager { get; private set; }
/// <inheritdoc/>
public Protocol Protocol { get; set; } = DmtpUtility.DmtpProtocol;
/// <inheritdoc/>
public override int ReceiveBufferSize => this.m_receiveBufferSize;
/// <inheritdoc/>
public IPHost RemoteIPHost { get; private set; }
/// <inheritdoc/>
public override int SendBufferSize => this.m_sendBufferSize;
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
/// </summary>
@@ -118,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/>
@@ -175,7 +132,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForConnect.WaitAsync();
if (this.IsHandshaked)
{
return;
@@ -190,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
};
@@ -214,7 +172,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForConnect.Release();
}
}
@@ -236,18 +194,6 @@ namespace ThingsGateway.Foundation.Dmtp
this.DmtpActor.ResetId(newId);
}
/// <summary>
/// 配置
/// </summary>
/// <param name="ipHost"></param>
/// <returns></returns>
public IWebSocketDmtpClient Setup(string ipHost)
{
var config = new TouchSocketConfig();
config.SetRemoteIPHost(new IPHost(ipHost));
return this.Setup(config);
}
/// <summary>
/// 配置
/// </summary>
@@ -297,7 +243,6 @@ namespace ThingsGateway.Foundation.Dmtp
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
}
}
@@ -331,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);
}
}
@@ -353,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,12 +348,12 @@ namespace ThingsGateway.Foundation.Dmtp
private void OnReceivePeriod(long value)
{
this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value);
this.m_receiveBufferSize = TouchSocketUtility.HitBufferLength(value);
}
private void OnSendPeriod(long value)
{
this.SendBufferSize = TouchSocketUtility.HitBufferLength(value);
this.m_sendBufferSize = TouchSocketUtility.HitBufferLength(value);
}
private void PrivateClose(string msg)
@@ -419,82 +364,89 @@ 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())
{
if (this.PluginsManager.Enable)
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
#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.ConfigureAwait(false);
task.GetAwaiter().GetResult();
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
@@ -505,34 +457,78 @@ 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
#region Receiver
/// <summary>
/// 不支持该功能
/// </summary>
/// <exception cref="NotSupportedException"></exception>
public void ClearReceiver()
{
throw new NotSupportedException("不支持该功能");
}
/// <summary>
/// 不支持该功能
/// </summary>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
public IReceiver CreateReceiver()
{
throw new NotSupportedException("不支持该功能");
}
#endregion Receiver
}
}

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,11 +73,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_pullFileResourceInfo_Request, byteBlock);
return true;
}
else
@@ -96,12 +92,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.SwitchId();
byteBlock.Reset();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
else
{
waitFileResource.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
_ = this.RequestPullFileResourceInfo(waitFileResource);
}
}
catch (Exception ex)
@@ -118,9 +114,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
else
@@ -143,9 +139,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileSection_Request, byteBlock);
await actor.SendAsync(this.m_pullFileSection_Request, byteBlock);
}
else
{
@@ -153,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.SwitchId();
byteBlock.Reset();
waitFileSection.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileSection_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileSection_Response, byteBlock);
}
}
else
@@ -177,9 +173,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileSection_Response, byteBlock);
await actor.SendAsync(this.m_pullFileSection_Response, byteBlock);
}
}
else
@@ -202,11 +198,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_pushFileResourceInfo_Request, byteBlock);
return true;
}
else
@@ -221,12 +217,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
else
{
waitFileResource.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPushFileResourceInfo, waitFileResource);
_ = this.RequestPushFileResourceInfo(waitFileResource);
}
}
catch (Exception ex)
@@ -243,9 +239,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
}
else
@@ -268,9 +264,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileSection_Request, byteBlock);
await actor.SendAsync(this.m_pushFileSection_Request, byteBlock);
}
else
{
@@ -278,7 +274,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.SwitchId();
byteBlock.Reset();
waitFileSection.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileSection_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileSection_Response, byteBlock);
}
}
else
@@ -303,9 +299,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileSection_Response, byteBlock);
await actor.SendAsync(this.m_pushFileSection_Response, byteBlock);
}
}
else
@@ -328,9 +324,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_finishedFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_finishedFileResourceInfo_Request, byteBlock);
}
else
{
@@ -338,13 +334,13 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.SwitchId();
byteBlock.Reset();
waitFinishedPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
}
else
{
waitFinishedPackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestFinishedFileResourceInfo, waitFinishedPackage);
_ = this.RequestFinishedFileResourceInfo(waitFinishedPackage);
}
}
catch (Exception ex)
@@ -361,9 +357,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
}
else
@@ -386,11 +382,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullSmallFile_Request, byteBlock);
await actor.SendAsync(this.m_pullSmallFile_Request, byteBlock);
return true;
}
else
@@ -405,12 +401,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitSmallFilePackage.SwitchId();
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
}
else
{
waitSmallFilePackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
_ = this.RequestPullSmallFile(waitSmallFilePackage);
}
}
catch (Exception ex)
@@ -427,9 +423,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullSmallFile_Response, byteBlock);
await actor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
}
}
else
@@ -452,11 +448,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushSmallFile_Request, byteBlock);
await actor.SendAsync(this.m_pushSmallFile_Request, byteBlock);
return true;
}
else
@@ -472,12 +468,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitSmallFilePackage.SwitchId();
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
}
else
{
waitSmallFilePackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPushSmallFile, waitSmallFilePackage);
_ = this.RequestPushSmallFile(waitSmallFilePackage);
}
}
catch (Exception ex)
@@ -495,9 +491,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushSmallFile_Response, byteBlock);
await actor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
}
}
else
@@ -568,24 +564,20 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.FileController.GetFullPath(this.m_rootPath, path);
}
private bool TryFindDmtpFileTransferActor(string targetId, out DmtpFileTransferActor rpcActor)
private async Task<DmtpFileTransferActor> TryFindDmtpFileTransferActor(string targetId)
{
if (targetId == this.DmtpActor.Id)
{
rpcActor = this;
return true;
return this;
}
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
{
if (smtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
if (dmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
{
rpcActor = newActor;
return true;
return newActor;
}
}
rpcActor = default;
return false;
return default;
}
#region Id传输
@@ -598,9 +590,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivateFinishedFileResourceInfo(targetId, fileResourceInfo, code, metadata, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
return actor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
}
else
{
@@ -625,9 +617,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePullFileResourceInfo(targetId, path, metadata, fileSectionSize, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
return actor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
}
else
{
@@ -652,9 +644,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePullFileSection(targetId, fileSection, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PullFileSection(fileSection, timeout, token);
return actor.PullFileSection(fileSection, timeout, token);
}
else
{
@@ -679,9 +671,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePushFileResourceInfo(targetId, savePath, fileResourceLocator, metadata, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
return actor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
}
else
{
@@ -715,9 +707,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePushFileSection(targetId, fileResourceLocator, fileSection, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
return actor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
}
else
{
@@ -1261,7 +1253,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFinishedPackage.SwitchId();
waitFinishedPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
var args = new FileTransferedEventArgs(transferType, waitFinishedPackage?.Metadata, resourceInfo?.FileInfo, waitFinishedPackage.Code == ResultCode.Canceled ? Result.Canceled : resultThis)
@@ -1332,7 +1324,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
catch
@@ -1454,7 +1446,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
}
catch
@@ -1507,7 +1499,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.Message = ex.Message;
}
waitFileSection.Value.Dispose();
waitFileSection.Value.SafeDispose();
waitFileSection.Value = default;
using (var byteBlock = new ByteBlock())
{
@@ -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

@@ -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)
{
@@ -283,7 +281,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
transientRpcServer.CallContext = callContext;
}
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext);
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext).ConfigureFalseAwait();
}
if (rpcPackage.Feedback == FeedbackType.OnlySend)
@@ -369,24 +367,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
}
private bool TryFindDmtpRpcActor(string targetId, out DmtpRpcActor rpcActor)
private async Task<DmtpRpcActor> TryFindDmtpRpcActor(string targetId)
{
if (targetId == this.DmtpActor.Id)
{
rpcActor = this;
return true;
return this;
}
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
{
if (smtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
if (dmtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
{
rpcActor = newActor;
return true;
return newActor;
}
}
rpcActor = default;
return false;
return default;
}
#region Rpc
@@ -504,8 +498,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -532,7 +524,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -689,8 +680,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -722,7 +711,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -779,8 +767,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitDataAsync(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -818,7 +804,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
@@ -832,7 +818,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -898,7 +884,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -907,7 +892,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
@@ -918,7 +903,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -961,7 +946,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
actor.Invoke(invokeKey, invokeOption, parameters);
return;
@@ -977,7 +962,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1009,7 +993,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1069,9 +1052,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
return rpcActor.Invoke(returnType, invokeKey, invokeOption, parameters);
return actor.Invoke(returnType, invokeKey, invokeOption, parameters);
}
var rpcPackage = new DmtpRpcPackage
@@ -1084,10 +1067,8 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
{
if (invokeOption == default)
@@ -1116,7 +1097,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1175,9 +1155,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
rpcActor.Invoke(invokeKey, invokeOption, ref parameters, types);
actor.Invoke(invokeKey, invokeOption, ref parameters, types);
return;
}
@@ -1191,7 +1171,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1219,7 +1198,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1289,9 +1267,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
return rpcActor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
return actor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
}
var rpcPackage = new DmtpRpcPackage
@@ -1304,7 +1282,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1330,7 +1307,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1400,9 +1376,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
{
await actor.InvokeAsync(invokeKey, invokeOption, parameters);
await actor.InvokeAsync(invokeKey, invokeOption, parameters).ConfigureFalseAwait();
return;
}
@@ -1416,7 +1392,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitDataAsync(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1448,7 +1423,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1456,7 +1430,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
@@ -1470,7 +1444,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -1508,9 +1482,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
{
return await rpcActor.InvokeAsync(returnType, invokeKey, invokeOption, parameters);
return await actor.InvokeAsync(returnType, invokeKey, invokeOption, parameters).ConfigureFalseAwait();
}
var rpcPackage = new DmtpRpcPackage
@@ -1553,8 +1527,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1563,7 +1535,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
@@ -1574,7 +1546,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{

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

@@ -213,14 +213,11 @@ namespace ThingsGateway.Foundation.Http
base.Dispose(disposing);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="byteBlock"></param>
/// <param name="requestInfo"></param>
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
protected override Task ReceivedData(ReceivedDataEventArgs e)
{
if (requestInfo is HttpResponse response)
if (e.RequestInfo is HttpResponse response)
{
if (this.m_getContent)
{
@@ -229,18 +226,18 @@ namespace ThingsGateway.Foundation.Http
this.m_waitData.Set(response);
}
return false;
return base.ReceivedData(e);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="e"></param>
protected override void OnConnecting(ConnectingEventArgs e)
protected override async Task OnConnecting(ConnectingEventArgs e)
{
this.Protocol = Protocol.Http;
this.SetDataHandlingAdapter(new HttpClientDataHandlingAdapter());
base.OnConnecting(e);
await base.OnConnecting(e);
}
}
}

View File

@@ -20,6 +20,8 @@ using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Sockets;
using HttpClient = System.Net.Http.HttpClient;
using HttpMethod = System.Net.Http.HttpMethod;
namespace ThingsGateway.Foundation.Http
{
@@ -100,16 +102,6 @@ namespace ThingsGateway.Foundation.Http
return this;
}
/// <summary>
/// 配置
/// </summary>
/// <param name="remoteIPHost"></param>
/// <returns></returns>
public HttpClientSlim Setup(string remoteIPHost)
{
return this.Setup(new TouchSocketConfig().SetRemoteIPHost(remoteIPHost));
}
private void BuildConfig(TouchSocketConfig config)
{
this.Config = config;

View File

@@ -39,34 +39,35 @@ namespace ThingsGateway.Foundation.Http
}
/// <inheritdoc/>
protected override void OnConnecting(ConnectingEventArgs e)
protected override async Task OnConnecting(ConnectingEventArgs e)
{
this.SetDataHandlingAdapter(new HttpServerDataHandlingAdapter());
base.OnConnecting(e);
await base.OnConnecting(e);
}
/// <inheritdoc/>
protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
if (requestInfo is HttpRequest request)
if (e.RequestInfo is HttpRequest request)
{
this.OnReceivedHttpRequest(request);
await this.OnReceivedHttpRequest(request);
}
return false;
await base.ReceivedData(e);
}
/// <summary>
/// 当收到到Http请求时。覆盖父类方法将不会触发插件。
/// </summary>
protected virtual void OnReceivedHttpRequest(HttpRequest request)
protected virtual Task OnReceivedHttpRequest(HttpRequest request)
{
if (this.PluginsManager.GetPluginCount(nameof(IHttpPlugin.OnHttpRequest)) > 0)
{
var e = new HttpContextEventArgs(new HttpContext(request));
this.PluginsManager.Raise(nameof(IHttpPlugin.OnHttpRequest), this, e);
return this.PluginsManager.RaiseAsync(nameof(IHttpPlugin.OnHttpRequest), this, e);
}
return EasyTask.CompletedTask;
}
}
}

View File

@@ -374,7 +374,7 @@ namespace ThingsGateway.Foundation.Http
/// <returns></returns>
public static TResponse SetContentTypeFromFileName<TResponse>(this TResponse response, string fileName) where TResponse : HttpResponse
{
var contentDisposition = "attachment;" + "filename=" + System.Web.HttpUtility.UrlEncode(fileName);
var contentDisposition = $"attachment;filename={System.Web.HttpUtility.UrlEncode(fileName)}";
response.Headers.Add(HttpHeaders.ContentDisposition, contentDisposition);
return response;
}
@@ -429,7 +429,7 @@ namespace ThingsGateway.Foundation.Http
using (var reader = FilePool.GetReader(filePath))
{
response.SetContentTypeByExtension(Path.GetExtension(filePath));
var contentDisposition = "attachment;" + "filename=" + System.Web.HttpUtility.UrlEncode(fileName ?? Path.GetFileName(filePath));
var contentDisposition = $"attachment;filename={System.Web.HttpUtility.UrlEncode(fileName ?? Path.GetFileName(filePath))}";
response.Headers.Add(HttpHeaders.ContentDisposition, contentDisposition);
response.Headers.Add(HttpHeaders.AcceptRanges, "bytes");
@@ -526,7 +526,7 @@ namespace ThingsGateway.Foundation.Http
using (var reader = FilePool.GetReader(filePath))
{
context.Response.SetContentTypeByExtension(Path.GetExtension(filePath));
var contentDisposition = "attachment;" + "filename=" + System.Web.HttpUtility.UrlEncode(fileName ?? Path.GetFileName(filePath));
var contentDisposition = $"attachment;filename={System.Web.HttpUtility.UrlEncode(fileName ?? Path.GetFileName(filePath))}";
context.Response.Headers.Add(HttpHeaders.ContentDisposition, contentDisposition);
context.Response.Headers.Add(HttpHeaders.AcceptRanges, "bytes");

Some files were not shown because too many files have changed in this diff Show More