Compare commits

...

55 Commits

Author SHA1 Message Date
Kimdiego2098
4cf35f7294 发布3.0.1版本 2023-11-03 11:32:13 +08:00
Kimdiego2098
94c77d151b update touchsocket 2023-11-03 11:27:12 +08:00
Kimdiego2098
7f600e2b4b update touchsocket 2023-11-03 11:19:26 +08:00
Kimdiego2098
c809d0ba87 不存在插件时,报错内容优化 2023-11-01 14:51:08 +08:00
Kimdiego2098
50f038ec89 update webapiClient 2023-11-01 14:21:53 +08:00
Kimdiego2098
9199a255a2 调整Timeout属性为int数据类型 2023-10-31 23:49:46 +08:00
Kimdiego2098
d324537b47 更新发布版3.0.0.28 2023-10-31 17:47:07 +08:00
Kimdiego2098
d0c05685f7 更新OPCUAClient,订阅模式适配 分组 2023-10-31 10:55:50 +08:00
Kimdiego2098
1063c930b5 update 2023-10-31 00:24:00 +08:00
Kimdiego2098
79cbd44366 tcpservice停止时执行shutdown方法,修复demo发布不显示页面的问题 2023-10-30 21:31:30 +08:00
Kimdiego2098
7fdac1c5cb 添加部分Pro内容 2023-10-29 19:39:38 +08:00
Kimdiego2098
0c0cf72ebb 添加部分Pro内容 2023-10-29 19:34:17 +08:00
Kimdiego2098
8e2fe175ed 更新文档 2023-10-28 22:06:58 +08:00
Kimdiego2098
d1cff037c9 发布3.0.0.27版本;
优化设备线程启停逻辑
添加winform(blazor) demo
部分页面显示内容优化
2023-10-28 22:03:52 +08:00
Kimdiego2098
fc88a2fafa 发布3.0.0.27版本;
优化设备线程启停逻辑
添加winform(blazor) demo
部分页面显示内容优化
2023-10-28 22:00:35 +08:00
Kimdiego2098
45fcceb056 优化设备线程启停逻辑 2023-10-28 21:58:09 +08:00
Kimdiego2098
7043477038 添加部分Pro内容 2023-10-28 21:21:03 +08:00
Kimdiego2098
7dd685cf54 添加winform(blazor) demo 2023-10-28 15:20:12 +08:00
Kimdiego2098
5f5e4969c0 调整pro类库 2023-10-28 10:54:26 +08:00
Diego2098
8a53fd19e9 设备状态页面显示优化 2023-10-27 20:19:26 +08:00
Diego2098
baf4714c36 状态显示:已退出自动更新 2023-10-27 20:18:57 +08:00
Kimdiego2098
7ba9ac7a5b 报文显示限长500 2023-10-27 14:53:19 +08:00
Kimdiego2098
85b8f26e8e tcpserver 报文输出 添加 ip端口 提示 2023-10-27 14:41:35 +08:00
Kimdiego2098
594a0f1410 update the tcpserver class and add log output for start and stop 2023-10-27 14:24:26 +08:00
Kimdiego2098
d317d757d7 优化线程上下文转换 2023-10-26 19:16:24 +08:00
Kimdiego2098
fdf0ba6318 添加ConfigureAwait 2023-10-26 18:06:33 +08:00
Kimdiego2098
15bf7de5fa 优化设备导出逻辑 2023-10-26 15:15:43 +08:00
Kimdiego2098
d3402b058e 优化设备导出逻辑 2023-10-26 15:10:26 +08:00
Kimdiego2098
e7dfdd4031 3.0.0.25 2023-10-26 13:21:40 +08:00
Kimdiego2098
b2dd7b6364 Merge branch 'master' of https://gitee.com/dotnetchina/ThingsGateway 2023-10-26 13:20:54 +08:00
Kimdiego2098
9bd6d9abbf 3.0.0.25 2023-10-26 13:20:31 +08:00
Kimdiego2098
cd14428fea update 2023-10-26 13:19:18 +08:00
Kimdiego2098
19d9f03c2b s7添加错误返回码提示,组包处理 2023-10-26 13:05:06 +08:00
Kimdiego2098
0d57e72bbf 增加硬件信息 相关json配置 2023-10-26 10:54:48 +08:00
Kimdiego2098
329516a61b 更新nuget依赖 2023-10-26 09:37:01 +08:00
Kimdiego2098
d566869589 硬件信息页面添加刷新条件 2023-10-26 09:20:25 +08:00
Kimdiego2098
9cb8d8e6c7 更新文档 2023-10-25 00:53:27 +08:00
Kimdiego2098
9de3c57e5d update touchsocket 2023-10-25 00:53:17 +08:00
Kimdiego2098
f32ff92b0b <Version>3.0.0.24</Version> 2023-10-24 23:48:20 +08:00
Kimdiego2098
88d71e271e 更改S7协议 设备属性,注意删除了DstTSAP,改为较直观的 机架号/槽位号 2023-10-24 23:47:35 +08:00
Kimdiego2098
fd9c14612a 添加属性识别 16进制写入 2023-10-24 23:46:50 +08:00
Kimdiego2098
e26e5a160f 添加nuget依赖包 2023-10-24 20:50:39 +08:00
Kimdiego2098
b836bfed22 更新nuget包 2023-10-24 00:37:46 +08:00
Kimdiego2098
a4b598c6d0 调整解决方案文件夹 2023-10-24 00:13:03 +08:00
Kimdiego2098
c9ab755839 暂时屏蔽mqttserver 遗留消息错误 2023-10-23 20:51:11 +08:00
Kimdiego2098
9920edba53 调整编码 2023-10-23 20:47:00 +08:00
Kimdiego2098
12bd7280d1 调整mqttlog 2023-10-23 20:46:17 +08:00
Kimdiego2098
d30ea7f63b 调整mqttlog 2023-10-23 20:43:58 +08:00
Kimdiego2098
ebd3390db6 添加部分兼容方法 2023-10-22 02:42:16 +08:00
Kimdiego2098
9a374a9ebc 添加部分兼容方法 2023-10-22 02:26:18 +08:00
Kimdiego2098
b1bc22cb08 update touchsocket 2023-10-22 02:26:04 +08:00
Kimdiego2098
4930d53890 调整代码格式 2023-10-21 19:15:26 +08:00
Kimdiego2098
c31327b5bc update touchsocket 2023-10-21 19:08:21 +08:00
Kimdiego2098
3f2aa1f1e1 调整代码格式 2023-10-21 19:03:15 +08:00
Kimdiego2098
6e78c00a96 调整代码格式 2023-10-21 19:02:58 +08:00
288 changed files with 5260 additions and 3291 deletions

View File

@@ -1,8 +1,7 @@
<Project>
<PropertyGroup>
<Version>3.0.0.23</Version>
<Version>3.0.1.0</Version>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -32,7 +32,6 @@ internal class Program
AppDomain.CurrentDomain.UnhandledException += (sender, error) =>
{
};
app.Run();
}
}

View File

@@ -2,6 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
@@ -28,5 +29,18 @@
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\favicon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\favicon.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -26,10 +26,10 @@
<MTextField Class="ma-1" Style="max-width:100px" Label="端口" Dense Outlined HideDetails="@("auto")" @bind-Value=@port />
<MButton Class="ma-1" OnClick=@Connect Color="primary">
连接
启动
</MButton>
<MButton Class="ma-1" OnClick=@DisConnect Color="red">
断开
停止
</MButton>

View File

@@ -1,12 +1,12 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>
// GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway
// GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway
// ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/
// QQȺ<EFBFBD><EFBFBD>605534569
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://diego2098.gitee.io/thingsgateway-docs/
// QQ群:605534569
//------------------------------------------------------------------------------
#endregion
@@ -26,7 +26,7 @@ public partial class MainLayout
[
{
"Href": "/index",
"Title": "<EFBFBD><EFBFBD>ҳ"
"Title": "首页"
},
{
"Title": "Modbus",
@@ -207,19 +207,40 @@ public partial class MainLayout
]
},
{
"Title": "GasCustom",
"Title": "HZW_QTJC_01",
"Children": [
{
"Href": "/GasCustomSerial",
"Title": "GasCustomSerial"
"Href": "/HZW_QTJC_01Serial",
"Title": "HZW_QTJC_01Serial"
},
{
"Href": "/GasCustomSerialOverTcp",
"Title": "GasCustomSerialOverTcp"
"Href": "/HZW_QTJC_01SerialOverTcp",
"Title": "HZW_QTJC_01SerialOverTcp"
}
]
}
},
{
"Title": "LQTCP",
"Children": [
{
"Href": "/LQTCP",
"Title": "LQTCP"
}
]
},
{
"Title": "KELID2008",
"Children": [
{
"Href": "/KELID2008",
"Title": "KELID2008"
},
{
"Href": "/KELID2008OverTcp",
"Title": "KELID2008OverTcp"
}
]
},
]

View File

@@ -1,18 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'">
<DefineConstants>Pro</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'">
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' AND '$(Configuration)' == 'Debug'">
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor.cs" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor.cs" />
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor" />
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Melsec\ThingsGateway.Foundation.Adapter.Melsec.csproj" />
<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor.cs" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor.cs" />
<Content Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor" />
<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.AllenBradleyCip\ThingsGateway.Foundation.Adapter.AllenBradleyCip.csproj" />
@@ -46,25 +47,44 @@
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.HZW_QTJC_01\ThingsGateway.Foundation.Adapter.HZW_QTJC_01.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro' ">
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor.cs" Link="Pages\LQTCP\LQTCPDebugPage.razor.cs" />
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.LQTCP\Page\LQTCPDebugPage.razor" Link="Pages\LQTCP\LQTCPDebugPage.razor" />
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.LQTCP\ThingsGateway.Foundation.Adapter.LQTCP.csproj" />
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor.cs" Link="Pages\KELID2008\KELID2008DebugPage.razor.cs" />
<Compile Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor.cs" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor.cs" />
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008DebugPage.razor" Link="Pages\KELID2008\KELID2008DebugPage.razor" />
<Content Include="..\..\PluginProAF2021\ThingsGateway.Plugin.KELID2008\Page\KELID2008OverTcpDebugPage.razor" Link="Pages\KELID2008\KELID2008OverTcpDebugPage.razor" />
<ProjectReference Include="..\..\PluginProAF2021\ThingsGateway.Foundation.Adapter.KELID2008\ThingsGateway.Foundation.Adapter.KELID2008.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007DebugPage.razor.cs" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\MqttRpcNameVaueWithId.cs" Link="Pages\Mqtt\MqttRpcNameVaueWithId.cs" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor.cs" Link="Pages\Mqtt\MqttClientDebugPage.razor.cs" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\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.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" />
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor" Link="Pages\Mqtt\MqttClientPage.razor" />
<PackageReference Include="MQTTnet" Version="4.3.1.873" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.DLT645\Page\DLT645_2007DebugPage.razor.cs" Link="Pages\DLT645\DLT645_2007DebugPage.razor.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" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuDebugPage.razor.cs" />
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuDebugPage.razor" Link="Pages\Modbus\ModbusRtuDebugPage.razor" />
<Compile Include="..\..\Plugin\ThingsGateway.Plugin.Modbus\Page\ModbusRtuOverTcpDebugPage.razor.cs" Link="Pages\Modbus\ModbusRtuOverTcpDebugPage.razor.cs" />
@@ -115,7 +135,7 @@
</ItemGroup>
<ItemGroup >
<ItemGroup>
<!--<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" />
@@ -128,25 +148,12 @@
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />
</ItemGroup>
<ItemGroup >
<ItemGroup>
<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" />
<Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientPage.razor" Link="Pages\Mqtt\MqttClientPage.razor" />
<PackageReference Include="MQTTnet" Version="4.3.1.873" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,4 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -10,12 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Serial;
global using System;
/// <summary>
/// 串口基接口
/// </summary>
public interface ISerial : ISocket
{
global using System.Windows.Forms;
}

View File

@@ -0,0 +1,77 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.Drawing;
namespace ThingsGateway.Foundation.Demo.Winform
{
partial class MainFrom
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainFrom));
blazorWebView1 = new Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView();
SuspendLayout();
//
// blazorWebView1
//
blazorWebView1.Dock = DockStyle.Fill;
blazorWebView1.Location = new Point(0, 0);
blazorWebView1.Margin = new Padding(4);
blazorWebView1.Name = "blazorWebView1";
blazorWebView1.Size = new Size(1029, 529);
blazorWebView1.TabIndex = 0;
blazorWebView1.Text = "blazorWebView1";
//
// MainFrom
//
AutoScaleDimensions = new SizeF(9F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1029, 529);
Controls.Add(blazorWebView1);
Icon = (Icon)resources.GetObject("$this.Icon");
Margin = new Padding(4);
Name = "MainFrom";
Text = "Form1";
FormClosed += MainFrom_FormClosed;
ResumeLayout(false);
}
#endregion
private Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView blazorWebView1;
}
}

View File

@@ -0,0 +1,41 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Microsoft.AspNetCore.Components.WebView.WindowsForms;
using Microsoft.Extensions.DependencyInjection;
using ThingsGateway.Components;
namespace ThingsGateway.Foundation.Demo.Winform
{
public partial class MainFrom : Form
{
public MainFrom()
{
InitializeComponent();
var services = new ServiceCollection();
services.AddWindowsFormsBlazorWebView();
services.ThingsGatewayComponentsConfigureServices();
blazorWebView1.HostPage = "wwwroot/index.html";
blazorWebView1.Services = services.BuildServiceProvider();
this.Text = "ThingsGateway.Foundation.Demo";
blazorWebView1.RootComponents.Add<ThingsGateway.Foundation.Demo.App>("#app");
}
private void MainFrom_FormClosed(object sender, FormClosedEventArgs e)
{
Application.Exit();
}
}
}

View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgvCjzYkwo82JsKPNifCjzYqwo82IcKPNgLCjzYAAAAAAAAA
AAAAAAAAAAAAAMKPNgDCjzYBwo82HsKPNknCjzZewo82QcKPNhLCjzYAwo82AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82S8KPNtPCjzbiwo8258KPNuDCjzatwo82EsKP
NgAAAAAAAAAAAAAAAADCjzYAwo82BsKPNmvCjzbbwo826MKPNtvCjzbhwo82vcKPNmDCjzYywo82AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYPwo82O8KPNs7Cjzb/wo82iMKP
Nh7CjzYCwo82AAAAAAAAAAAAwo82AMKPNgDCjzZnwo8298KPNsLCjzY6wo82GsKPNjTCjzbJwo82/8KP
NpTCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYIwo82vsKP
Nv/CjzZowo82AAAAAAAAAAAAAAAAAAAAAADCjzYAwo82JMKPNtnCjzbxwo82QcKPNgDCjzYAwo82AMKP
NpHCjzb/wo82lsKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKP
NgjCjza9wo82/8KPNmjCjzYAAAAAAAAAAAAAAAAAwo82AMKPNgDCjzZ2wo82/8KPNrnCjzYKwo82AAAA
AADCjzYAwo82jcKPNv/CjzaWwo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADCjzYAwo82CMKPNr3Cjzb/wo82aMKPNgAAAAAAAAAAAAAAAADCjzYAwo82CcKPNrrCjzb/wo82fcKP
NgDCjzYAAAAAAMKPNgDCjzaLwo82/8KPNpbCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAMKPNgDCjzYIwo82vMKPNv/CjzZpwo82AAAAAAAAAAAAAAAAAMKPNgDCjzYfwo8238KP
Nv3CjzZRwo82AMKPNgDCjzYBwo82B8KPNpnCjzb/wo82psKPNgrCjzYAwo82AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgjCjza8wo82/8KPNmnCjzYAAAAAAAAAAAAAAAAAwo82AMKP
NjbCjzbxwo829sKPNj7CjzYAwo82AMKPNiPCjzaywo827cKPNv/Cjzbywo82qMKPNhPCjzYAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82CMKPNrvCjzb/wo82acKPNgAAAAAAAAAAAAAA
AADCjzYAwo82P8KPNvfCjzbzwo82OcKPNgDCjzYAwo82D8KPNlnCjzZiwo82X8KPNmDCjzZRwo82CcKP
NgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKPNgDCjzYHwo82usKPNv/CjzZpwo82AAAA
AAAAAAAAAAAAAMKPNgDCjzY+wo829sKPNvTCjzY8wo82AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgfCjza6wo82/8KP
NmnCjzYAAAAAAAAAAAAAAAAAwo82AMKPNirCjzbpwo82+MKPNkDCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82B8KP
NrnCjzb/wo82acKPNgAAAAAAAAAAAAAAAADCjzYAwo82FcKPNtLCjzb/wo82VsKPNgAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNgLCjzYTwo82BMKP
NgDCjzYHwo82t8KPNv/CjzZpwo82AMKPNgDCjzYMwo82E8KPNgDCjzYCwo82n8KPNv/CjzaEwo82AMKP
NgAAAAAAwo82AMKPNgDCjzZPwo82XcKPNgLCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82F8KP
NrTCjzY6wo82AMKPNgbCjza0wo82/8KPNmnCjzYAwo82AMKPNnPCjzaawo82A8KPNgDCjzZOwo82+MKP
NsbCjzYRwo82AAAAAADCjzYAwo82DcKPNsLCjzagwo82AMKPNgAAAAAAAAAAAAAAAAAAAAAAAAAAAMKP
NgDCjzYPwo82ysKPNpPCjzYBwo82BcKPNrHCjzb/wo82acKPNgDCjzYUwo82zMKPNpPCjzYAwo82AMKP
NgrCjzanwo82/MKPNmnCjzYAwo82AMKPNgDCjzZRwo8298KPNnbCjzYAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAwo82AMKPNgDCjzaawo827cKPNmHCjzYswo82vMKPNv/CjzaEwo82K8KPNoDCjzb5wo82ZMKP
NgAAAAAAwo82AMKPNi7CjzbWwo825sKPNlnCjzYdwo82SMKPNtTCjzb9wo82UsKPNgAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAwo82AMKPNmHCjzb3wo828cKPNt/Cjzbuwo8298KPNurCjzbjwo829MKP
NurCjzY6wo82AAAAAADCjzYAwo82AMKPNjfCjza8wo826cKPNtvCjzbewo82ycKPNs7CjzYvwo82AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCjzYAwo82EsKPNj3CjzZAwo82QcKPNkDCjzY/wo82QMKP
NkDCjzY/wo82OMKPNgrCjzYAAAAAAAAAAADCjzYAwo82AMKPNg/CjzY5wo82SsKPNjDCjzYOwo82G8KP
NgXCjzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////wH4H/8B8Af/AfAH/4f
hx/+H4cf/h8PH/4fDAf+HwwH/h8MB/4fD//+Hw///h8P/+IZD4/iGIcP4BGHH+ABwB/wAeAf8AHwH///
//////////////////////////////////8=
</value>
</data>
</root>

View File

@@ -0,0 +1,29 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Demo.Winform
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainFrom());
}
}
}

View File

@@ -0,0 +1,47 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<ApplicationIcon>favicon.ico</ApplicationIcon>
<TargetFrameworks>net7.0-windows</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<None Remove="favicon.ico" />
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.WindowsForms" Version="7.0.96" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ThingsGateway.Foundation.Demo.Rcl\ThingsGateway.Foundation.Demo.Rcl.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\favicon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\favicon.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\index.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<title>ThingsGateway.Foundation.Demo</title>
<base href="/" />
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link href="_content/Masa.Blazor/css/masa-blazor.min.css" rel="stylesheet" />
<link href="_content/ThingsGateway.Components/css/materialdesign/v7.1.96/css/materialdesignicons.min.css" rel="stylesheet">
<link href="_content/ThingsGateway.Components/css/material/icons.css" rel="stylesheet">
<link href="_content/ThingsGateway.Components/css/fontawesome/v6.4.0/css/all.min.css" rel="stylesheet">
<link href="_content/ThingsGateway.Components/style/custom.css" rel="stylesheet">
<link href="_content/ThingsGateway.Components/prism/prism-material-dark-for-masa.css" rel="stylesheet">
<link href="_content/ThingsGateway.Components/prism/prism-line-highlight.min.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<div id="blazor-error-ui">
<span>
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
</span>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_framework/blazor.webview.js" autostart="true"></script>
<script src="_content/ThingsGateway.Components/prism/prism.min.js"></script>
<script src="_content/BlazorComponent/js/blazor-component.js"></script>
</body>
</html>

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.0.0.23</Version>
<Version>3.0.1.0</Version>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<LangVersion>latest</LangVersion>
<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks>

View File

@@ -35,12 +35,7 @@ public class DataInfo
}
internal static class DLT645Helper
{
internal static byte[] BytesAdd(this byte[] bytes, int value)
{
for (int index = 0; index < bytes.Length; ++index)
bytes[index] = (byte)(bytes[index] + value);
return bytes;
}
internal static string Get2007ErrorMessage(byte buffer)
{

View File

@@ -186,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
var item = commandResult.Content;
if (FrameTime != 0)
Thread.Sleep(FrameTime);
var WaitingClientEx = client.CreateWaitingClient(new() { });
var WaitingClientEx = client.CreateWaitingClient(new() { });
var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken);
return (MessageBase)result.RequestInfo;
}
@@ -213,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase
var item = commandResult.Content;
await Task.Delay(FrameTime, cancellationToken);
var WaitingClientEx = client.CreateWaitingClient(new() { });
var WaitingClientEx = client.CreateWaitingClient(new() { });
var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken);
return (MessageBase)result.RequestInfo;
}

View File

@@ -1,5 +1,4 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -9,7 +8,6 @@
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Newtonsoft.Json.Linq;
@@ -49,7 +47,7 @@ public class OPCUAClient : IDisposable
/// <summary>
/// 当前保存的变量名称列表
/// </summary>
public List<string> Variables = new();
public List<List<string>> Variables = new();
/// <summary>
/// 当前的变量名称/OPC变量节点
@@ -518,9 +516,9 @@ public class OPCUAClient : IDisposable
/// <summary>
/// 连接到服务器
/// </summary>
public async Task ConnectAsync()
public async Task ConnectAsync(CancellationToken cancellationToken)
{
await ConnectAsync(OPCNode.OPCUrl);
await ConnectAsync(OPCNode.OPCUrl, cancellationToken);
}
/// <summary>
@@ -540,7 +538,7 @@ public class OPCUAClient : IDisposable
/// Creates a new session.
/// </summary>
/// <returns>The new session object.</returns>
private async Task<ISession> ConnectAsync(string serverUrl)
private async Task<ISession> ConnectAsync(string serverUrl, CancellationToken cancellationToken)
{
PrivateDisconnect();
@@ -549,6 +547,7 @@ public class OPCUAClient : IDisposable
throw new ArgumentNullException("未初始化配置");
}
var useSecurity = OPCNode?.IsUseSecurity ?? true;
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, useSecurity, 10000);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
@@ -571,7 +570,8 @@ public class OPCUAClient : IDisposable
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
60000,
userIdentity,
Array.Empty<string>());
Array.Empty<string>(), cancellationToken
).ConfigureAwait(false);
typeSystem = new ComplexTypeSystem(m_session);
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
@@ -584,7 +584,12 @@ public class OPCUAClient : IDisposable
//如果是订阅模式,连接时添加订阅组
if (OPCNode.ActiveSubscribe)
await AddSubscriptionAsync(Guid.NewGuid().ToString(), Variables.ToArray(), OPCNode.LoadType);
{
foreach (var item in Variables)
{
await AddSubscriptionAsync(Guid.NewGuid().ToString(), item.ToArray(), OPCNode.LoadType);
}
}
return m_session;
}
@@ -741,7 +746,7 @@ public class OPCUAClient : IDisposable
NodeId nodeToRead = new(nodeIdStr);
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, NodeClass.Variable, false, cancellationToken);
if (OPCNode.LoadType)
await typeSystem.LoadType(node.DataType);
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
_variableDicts.AddOrUpdate(nodeIdStr, node);
return node;
}
@@ -781,7 +786,7 @@ public class OPCUAClient : IDisposable
if (StatusCode.IsGood(nodes.Item2[i].StatusCode))
{
var node = ((VariableNode)nodes.Item1[i]);
await typeSystem.LoadType(node.DataType);
await typeSystem.LoadType(node.DataType).ConfigureAwait(false);
_variableDicts.AddOrUpdate(nodeIdStrs[i], node);
}
else

View File

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

View File

@@ -7,8 +7,8 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.56" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.76" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.76" />
</ItemGroup>
</Project>

View File

@@ -36,11 +36,42 @@ internal partial class SiemensHelper
// return OperResult.CreateSuccessResult<byte[]>(numArray);
//}
internal static OperResult<byte[]> AnalysisReadByte(byte[] sends, byte[] content)
internal static OperResult<byte[], FilterResult> AnalysisReadByte(byte[] sends, byte[] content)
{
int length = 0;
int itemLen = (sends.Length - 19) / 12;
//添加错误代码校验
if (content[17] + content[18] > 0)
{
return new($"PLC返回错误错误类型{content[17].ToString("X2")}错误代码:{content[18].ToString("X2")}")
{
Content2 = FilterResult.Success
};
}
if (content.Length < 21)
{
return new($"长度不足")
{
Content2 = FilterResult.Cache
};
}
if (content.Length < 25 + content[20])
{
return new($"长度不足")
{
Content2 = FilterResult.Cache
};
}
//添加返回代码校验
if (content[21] != 0xff)
{
return new($"PLC返回错误返回代码{content[21].ToString("X2")}")
{
Content2 = FilterResult.Success
};
}
for (int index = 0; index < itemLen; index++)
{
if (sends[22 + (index * 12)] >= (byte)S7WordLength.Word)
@@ -53,9 +84,9 @@ internal partial class SiemensHelper
}
}
if (content.Length < 21 || content[20] != itemLen)
if (content[20] != itemLen)
{
return new OperResult<byte[]>("数据块长度校验失败");
return new("数据块长度校验失败");
}
byte[] dataArray = new byte[length];
@@ -105,29 +136,39 @@ internal partial class SiemensHelper
}
else
{
return new OperResult<byte[]>((int)content[index2] + GetCpuError(content[index2]));
return new((int)content[index2] + GetCpuError(content[index2]))
{
Content2 = FilterResult.Success
};
}
}
}
return OperResult.CreateSuccessResult(dataArray);
return OperResult.CreateSuccessResult(dataArray, FilterResult.Success);
}
internal static OperResult<byte[]> AnalysisWrite(byte[] content)
internal static OperResult<byte[], FilterResult> AnalysisWrite(byte[] content)
{
if (content.Length < 22)
{
return new OperResult<byte[]>() { Message = "未知错误" };
return new()
{
Message = "长度不足",
Content2 = FilterResult.Success
};
}
byte err = content[21];
if (err != byte.MaxValue)
{
return new OperResult<byte[]>((int)content[21] + GetCpuError(content[21]));
return new($"错误代码:{(int)content[21]}描述:{GetCpuError(content[21])}")
{
Content2 = FilterResult.Success
};
}
else
{
return OperResult.CreateSuccessResult(content);
return OperResult.CreateSuccessResult(content, FilterResult.Success);
}
}

View File

@@ -123,34 +123,7 @@ namespace ThingsGateway.Foundation.Adapter.Siemens
#region
/// <summary>
/// 远程TSAP,需重新连接
/// </summary>
public int DestTSAP
{
get
{
return
_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart ?
(ISO_CR[17] * 256) + ISO_CR[18] :
(ISO_CR[20] * 256) + ISO_CR[21];
}
set
{
if (_currentPlc == SiemensEnum.S200 || _currentPlc == SiemensEnum.S200Smart)
{
ISO_CR[17] = BitConverter.GetBytes(value)[1];
ISO_CR[18] = BitConverter.GetBytes(value)[0];
}
else
{
ISO_CR[20] = BitConverter.GetBytes(value)[1];
ISO_CR[21] = BitConverter.GetBytes(value)[0];
}
}
}
/// <summary>
/// 本地TSAP需重新连接
/// 本地TSAP
/// </summary>
public int LocalTSAP
{

View File

@@ -35,10 +35,10 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
/// <inheritdoc/>
protected override FilterResult UnpackResponse(SiemensMessage request, byte[] send, byte[] body, byte[] response)
{
var result = new OperResult<byte[]>();
var result = new OperResult<byte[], FilterResult>();
if (response[2] * 256 + response[3] == 7)
{
result = new OperResult<byte[]>() { Content = response };
result = new() { Content = response, Content2 = FilterResult.Success };
}
else
{
@@ -56,6 +56,6 @@ public class SiemensS7PLCDataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapte
request.ErrorCode = result.ErrorCode;
request.Message = result.Message;
request.Content = result.Content;
return FilterResult.Success;
return result.Content2;
}
}

View File

@@ -0,0 +1,15 @@
0x00 Reserved 未定义,预留
0x01 Hardware error 硬件错误
0x03 Accessing the object not allowed 对象不允许访问
0x05 Invalid address 无效地址所需的地址超出此PLC的极限
0x06 Data type not supported 数据类型不支持
0x07 Data type inconsistent 日期类型不一致
0x0a Object does not exist 对象不存在
0xff Success 成功

View File

@@ -0,0 +1,825 @@
附录一:错误码具体含义
0x0000
没有错误
0x0110
块号无效
0x0111
请求长度无效
0x0112
参数无效
0x0113
块类型无效
0x0114
找不到块
0x0115
块已存在
0x0116
块被写保护
0x0117
块/操作系统更新太大
0x0118
块号无效
0x0119
输入的密码不正确
0x011A
PG资源错误
0x011B
PLC资源错误
0x011C
协议错误
0x011D
块太多(与模块相关的限制)
0x011E
不再与数据库建立连接或者S7DOS句柄无效
0x011F
结果缓冲区太小
0x0120
块结束列表
0x0140
可用内存不足
0x0141
由于缺少资源,无法处理作业
0x8001
当块处于当前状态时,无法执行请求的服务
0x8003
S7协议错误传输块时发生错误
0x8100
应用程序,一般错误:远程模块未知的服务
0x8104
未在模块上实现此服务或报告了帧错误
0x8204
对象的类型规范不一致
0x8205
复制的块已存在且未链接
0x8301
模块上的内存空间或工作内存不足,或者指定的存储介质不可访问
0x8302
可用资源太少或处理器资源不可用
0x8304
无法进一步并行上传。存在资源瓶颈
0x8305
功能不可用
0x8306
工作内存不足用于复制链接加载AWP
0x8307
保持性工作记忆不够用于复制链接加载AWP
0x8401
S7协议错误无效的服务序列例如加载或上载块
0x8402
由于寻址对象的状态,服务无法执行
0x8404
S7协议无法执行该功能
0x8405
远程块处于DISABLE状态CFB。该功能无法执行
0x8500
S7协议错误帧错误
0x8503
来自模块的警报:服务过早取消
0x8701
寻址通信伙伴上的对象时出错(例如,区域长度错误)
0x8702
模块不支持所请求的服务
0x8703
拒绝访问对象
0x8704
访问错误:对象已损坏
0xD001
协议错误:非法的作业号
0xD002
参数错误:非法的作业变体
0xD003
参数错误:模块不支持调试功能
0xD004
参数错误:作业状态非法
0xD005
参数错误:作业终止非法
0xD006
参数错误非法链路断开ID
0xD007
参数错误:缓冲区元素数量非法
0xD008
参数错误:扫描速率非法
0xD009
参数错误:执行次数非法
0xD00A
参数错误:非法触发事件
0xD00B
参数错误:非法触发条件
0xD011
调用环境路径中的参数错误:块不存在
0xD012
参数错误:块中的地址错误
0xD014
参数错误:正在删除/覆盖块
0xD015
参数错误:标签地址非法
0xD016
参数错误:由于用户程序错误,无法测试作业
0xD017
参数错误:非法触发号
0xD025
参数错误:路径无效
0xD026
参数错误:非法访问类型
0xD027
参数错误:不允许此数据块数
0xD031
内部协议错误
0xD032
参数错误:结果缓冲区长度错误
0xD033
协议错误:作业长度错误
0xD03F
编码错误参数部分出错例如保留字节不等于0
0xD041
数据错误非法状态列表ID
0xD042
数据错误:标签地址非法
0xD043
数据错误:找不到引用的作业,检查作业数据
0xD044
数据错误:标签值非法,检查作业数据
0xD045
数据错误HOLD中不允许退出ODIS控制
0xD046
数据错误:运行时测量期间非法测量阶段
0xD047
数据错误:“读取作业列表”中的非法层次结构
0xD048
数据错误“删除作业”中的非法删除ID
0xD049
“替换作业”中的替换ID无效
0xD04A
执行'程序状态'时出错
0xD05F
编码错误数据部分出错例如保留字节不等于0...
0xD061
资源错误:没有作业的内存空间
0xD062
资源错误:作业列表已满
0xD063
资源错误:触发事件占用
0xD064
资源错误:没有足够的内存空间用于一个结果缓冲区元素
0xD065
资源错误:没有足够的内存空间用于多个结果缓冲区元素
0xD066
资源错误:可用于运行时测量的计时器被另一个作业占用
0xD067
资源错误:“修改标记”作业过多(特别是多处理器操作)
0xD081
当前模式下不允许使用的功能
0xD082
模式错误无法退出HOLD模式
0xD0A1
当前保护级别不允许使用的功能
0xD0A2
目前无法运行,因为正在运行的函数会修改内存
0xD0A3
I / O上活动的“修改标记”作业太多特别是多处理器操作
0xD0A4
'强制'已经建立
0xD0A5
找不到引用的作业
0xD0A6
无法禁用/启用作业
0xD0A7
无法删除作业,例如因为当前正在读取作业
0xD0A8
无法替换作业,例如因为当前正在读取或删除作业
0xD0A9
无法读取作业,例如因为当前正在删除作业
0xD0AA
处理操作超出时间限制
0xD0AB
进程操作中的作业参数无效
0xD0AC
进程操作中的作业数据无效
0xD0AD
已设置操作模式
0xD0AE
作业是通过不同的连接设置的,只能通过此连接进行处理
0xD0C1
访问标签时至少检测到一个错误
0xD0C2
切换到STOP / HOLD模式
0xD0C3
访问标记时至少检测到一个错误。模式更改为STOP / HOLD
0xD0C4
运行时测量期间超时
0xD0C5
块堆栈的显示不一致,因为块被删除/重新加载
0xD0C6
作业已被删除,因为它所引用的作业已被删除
0xD0C7
由于退出了STOP模式因此作业被自动删除
0xD0C8
由于测试作业和正在运行的程序之间不一致,“块状态”中止
0xD0C9
通过复位OB90退出状态区域
0xD0CA
通过在退出前重置OB90并访问错误读取标签退出状态范围
0xD0CB
外设输出的输出禁用再次激活
0xD0CC
调试功能的数据量受时间限制
0xD201
块名称中的语法错误
0xD202
函数参数中的语法错误
0xD205
RAM中已存在链接块无法进行条件复制
0xD206
EPROM中已存在链接块无法进行条件复制
0xD208
超出模块的最大复制(未链接)块数
0xD209
(至少)模块上找不到给定块之一
0xD20A
超出了可以与一个作业链接的最大块数
0xD20B
超出了一个作业可以删除的最大块数
0xD20C
OB无法复制因为关联的优先级不存在
0xD20D
SDB无法解释例如未知数
0xD20E
没有(进一步)阻止可用
0xD20F
超出模块特定的最大块大小
0xD210
块号无效
0xD212
标头属性不正确(与运行时相关)
0xD213
SDB太多。请注意对正在使用的模块的限制
0xD216
无效的用户程序 - 重置模块
0xD217
不允许在模块属性中指定的保护级别
0xD218
属性不正确(主动/被动)
0xD219
块长度不正确(例如,第一部分或整个块的长度不正确)
0xD21A
本地数据长度不正确或写保护错误
0xD21B
模块无法压缩或压缩早期中断
0xD21D
传输的动态项目数据量是非法的
0xD21E
无法为模块例如FMCP分配参数。系统数据无法链接
0xD220
编程语言无效。请注意对正在使用的模块的限制
0xD221
连接或路由的系统数据无效
0xD222
全局数据定义的系统数据包含无效参数
0xD223
通信功能块的实例数据块错误或超出最大背景数据块数
0xD224
SCAN系统数据块包含无效参数
0xD225
DP系统数据块包含无效参数
0xD226
块中发生结构错误
0xD230
块中发生结构错误
0xD231
至少有一个已加载的OB无法复制因为关联的优先级不存在
0xD232
加载块的至少一个块编号是非法的
0xD234
块在指定的内存介质或作业中存在两次
0xD235
该块包含不正确的校验和
0xD236
该块不包含校验和
0xD237
您将要加载块两次即CPU上已存在具有相同时间戳的块
0xD238
指定的块中至少有一个不是DB
0xD239
至少有一个指定的DB在装载存储器中不可用作链接变量
0xD23A
至少有一个指定的DB与复制和链接的变体有很大不同
0xD240
违反了协调规则
0xD241
当前保护级别不允许该功能
0xD242
处理F块时的保护冲突
0xD250
更新和模块ID或版本不匹配
0xD251
操作系统组件序列不正确
0xD252
校验和错误
0xD253
没有可用的可执行加载程序; 只能使用存储卡进行更新
0xD254
操作系统中的存储错误
0xD280
在S7-300 CPU中编译块时出错
0xD2A1
块上的另一个块功能或触发器处于活动状态
0xD2A2
块上的触发器处于活动状态。首先完成调试功能
0xD2A3
块未激活(链接),块被占用或块当前被标记为删除
0xD2A4
该块已被另一个块函数处理
0xD2A6
无法同时保存和更改用户程序
0xD2A7
块具有“未链接”属性或未处理
0xD2A8
激活的调试功能阻止将参数分配给CPU
0xD2A9
正在为CPU分配新参数
0xD2AA
当前正在为模块分配新参数
0xD2AB
当前正在更改动态配置限制
0xD2AC
正在运行的激活或取消激活分配SFC 12暂时阻止R-KiR过程
0xD2B0
在RUNCiR中配置时发生错误
0xD2C0
已超出最大工艺对象数
0xD2C1
模块上已存在相同的技术数据块
0xD2C2
无法下载用户程序或下载硬件配置
0xD401
信息功能不可用
0xD402
信息功能不可用
0xD403
服务已登录/注销(诊断/ PMC
0xD404
达到的最大节点数。不再需要登录诊断/ PMC
0xD405
不支持服务或函数参数中的语法错误
0xD406
当前不可用的必需信息
0xD407
发生诊断错误
0xD408
更新已中止
0xD409
DP总线错误
0xD601
函数参数中的语法错误
0xD602
输入的密码不正确
0xD603
连接已合法化
0xD604
已启用连接
0xD605
由于密码不存在,因此无法进行合法化
0xD801
至少有一个标记地址无效
0xD802
指定的作业不存在
0xD803
非法的工作状态
0xD804
非法循环时间(非法时基或多个)
0xD805
不能再设置循环读取作业
0xD806
引用的作业处于无法执行请求的功能的状态
0xD807
功能因过载而中止,这意味着执行读取周期所需的时间比设置的扫描周期时间长
0xDC01
日期和/或时间无效
0xE201
CPU已经是主设备
0xE202
由于闪存模块中的用户程序不同,无法进行连接和更新
0xE203
由于固件不同,无法连接和更新
0xE204
由于内存配置不同,无法连接和更新
0xE205
由于同步错误导致连接/更新中止
0xE206
由于协调违规而拒绝连接/更新
0xEF01
S7协议错误ID2错误; 工作中只允许00H
0xEF02
S7协议错误ID2错误; 资源集不存在

View File

@@ -207,7 +207,7 @@ public interface IReadWrite : IDisposable
/// <summary>
/// 读写超时时间
/// </summary>
ushort TimeOut { get; set; }
int TimeOut { get; set; }
/// <summary>
/// 一个寄存器所占的字节长度

View File

@@ -54,7 +54,7 @@ public abstract class ReadWriteDevicesBase : IReadWrite
/// <inheritdoc/>
[Description("读写超时时间")]
public ushort TimeOut { get; set; } = 3000;
public int TimeOut { get; set; } = 3000;
/// <inheritdoc/>
public bool CascadeDisposal { get; set; } = true;

View File

@@ -55,7 +55,8 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken cancellationToken)
{
return Task.Run(() => TcpService.Start());
Connect(cancellationToken);
return EasyTask.CompletedTask;
}
/// <inheritdoc/>

View File

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

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using System.Text;
using ThingsGateway.Foundation.Extension.Generic;
namespace ThingsGateway.Foundation.Core;
@@ -19,6 +21,10 @@ namespace ThingsGateway.Foundation.Core;
/// </summary>
public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDataHandlingAdapter<TRequest> where TRequest : class, IMessage
{
/// <summary>
/// 报文输出时采用字符串还是HexString
/// </summary>
public virtual bool IsHexData { get; set; } = true;
/// <inheritdoc cref="ReadWriteDevicesTcpDataHandleAdapter{TRequest}"/>
public ReadWriteDevicesTcpDataHandleAdapter()
{
@@ -46,7 +52,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
{
//获取全部内容
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
//缓存/不缓存解析一样因为游标已经归0
{
request = Request;
@@ -131,7 +137,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
/// <summary>
/// 发送方法,会重新建立<see cref="Request"/>
/// </summary>
protected void GoSend(byte[] item)
protected virtual void GoSend(byte[] item)
{
byte[] bytes;
if (IsSendPackCommand)
@@ -141,12 +147,12 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
Request = GetInstance();
Request.SendBytes = bytes;
GoSend(bytes, 0, bytes.Length);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
}
/// <summary>
/// 发送方法,会重新建立<see cref="Request"/>
/// </summary>
protected async Task GoSendAsync(byte[] item)
protected virtual async Task GoSendAsync(byte[] item)
{
byte[] bytes;
if (IsSendPackCommand)
@@ -156,7 +162,7 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
Request = GetInstance();
Request.SendBytes = bytes;
await GoSendAsync(bytes, 0, bytes.Length);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
}
/// <inheritdoc/>
@@ -180,6 +186,13 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
/// <inheritdoc/>
public override string ToString()
{
return Owner.ToString();
if (Owner is SocketClient client)
{
return client.GetIPPort();
}
else
{
return Owner.ToString();
}
}
}

View File

@@ -11,6 +11,7 @@
#endregion
using System.Net;
using System.Text;
using ThingsGateway.Foundation.Extension.Generic;
@@ -21,6 +22,13 @@ namespace ThingsGateway.Foundation.Core;
/// </summary>
public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHandlingAdapter where TRequest : class, IMessage
{
/// <summary>
/// 报文输出时采用字符串还是HexString
/// </summary>
public virtual bool IsHexData { get; set; } = true;
/// <inheritdoc cref="ReadWriteDevicesUdpDataHandleAdapter{TRequest}"/>
public ReadWriteDevicesUdpDataHandleAdapter()
{
@@ -68,13 +76,13 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa
Request = GetInstance();
Request.SendBytes = bytes;
GoSend(endPoint, bytes, 0, bytes.Length);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}");
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{(IsHexData ? Request.SendBytes.ToHexString(' ') : Encoding.UTF8.GetString(Request.SendBytes))}");
}
/// <inheritdoc/>
protected override void PreviewReceived(EndPoint remoteEndPoint, ByteBlock byteBlock)
{
var allBytes = byteBlock.ToArray(0, byteBlock.Len);
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{allBytes.ToHexString(' ')}");
Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 接收:{(IsHexData ? allBytes.ToHexString(' ') : Encoding.UTF8.GetString(allBytes))}");
if (Request?.SendBytes == null)
{

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using System.Text;
using ThingsGateway.Foundation.Extension.Generic;
namespace ThingsGateway.Foundation.Core;
@@ -17,6 +19,39 @@ namespace ThingsGateway.Foundation.Core;
/// <inheritdoc/>
public static class ByteExtensions
{
/// <summary>
/// 获取异或校验
/// </summary>
/// <param name="data"></param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static byte[] GetAsciiXOR(this byte[] data, int left, int right)
{
int tmp = data[left];
for (int i = left + 1; i < data.Length - right; i++)
{
tmp = (tmp ^ data[i]);
}
byte[] fcs = new byte[2];
fcs[0] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[0];
fcs[1] = Encoding.ASCII.GetBytes(((byte)tmp).ToString("X2"))[1];
return fcs;
}
/// <summary>
/// 数组内容分别相加某个数字
/// </summary>
/// <param name="bytes"></param>
/// <param name="value"></param>
/// <returns></returns>
public static byte[] BytesAdd(this byte[] bytes, int value)
{
for (int index = 0; index < bytes.Length; ++index)
bytes[index] = (byte)(bytes[index] + value);
return bytes;
}
/// <summary>
/// 获取byte数据类型的第offset位是否为True<br />
/// </summary>

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

@@ -72,4 +72,28 @@ namespace ThingsGateway.Foundation.Core
GC.SuppressFinalize(this);
}
}
#if NET6_0_OR_GREATER
public partial class DisposableObject : IAsyncDisposable
{
/// <summary>
/// 异步释放资源。内部已经处理了<see cref="GC.SuppressFinalize(object)"/>
/// </summary>
/// <returns></returns>
public async ValueTask DisposeAsync()
{
await DisposeAsyncCore().ConfigureAwait(false);
Dispose(disposing: false);
GC.SuppressFinalize(this);
}
/// <summary>
/// 异步释放资源。注意:此方法仅在调用<see cref="IAsyncDisposable.DisposeAsync"/>时有效。
/// </summary>
/// <returns></returns>
protected virtual ValueTask DisposeAsyncCore()
{
return ValueTask.CompletedTask;
}
}
#endif
}

View File

@@ -0,0 +1,47 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// ConfigEventArgs
/// </summary>
public class ConfigEventArgs : PluginEventArgs
{
/// <summary>
/// ConfigEventArgs
/// </summary>
/// <param name="config"></param>
public ConfigEventArgs(TouchSocketConfig config)
{
this.Config = config;
}
/// <summary>
/// 具体配置
/// </summary>
public TouchSocketConfig Config { get; }
}
}

View File

@@ -1,4 +1,4 @@
#region copyright
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -10,24 +10,17 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 通讯基类
/// </summary>
public abstract class BaseSerial : DependencyObject, ISerial
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 同步根。
/// 具有配置设置的对象
/// </summary>
protected readonly object SyncRoot = new object();
public abstract class ConfigObject : DependencyObject, IConfigObject
{
/// <inheritdoc/>
public abstract TouchSocketConfig Config { get; }
/// <inheritdoc/>
public abstract int SendBufferSize { get; }
/// <inheritdoc/>
public abstract int ReceiveBufferSize { get; }
/// <inheritdoc/>
public ILog Logger { get; set; }
/// <inheritdoc/>
public ILog Logger { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 具有配置的对象接口
/// </summary>
public interface IConfigObject : IDependencyObject, ILoggerObject
{
/// <summary>
/// 设置项
/// </summary>
TouchSocketConfig Config { get; }
}
}

View File

@@ -0,0 +1,48 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 当配置Config完成时触发。
/// </summary>
public interface ILoadedConfigPlugin<in TSender> : IPlugin where TSender : IConfigObject
{
/// <summary>
/// 当完成配置载入时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <returns></returns>
Task OnLoadedConfig(TSender sender, ConfigEventArgs e);
}
/// <summary>
/// 当配置Config完成时触发。
/// </summary>
public interface ILoadedConfigPlugin : ILoadedConfigPlugin<IConfigObject>
{
}
}

View File

@@ -0,0 +1,34 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 当正在配置Config时触发。
/// </summary>
public interface ILoadingConfigPlugin<in TSender> : IPlugin where TSender : IConfigObject
{
/// <summary>
/// 当载入配置时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
Task OnLoadingConfig(TSender sender, ConfigEventArgs e);
}
/// <summary>
/// ILoadingConfigPlugin
/// </summary>
public interface ILoadingConfigPlugin : ILoadingConfigPlugin<IConfigObject>
{
}
}

View File

@@ -0,0 +1,27 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 具有设置配置的对象接口
/// </summary>
public interface ISetupConfigObject : IConfigObject, IPluginObject
{
/// <summary>
/// 配置设置项
/// </summary>
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
void Setup(TouchSocketConfig config);
}
}

View File

@@ -0,0 +1,102 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 具有设置配置的对象
/// </summary>
public abstract class SetupConfigObject : ConfigObject, ISetupConfigObject
{
private TouchSocketConfig m_config;
/// <inheritdoc/>
public override TouchSocketConfig Config => this.m_config;
/// <inheritdoc/>
public IContainer Container { get; private set; }
/// <inheritdoc/>
public IPluginsManager PluginsManager { get; private set; }
/// <inheritdoc/>
public void Setup(TouchSocketConfig config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
this.ThrowIfDisposed();
this.BuildConfig(config);
this.PluginsManager?.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
this.LoadConfig(this.Config);
this.PluginsManager?.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
}
/// <summary>
/// 加载配置
/// </summary>
/// <param name="config"></param>
protected virtual void LoadConfig(TouchSocketConfig config)
{
}
private void BuildConfig(TouchSocketConfig config)
{
this.m_config = config;
if (!config.TryGetValue(TouchSocketCoreConfigExtension.ContainerProperty, out var container))
{
container = new Container();
}
if (!container.IsRegistered(typeof(ILog)))
{
container.RegisterSingleton<ILog, LoggerGroup>();
}
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
{
pluginsManager = new PluginsManager(container);
}
if (container.IsRegistered(typeof(IPluginsManager)))
{
pluginsManager = container.Resolve<IPluginsManager>();
}
else
{
container.RegisterSingleton<IPluginsManager>(pluginsManager);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
{
actionContainer.Invoke(container);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
{
pluginsManager.Enable = true;
actionPluginsManager.Invoke(pluginsManager);
}
this.Logger ??= container.Resolve<ILog>();
this.Container = container;
this.PluginsManager = pluginsManager;
}
}
}

View File

@@ -28,8 +28,22 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 配置文件基类
/// </summary>
public class TouchSocketConfig : DependencyObject
public class TouchSocketConfig : DependencyObject, ICloneable
{
/// <summary>
/// 克隆配置依赖项,并返回一个新的克隆对象。
/// </summary>
/// <returns></returns>
public TouchSocketConfig Clone()
{
var config = new TouchSocketConfig();
this.CloneTo(config, true);
return config;
}
object ICloneable.Clone()
{
return this.Clone();
}
}
}

View File

@@ -28,17 +28,17 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 单线程流式适配器配置
/// </summary>
public class SingleStreamAdapterOption
public class AdapterOption
{
/// <summary>
/// 适配器数据包缓存启用。默认为缺省null如果有正常值会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeout"/>
/// </summary>
public bool? CacheTimeoutEnable { get; set; } = true;
public bool? CacheTimeoutEnable { get; set; }
/// <summary>
/// 适配器数据包缓存时长。默认为缺省null。当该值有效时会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeout"/>
/// </summary>
public int? CacheTimeout { get; set; }
public TimeSpan? CacheTimeout { get; set; }
/// <summary>
/// 适配器数据包最大值。默认缺省null当该值有效时会在设置适配器时直接作用于<see cref="DataHandlingAdapter.MaxPackageSize"/>

View File

@@ -103,12 +103,12 @@ namespace ThingsGateway.Foundation.Core
{
return FilterResult.Cache;
}
if (!requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos, this.StartCode.Length)))
if (!requestInfo.OnParsingStartCode(byteBlock.ToArray(byteBlock.Pos + indexStart + 1 - this.StartCode.Length, this.StartCode.Length)))
{
byteBlock.Pos += this.StartCode.Length;
byteBlock.Pos += indexStart;
return FilterResult.GoOn;
}
byteBlock.Pos += this.StartCode.Length;
byteBlock.Pos += indexStart + 1;
request = requestInfo;
int len;

View File

@@ -26,92 +26,62 @@ namespace ThingsGateway.Foundation.Core
/// <param name="config"></param>
public static void Config(this SingleStreamDataHandlingAdapter adapter, TouchSocketConfig config)
{
if (config.GetValue(DataHandlingAdapterExtension.MaxPackageSizeProperty) is int v1)
var option = config.GetValue(AdapterOptionProperty) ?? throw new ArgumentNullException(nameof(AdapterOptionProperty));
if (option.MaxPackageSize.HasValue)
{
adapter.MaxPackageSize = v1;
adapter.MaxPackageSize = option.MaxPackageSize.Value;
}
if (config.GetValue(DataHandlingAdapterExtension.CacheTimeoutProperty) != TimeSpan.Zero)
if (option.CacheTimeout.HasValue)
{
adapter.CacheTimeout = config.GetValue(DataHandlingAdapterExtension.CacheTimeoutProperty);
adapter.CacheTimeout = option.CacheTimeout.Value;
}
if (config.GetValue(DataHandlingAdapterExtension.CacheTimeoutEnableProperty) is bool v2)
if (option.CacheTimeoutEnable.HasValue)
{
adapter.CacheTimeoutEnable = v2;
adapter.CacheTimeoutEnable = option.CacheTimeoutEnable.Value;
}
if (config.GetValue(DataHandlingAdapterExtension.UpdateCacheTimeWhenRevProperty) is bool v3)
if (option.UpdateCacheTimeWhenRev.HasValue)
{
adapter.UpdateCacheTimeWhenRev = v3;
adapter.UpdateCacheTimeWhenRev = option.UpdateCacheTimeWhenRev.Value;
}
}
/// <summary>
/// 将<see cref="TouchSocketConfig"/>中的配置,装载在<see cref="SingleStreamDataHandlingAdapter"/>上。
/// </summary>
/// <param name="adapter"></param>
/// <param name="config"></param>
public static void Config(this DataHandlingAdapter adapter, TouchSocketConfig config)
{
var option = config.GetValue(AdapterOptionProperty) ?? throw new ArgumentNullException(nameof(AdapterOptionProperty));
if (option.MaxPackageSize.HasValue)
{
adapter.MaxPackageSize = option.MaxPackageSize.Value;
}
}
#endregion
#region
/// <summary>
/// 适配器数据包缓存启用。默认为缺省null如果有正常值会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeout"/>
/// 设置适配器相关的配置
/// </summary>
public static readonly DependencyProperty<bool?> CacheTimeoutEnableProperty = DependencyProperty<bool?>.Register("CacheTimeoutEnable", null);
public static readonly DependencyProperty<AdapterOption> AdapterOptionProperty = DependencyProperty<AdapterOption>.Register("AdapterOption", new AdapterOption());
/// <summary>
/// 适配器数据包缓存时长。默认为缺省(<see cref="TimeSpan.Zero"/>)。当该值有效时会在设置适配器时,直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeout"/>
/// </summary>
public static readonly DependencyProperty<TimeSpan> CacheTimeoutProperty = DependencyProperty<TimeSpan>.Register("CacheTimeout", TimeSpan.Zero);
/// <summary>
/// 适配器数据包最大值。默认缺省null当该值有效时会在设置适配器时直接作用于<see cref="DataHandlingAdapter.MaxPackageSize"/>
/// </summary>
public static readonly DependencyProperty<int?> MaxPackageSizeProperty = DependencyProperty<int?>.Register("MaxPackageSize", null);
/// <summary>
/// 适配器数据包缓存策略。默认缺省null当该值有效时会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.UpdateCacheTimeWhenRev"/>
/// </summary>
public static readonly DependencyProperty<bool?> UpdateCacheTimeWhenRevProperty = DependencyProperty<bool?>.Register("UpdateCacheTimeWhenRev", null);
/// <summary>
/// 适配器数据包缓存时长。默认为缺省(<see cref="TimeSpan.Zero"/>)。当该值有效时会在设置适配器时,直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeout"/>
/// 设置适配器相关的配置
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetCacheTimeout(this TouchSocketConfig config, TimeSpan value)
public static TouchSocketConfig SetAdapterOption(this TouchSocketConfig config, AdapterOption value)
{
config.SetValue(CacheTimeoutProperty, value);
return config;
}
/// <summary>
/// 适配器数据包缓存启用。默认为缺省null如果有正常值会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.CacheTimeoutEnable"/>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetCacheTimeoutEnable(this TouchSocketConfig config, bool value)
{
config.SetValue(CacheTimeoutEnableProperty, value);
return config;
}
/// <summary>
/// 适配器数据包最大值。默认缺省null当该值有效时会在设置适配器时直接作用于<see cref="DataHandlingAdapter.MaxPackageSize"/>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetMaxPackageSize(this TouchSocketConfig config, int value)
{
config.SetValue(MaxPackageSizeProperty, value);
return config;
}
/// <summary>
/// 适配器数据包缓存策略。默认缺省null当该值有效时会在设置适配器时直接作用于<see cref="SingleStreamDataHandlingAdapter.UpdateCacheTimeWhenRev"/>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetUpdateCacheTimeWhenRev(this TouchSocketConfig config, bool value)
{
config.SetValue(UpdateCacheTimeWhenRevProperty, value);
config.SetValue(AdapterOptionProperty, value);
return config;
}

View File

@@ -96,5 +96,45 @@ namespace ThingsGateway.Foundation.Core
this.m_dp.Clear();
base.Dispose(disposing);
}
/// <summary>
/// 将当前对象的依赖项克隆到目标对象中
/// </summary>
/// <param name="dependencyObject">目标对象</param>
/// <param name="overwrite">当目标对象中存在相同依赖项时,是或否覆盖</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ObjectDisposedException"></exception>
protected void CloneTo(DependencyObject dependencyObject, bool overwrite)
{
if (dependencyObject is null)
{
throw new ArgumentNullException(nameof(dependencyObject));
}
if (dependencyObject.DisposedValue)
{
throw new ObjectDisposedException(nameof(dependencyObject));
}
this.ThrowIfDisposed();
foreach (var item in this.m_dp)
{
if (dependencyObject.m_dp.ContainsKey(item.Key))
{
if (overwrite)
{
dependencyObject.m_dp.Remove(item.Key);
dependencyObject.m_dp.Add(item.Key, item.Value);
}
}
else
{
dependencyObject.m_dp.Add(item.Key, item.Value);
}
}
}
}
}

View File

@@ -189,7 +189,7 @@ namespace ThingsGateway.Foundation.Core
/// <returns></returns>
public static IEnumerable<string> GetTupleElementNames(this ParameterInfo parameter)
{
return ((dynamic)parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(parameter.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
}
/// <summary>
@@ -199,7 +199,7 @@ namespace ThingsGateway.Foundation.Core
/// <returns></returns>
public static IEnumerable<string> GetTupleElementNames(this MemberInfo memberInfo)
{
return ((dynamic)memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")))?.TransformNames;
return (IEnumerable<string>)DynamicMethodMemberAccessor.Default.GetValue(memberInfo.GetCustomAttribute(Type.GetType("System.Runtime.CompilerServices.TupleElementNamesAttribute")), "TransformNames");
}
#endregion

View File

@@ -73,5 +73,47 @@ namespace ThingsGateway.Foundation.Core
return task.ConfigureAwait(false);
}
/// <summary>
/// 异步等待指定最大时间
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="task"></param>
/// <param name="timeout"></param>
/// <returns></returns>
/// <exception cref="TimeoutException"></exception>
public static async Task<TResult> WaitAsync<TResult>(this Task<TResult> task, TimeSpan timeout)
{
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var delayTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token);
if (await Task.WhenAny(task, delayTask) == task)
{
timeoutCancellationTokenSource.Cancel();
return await task;
}
throw new TimeoutException();
}
}
/// <summary>
/// 异步等待指定最大时间
/// </summary>
/// <param name="task"></param>
/// <param name="timeout"></param>
/// <returns></returns>
/// <exception cref="TimeoutException"></exception>
public static async Task WaitAsync(this Task task, TimeSpan timeout)
{
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var delayTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token);
if (await Task.WhenAny(task, delayTask) == task)
{
timeoutCancellationTokenSource.Cancel();
await task;
}
throw new TimeoutException();
}
}
}
}

View File

@@ -23,22 +23,16 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Rpc
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 函数标识
/// 具有日志记录器的对象接口
/// </summary>
[Flags]
public enum MethodFlags
public interface ILoggerObject
{
/// <summary>
///
/// 日志记录器
/// </summary>
None = 1,
/// <summary>
/// 包含调用上下文
/// </summary>
IncludeCallContext = 2
ILog Logger { get; set; }
}
}

View File

@@ -11,6 +11,7 @@
#endregion
using System.Diagnostics;
using System.Runtime.CompilerServices;
#if NET6_0_OR_GREATER
using System.Numerics;
@@ -55,12 +56,11 @@ namespace ThingsGateway.Foundation.Core
}
var capacity = 0L;
var poolId = this.Id;
var maxBuckets = SelectBucketIndex(maxArrayLength);
var buckets = new Bucket[maxBuckets + 1];
for (var i = 0; i < buckets.Length; i++)
{
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
buckets[i] = new Bucket(GetMaxSizeForBucket(i), maxArraysPerBucket);
long num = GetMaxSizeForBucket(i) * maxArraysPerBucket;
capacity += num;
}
@@ -183,16 +183,19 @@ namespace ThingsGateway.Foundation.Core
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int HitSize(int size)
{
return GetMaxSizeForBucket(SelectBucketIndex(size));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int GetMaxSizeForBucket(int binIndex)
{
return 16 << binIndex;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int SelectBucketIndex(int bufferSize)
{
#if NET6_0_OR_GREATER
@@ -208,18 +211,16 @@ namespace ThingsGateway.Foundation.Core
internal readonly int m_bufferLength;
private readonly int m_numberOfBuffers;
private T[][] m_buffers;
private readonly int m_poolId;
private int m_index;
private SpinLock m_lock;
internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
internal Bucket(int bufferLength, int numberOfBuffers)
{
this.m_lock = new SpinLock(Debugger.IsAttached);
this.m_buffers = new T[numberOfBuffers][];
this.m_bufferLength = bufferLength;
this.m_numberOfBuffers = numberOfBuffers;
this.m_poolId = poolId;
}
public void Clear()

View File

@@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Core
/// <summary>
/// 内存池
/// </summary>
public class BytePool : ArrayPool<byte>
public sealed class BytePool : ArrayPool<byte>
{
private readonly Timer m_timer;

View File

@@ -0,0 +1,49 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Core
{
/// <summary>
/// 序列化器
/// </summary>
/// <typeparam name="TSource"></typeparam>
public interface ISerializer<TSource>
{
/// <summary>
/// 序列化
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
TSource Serialize(object target);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="source"></param>
/// <param name="targetType"></param>
/// <returns></returns>
object Deserialize(TSource source, Type targetType);
}
}

View File

@@ -123,25 +123,6 @@ namespace ThingsGateway.Foundation.Dmtp
{
}
/// <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;
}
}
/// <summary>
/// 建立对点
@@ -1051,7 +1032,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
#region
#region
/// <summary>
/// <inheritdoc/>
@@ -1070,7 +1051,25 @@ namespace ThingsGateway.Foundation.Dmtp
this.WaitHandlePool.SafeDispose();
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

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 提供Dmtp协议的最基础功能件
/// </summary>
public interface IDmtpActor : IDependencyObject
public interface IDmtpActor : IDependencyObject, IHandshakeObject
{
#region
@@ -39,11 +39,6 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
string Id { get; }
/// <summary>
/// 获取当前功能件是否已经完成握手连接状态。
/// </summary>
bool IsHandshaked { get; }
/// <summary>
/// 最后一次活动时间。
/// </summary>

View File

@@ -10,12 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>

View File

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

View File

@@ -0,0 +1,56 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
/// 针对Dmtp的配置项
/// </summary>
public class DmtpOption
{
/// <summary>
/// 连接令箭
/// </summary>
public string VerifyToken { get; set; }
/// <summary>
/// 连接时指定Id。
/// <para>
/// 使用该功能时仅在服务器的Handshaking之后生效。且如果id重复则会连接失败。
/// </para>
/// </summary>
public string Id { get; set; }
/// <summary>
/// 设置DmtpClient连接时的元数据
/// </summary>
public Metadata Metadata { get; set; }
/// <summary>
/// 验证连接超时时间。仅用于服务器。意为:当服务器收到基础链接,在指定的时间内如果没有收到握手信息,则直接视为无效链接,直接断开。
/// </summary>
public TimeSpan VerifyTimeout { get; set; } = TimeSpan.FromSeconds(3);
}
}

View File

@@ -70,7 +70,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 最大传输速度。
/// </summary>
public long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
public virtual long MaxSpeed { get => this.m_flowGate.Maximum; set => this.m_flowGate.Maximum = value; }
/// <summary>
/// 元数据

View File

@@ -22,7 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp
{

View File

@@ -35,14 +35,14 @@ namespace ThingsGateway.Foundation.Dmtp
private bool m_allowRoute;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
private DmtpActor m_dmtpActor;
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim m_semaphoreForConnect = 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;
/// <inheritdoc cref="IHandshakeObject.IsHandshaked"/>
public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
@@ -50,22 +50,23 @@ namespace ThingsGateway.Foundation.Dmtp
#region
/// <summary>
/// 建立Tcp连接并且执行握手。
/// 使用基于Http升级的协议连接Dmtp服务器
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
/// <param name="token"></param>
/// <exception cref="Exception"></exception>
public override ITcpClient Connect(int timeout = 5000)
public override void Connect(int timeout, CancellationToken token)
{
lock (this.SyncRoot)
try
{
this.m_semaphoreForConnect.Wait(token);
if (this.IsHandshaked)
{
return this;
return;
}
if (!this.Online)
{
base.Connect(timeout);
base.Connect(timeout, token);
}
var request = new HttpRequest()
@@ -78,72 +79,41 @@ namespace ThingsGateway.Foundation.Dmtp
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
return this;
this.m_dmtpActor.Handshake(
this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Id, timeout, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Metadata, token);
return;
}
else
{
throw new Exception(response.StatusMessage);
}
}
}
/// <inheritdoc/>
public virtual IHttpDmtpClient Connect(CancellationToken token, int timeout = 5000)
{
lock (this.SyncRoot)
finally
{
if (this.IsHandshaked)
{
return this;
}
if (!this.Online)
{
base.Connect(timeout);
}
var request = new HttpRequest()
.SetHost(this.RemoteIPHost.Host);
request.Headers.Add(HttpHeaders.Connection, "upgrade");
request.Headers.Add(HttpHeaders.Upgrade, DmtpUtility.Dmtp.ToLower());
request.AsMethod(DmtpUtility.Dmtp);
var response = this.RequestContent(request, timeout: timeout, token: token);
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
}
else
{
throw new Exception(response.StatusMessage);
}
this.m_semaphoreForConnect.Release();
}
}
/// <summary>
/// 建立Tcp连接并且执行握手。
/// 异步使用基于Http升级的协议连接Dmtp服务器
/// </summary>
/// <param name="timeout"></param>
/// <param name="token"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public override async Task<ITcpClient> ConnectAsync(int timeout = 5000)
public override async Task ConnectAsync(int timeout, CancellationToken token)
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForConnect.WaitAsync(timeout, token);
if (this.IsHandshaked)
{
return this;
return;
}
if (!this.Online)
{
await base.ConnectAsync(timeout);
await base.ConnectAsync(timeout, token);
}
var request = new HttpRequest()
@@ -152,14 +122,12 @@ namespace ThingsGateway.Foundation.Dmtp
request.Headers.Add(HttpHeaders.Upgrade, DmtpUtility.Dmtp.ToLower());
request.AsMethod(DmtpUtility.Dmtp);
var response = this.RequestContent(request);
var response = await this.RequestContentAsync(request);
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
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;
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Id, timeout, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Metadata, token);
return;
}
else
{
@@ -168,48 +136,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
finally
{
this.m_semaphore.Release();
}
}
/// <inheritdoc/>
public virtual async Task<IHttpDmtpClient> ConnectAsync(CancellationToken token, int timeout = 5000)
{
try
{
await this.m_semaphore.WaitAsync();
if (this.IsHandshaked)
{
return this;
}
if (!this.Online)
{
await base.ConnectAsync(timeout);
}
var request = new HttpRequest()
.SetHost(this.RemoteIPHost.Host);
request.Headers.Add(HttpHeaders.Connection, "upgrade");
request.Headers.Add(HttpHeaders.Upgrade, DmtpUtility.Dmtp.ToLower());
request.AsMethod(DmtpUtility.Dmtp);
var response = this.RequestContent(request, timeout: timeout, token: token);
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
}
else
{
throw new Exception(response.StatusMessage);
}
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForConnect.Release();
}
}
@@ -219,7 +146,10 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_dmtpActor?.SafeDispose();
if (this.IsHandshaked)
{
this.m_dmtpActor?.SafeDispose();
}
base.Dispose(disposing);
}
@@ -230,7 +160,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <returns></returns>
public override void Close(string msg = "")
{
if (this.m_dmtpActor != null)
if (this.IsHandshaked)
{
this.m_dmtpActor.SendClose(msg);
this.m_dmtpActor.Close(msg);
@@ -303,7 +233,7 @@ namespace ThingsGateway.Foundation.Dmtp
Routing = this.OnDmtpActorRouting,
Handshaking = this.OnDmtpActorHandshaking,
Handshaked = this.OnDmtpActorHandshaked,
Closed = OnDmtpActorClose,
Closed = this.OnDmtpActorClose,
CreatedChannel = this.OnDmtpActorCreateChannel,
Logger = this.Logger,
Client = this,

View File

@@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 连接令箭
/// </summary>
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty);
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken;
#region

View File

@@ -40,14 +40,14 @@ namespace ThingsGateway.Foundation.Dmtp
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
/// <summary>
/// 验证超时时间,默认为3000ms
/// 验证超时时间
/// </summary>
public int VerifyTimeout => this.Config.GetValue(DmtpConfigExtension.VerifyTimeoutProperty);
public TimeSpan VerifyTimeout => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyTimeout;
/// <summary>
/// 连接令箭
/// </summary>
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty);
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken;
#region

View File

@@ -10,10 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Http;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -21,20 +17,5 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
public interface IHttpDmtpClient : IHttpClient, IHttpDmtpClientBase
{
/// <summary>
/// 建立Tcp并发送Http请求最后完成Dmtp握手连接。
/// </summary>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
IHttpDmtpClient Connect(CancellationToken token, int timeout = 5000);
/// <summary>
/// 建立Tcp并发送Http请求最后完成Dmtp握手连接。
/// </summary>
/// <param name="token"></param>
/// <param name="timeout"></param>
/// <returns></returns>
Task<IHttpDmtpClient> ConnectAsync(CancellationToken token, int timeout = 5000);
}
}

View File

@@ -17,20 +17,6 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
public interface ITcpDmtpClient : ITcpDmtpClientBase, ITcpClient
{
/// <summary>
/// 建立Tcp连接并且执行握手。
/// </summary>
/// <param name="token">可取消令箭</param>
/// <param name="timeout">超时时间</param>
/// <returns></returns>
ITcpDmtpClient Connect(CancellationToken token, int timeout = 5000);
/// <summary>
/// 建立Tcp连接并且执行握手。
/// </summary>
/// <param name="token">可取消令箭</param>
/// <param name="timeout">超时时间</param>
/// <returns></returns>
Task<ITcpDmtpClient> ConnectAsync(CancellationToken token, int timeout = 5000);
}
}

View File

@@ -42,19 +42,19 @@ namespace ThingsGateway.Foundation.Dmtp
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc cref="IDmtpActor.Id"/>
public string Id => this.DmtpActor.Id;
public string Id => this.m_dmtpActor.Id;
#region
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim m_semaphoreForConnect = 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;
/// <inheritdoc cref="IHandshakeObject.IsHandshaked"/>
public bool IsHandshaked => this.m_dmtpActor != null && this.m_dmtpActor.IsHandshaked;
#region
@@ -65,15 +65,21 @@ namespace ThingsGateway.Foundation.Dmtp
/// <returns></returns>
public override void Close(string msg = "")
{
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
if (this.IsHandshaked)
{
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
}
base.Close(msg);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_dmtpActor?.SafeDispose();
if (this.IsHandshaked)
{
this.m_dmtpActor?.SafeDispose();
}
base.Dispose(disposing);
}
@@ -89,98 +95,60 @@ namespace ThingsGateway.Foundation.Dmtp
#region
/// <summary>
/// 建立Tcp连接并且执行握手。
/// 进行Dmtp协议的握手连接
/// </summary>
/// <param name="timeout"></param>
/// <param name="token"></param>
/// <returns></returns>
public override ITcpClient Connect(int timeout = 5000)
public override void Connect(int timeout, CancellationToken token)
{
lock (this.SyncRoot)
try
{
this.m_semaphoreForConnect.Wait(token);
if (this.IsHandshaked)
{
return this;
return;
}
if (!this.Online)
{
base.Connect(timeout);
base.Connect(timeout, token);
}
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
return this;
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken,
this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Id, timeout, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Metadata, token);
}
}
/// <inheritdoc/>
public virtual ITcpDmtpClient Connect(CancellationToken token, int timeout = 5000)
{
lock (this.SyncRoot)
finally
{
if (this.IsHandshaked)
{
return this;
}
if (!this.Online)
{
base.Connect(timeout);
}
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
this.m_semaphoreForConnect.Release();
}
}
/// <summary>
/// 建立Tcp连接并且执行握手。
/// 异步进行Dmtp协议的握手连接
/// </summary>
/// <param name="timeout"></param>
/// <param name="token"></param>
/// <returns></returns>
public override async Task<ITcpClient> ConnectAsync(int timeout = 5000)
public override async Task ConnectAsync(int timeout, CancellationToken token)
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForConnect.WaitAsync(timeout, token);
if (this.IsHandshaked)
{
return this;
return;
}
if (!this.Online)
{
await base.ConnectAsync(timeout).ConfigureFalseAwait();
await base.ConnectAsync(timeout, token);
}
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;
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken,
this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Id, timeout, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Metadata, token);
}
finally
{
this.m_semaphore.Release();
}
}
/// <inheritdoc/>
public virtual async Task<ITcpDmtpClient> ConnectAsync(CancellationToken token, int timeout = 5000)
{
try
{
await this.m_semaphore.WaitAsync();
if (this.IsHandshaked)
{
return this;
}
if (!this.Online)
{
await base.ConnectAsync(timeout).ConfigureFalseAwait();
}
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
{
this.m_semaphore.Release();
this.m_semaphoreForConnect.Release();
}
}

View File

@@ -48,7 +48,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 连接令箭
/// </summary>
public string VerifyToken => this.Config?.GetValue(DmtpConfigExtension.VerifyTokenProperty);
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken;
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)

View File

@@ -43,18 +43,18 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
/// <inheritdoc cref="IHandshakeObject.IsHandshaked"/>
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
/// <summary>
/// 验证超时时间,默认为3000ms
/// </summary>
public int VerifyTimeout => this.Config.GetValue(DmtpConfigExtension.VerifyTimeoutProperty);
public TimeSpan VerifyTimeout => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyTimeout;
/// <summary>
/// 连接令箭
/// </summary>
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty);
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken;
#region
@@ -161,22 +161,31 @@ namespace ThingsGateway.Foundation.Dmtp
/// <returns></returns>
public override void Close(string msg = "")
{
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
if (this.IsHandshaked)
{
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
}
base.Close(msg);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_dmtpActor?.SafeDispose();
if (this.IsHandshaked)
{
this.m_dmtpActor?.SafeDispose();
}
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.m_dmtpActor?.Close(e.Message);
if (this.IsHandshaked)
{
this.m_dmtpActor?.Close(e.Message);
}
await base.OnDisconnected(e).ConfigureFalseAwait();
}

View File

@@ -22,11 +22,7 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Net;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Sockets;
namespace ThingsGateway.Foundation.Dmtp.Rpc
{

View File

@@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// IWebSocketDmtpClient
/// </summary>
public interface IWebSocketDmtpClient : IWebSocketDmtpClientBase
public interface IWebSocketDmtpClient : IWebSocketDmtpClientBase, ISetupConfigObject
{
/// <summary>
/// 异步连接

View File

@@ -22,14 +22,5 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
string Id { get; }
/// <summary>
/// 加载到当前客户端的配置
/// </summary>
TouchSocketConfig Config { get; }
/// <summary>
/// 是否已完成<see cref="IDmtpActor.IsHandshaked"/>
/// </summary>
bool IsHandshaked { get; }
}
}

View File

@@ -22,19 +22,14 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Sockets;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
/// WebSocketDmtpClient
/// </summary>
public class WebSocketDmtpClient : BaseSocket, IWebSocketDmtpClient
public class WebSocketDmtpClient : SetupConfigObject, IWebSocketDmtpClient
{
/// <summary>
/// WebSocketDmtpClient
@@ -71,13 +66,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public bool CanSend => this.m_client.State == WebSocketState.Open;
/// <summary>
/// 客户端配置
/// </summary>
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public IContainer Container { get; private set; }
/// <summary>
/// 断开连接
@@ -99,20 +88,14 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public DateTime LastSendTime => this.m_sendCounter.LastIncrement;
/// <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"/>关闭消息。
@@ -170,9 +153,9 @@ namespace ThingsGateway.Foundation.Dmtp
_ = this.BeginReceive();
}
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).VerifyToken,
this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Id,
timeout, this.Config.GetValue(DmtpConfigExtension.DmtpOptionProperty).Metadata, token);
this.IsHandshaked = true;
}
finally
@@ -199,28 +182,6 @@ namespace ThingsGateway.Foundation.Dmtp
this.DmtpActor.ResetId(newId);
}
/// <summary>
/// 配置
/// </summary>
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
public IWebSocketDmtpClient Setup(TouchSocketConfig config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
this.ThrowIfDisposed();
this.BuildConfig(config);
this.PluginsManager.Raise(nameof(ILoadingConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
this.LoadConfig(this.Config);
this.PluginsManager.Raise(nameof(ILoadedConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
return this;
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
@@ -241,11 +202,9 @@ namespace ThingsGateway.Foundation.Dmtp
/// 加载配置
/// </summary>
/// <param name="config"></param>
protected virtual void LoadConfig(TouchSocketConfig config)
protected override void LoadConfig(TouchSocketConfig config)
{
this.RemoteIPHost = config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty);
this.Logger ??= this.Container.Resolve<ILog>();
if (this.Container.IsRegistered(typeof(IDmtpRouteService)))
{
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
@@ -271,7 +230,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
while (true)
{
using (var byteBlock = new ByteBlock(this.ReceiveBufferSize))
using (var byteBlock = new ByteBlock(this.m_receiveBufferSize))
{
var result = await this.m_client.ReceiveAsync(new ArraySegment<byte>(byteBlock.Buffer, 0, byteBlock.Capacity), default);
if (result.Count == 0)
@@ -295,7 +254,7 @@ namespace ThingsGateway.Foundation.Dmtp
private void BreakOut(string msg, bool manual)
{
lock (this.SyncRoot)
lock (this.m_semaphoreForConnect)
{
if (this.IsHandshaked)
{
@@ -309,47 +268,6 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
private void BuildConfig(TouchSocketConfig config)
{
this.Config = config;
if (!(config.GetValue(TouchSocketCoreConfigExtension.ContainerProperty) is IContainer container))
{
container = new Container();
}
if (!container.IsRegistered(typeof(ILog)))
{
container.RegisterSingleton<ILog, LoggerGroup>();
}
if (!(config.GetValue(TouchSocketCoreConfigExtension.PluginsManagerProperty) is IPluginsManager pluginsManager))
{
pluginsManager = new PluginsManager(container);
}
if (container.IsRegistered(typeof(IPluginsManager)))
{
pluginsManager = container.Resolve<IPluginsManager>();
}
else
{
container.RegisterSingleton<IPluginsManager>(pluginsManager);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigureContainerProperty) is Action<IContainer> actionContainer)
{
actionContainer.Invoke(container);
}
if (config.GetValue(TouchSocketCoreConfigExtension.ConfigurePluginsProperty) is Action<IPluginsManager> actionPluginsManager)
{
pluginsManager.Enable = true;
actionPluginsManager.Invoke(pluginsManager);
}
this.Container = container;
this.PluginsManager = pluginsManager;
}
private void OnReceivePeriod(long value)
{
@@ -371,7 +289,7 @@ namespace ThingsGateway.Foundation.Dmtp
var message = (DmtpMessage)requestInfo;
if (!this.m_dmtpActor.InputReceivedData(message).GetFalseAwaitResult())
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
this.PluginsManager?.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}

View File

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

View File

@@ -10,9 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>

View File

@@ -10,9 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Sockets;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -21,77 +18,20 @@ namespace ThingsGateway.Foundation.Dmtp
public static class DmtpConfigExtension
{
/// <summary>
/// 默认使用Id
/// 设置Dmtp相关配置
/// </summary>
public static readonly DependencyProperty<string> DefaultIdProperty =
DependencyProperty<string>.Register("DefaultId", null);
public static readonly DependencyProperty<DmtpOption> DmtpOptionProperty =
DependencyProperty<DmtpOption>.Register("DmtpOption", new DmtpOption());
/// <summary>
/// DmtpClient连接时的元数据, 所需类型<see cref="Metadata"/>
/// </summary>
public static readonly DependencyProperty<Metadata> MetadataProperty = DependencyProperty<Metadata>.Register("Metadata", null);
/// <summary>
/// 验证超时时间,默认为3000ms, 所需类型<see cref="int"/>
/// </summary>
public static readonly DependencyProperty<int> VerifyTimeoutProperty =
DependencyProperty<int>.Register("VerifyTimeout", 3000);
/// <summary>
/// 连接令箭,当为null或空时重置为默认值“rrqm”, 所需类型<see cref="string"/>
/// </summary>
public static readonly DependencyProperty<string> VerifyTokenProperty =
DependencyProperty<string>.Register("VerifyToken", "rrqm");
/// <summary>
/// 设置默认的使用Id。仅在DmtpRpc组件适用。
/// <para>
/// 使用该功能时仅在服务器的Handshaking之后生效。且如果id重复则会连接失败。
/// </para>
/// 设置Dmtp相关配置。
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetDefaultId(this TouchSocketConfig config, string value)
public static TouchSocketConfig SetDmtpOption(this TouchSocketConfig config, DmtpOption value)
{
config.SetValue(DefaultIdProperty, value);
return config;
}
/// <summary>
/// 设置DmtpClient连接时的元数据
/// <para>仅适用于DmtpClient系类</para>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetMetadata(this TouchSocketConfig config, Metadata value)
{
config.SetValue(MetadataProperty, value);
return config;
}
/// <summary>
/// 验证超时时间,默认为3000ms.
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetVerifyTimeout(this TouchSocketConfig config, int value)
{
config.SetValue(VerifyTimeoutProperty, value);
return config;
}
/// <summary>
/// 连接令箭当为null或空时重置为默认值“rrqm”
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig SetVerifyToken(this TouchSocketConfig config, string value)
{
config.SetValue(VerifyTokenProperty, value);
config.SetValue(DmtpOptionProperty, value);
return config;
}
@@ -186,32 +126,6 @@ namespace ThingsGateway.Foundation.Dmtp
#endregion HttpDmtp
//#region 创建UdpTouchRpc
///// <summary>
///// 构建UdpTouchRpc类
///// </summary>
///// <typeparam name="TClient"></typeparam>
///// <param name="config"></param>
///// <returns></returns>
//public static TClient BuildWithUdpTouchRpc<TClient>(this TouchSocketConfig config) where TClient : IUdpTouchRpc
//{
// TClient client = Activator.CreateInstance<TClient>();
// client.Setup(config);
// client.Start();
// return client;
//}
///// <summary>
///// 构建UdpTouchRpc类客户端
///// </summary>
///// <param name="config"></param>
///// <returns></returns>
//public static UdpTouchRpc BuildWithUdpTouchRpc(this TouchSocketConfig config)
//{
// return BuildWithUdpTouchRpc<UdpTouchRpc>(config);
//}
//#endregion 创建UdpTouchRpc
}
}

View File

@@ -22,7 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp
{

View File

@@ -10,11 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Resources;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
@@ -82,7 +77,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
await actor.SendAsync(this.m_pullFileResourceInfo_Request, byteBlock);
actor.Send(this.m_pullFileResourceInfo_Request, byteBlock);
return true;
}
else
@@ -97,12 +92,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.SwitchId();
byteBlock.Reset();
waitFileResource.Package(byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
}
else
{
waitFileResource.UnpackageBody(byteBlock);
_ = this.RequestPullFileResourceInfo(waitFileResource);
_ = Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
}
}
catch (Exception ex)
@@ -121,7 +116,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
await actor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
actor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
else
@@ -411,7 +406,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
else
{
waitSmallFilePackage.UnpackageBody(byteBlock);
_ = this.RequestPullSmallFile(waitSmallFilePackage);
_ = Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
}
}
catch (Exception ex)
@@ -1329,7 +1324,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
catch

View File

@@ -22,10 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{

View File

@@ -59,12 +59,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// </summary>
public int TryCount { get; set; } = 10;
/// <summary>
/// 设置结果状态
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public Result SetResult(Result result)
internal Result SetResult(Result result)
{
this.Result = result;
return result;

View File

@@ -22,11 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{

View File

@@ -22,7 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{

View File

@@ -22,7 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{

View File

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

View File

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

View File

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

View File

@@ -22,8 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.IO;
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{

View File

@@ -22,8 +22,8 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Resources;
namespace ThingsGateway.Foundation.Dmtp.Redis

View File

@@ -22,8 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.Redis
{

View File

@@ -22,8 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.Redis
{

View File

@@ -22,7 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.Redis
{

View File

@@ -240,7 +240,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
DmtpRpcPackage = rpcPackage
};
this.TryAdd(rpcPackage.Sign, callContext);
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
if (methodInstance.IncludeCallContext)
{
ps = new object[methodInstance.ParameterTypes.Length];
ps[0] = callContext;
@@ -314,7 +314,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
rpcPackage.ParametersBytes = new List<byte[]>();
var i = 0;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
if (methodInstance.IncludeCallContext)
{
i = 1;
}
@@ -383,6 +383,23 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
return default;
}
private static void CheckWaitDataStatus(WaitDataStatus status)
{
switch (status)
{
case WaitDataStatus.SetRunning:
return;
case WaitDataStatus.Canceled: throw new OperationCanceledException();
case WaitDataStatus.Overtime: throw new TimeoutException();
case WaitDataStatus.Disposed:
case WaitDataStatus.Default:
default:
{
throw new Exception(TouchSocketCoreResource.UnknownError.GetDescription());
}
}
}
#region Rpc
/// <inheritdoc/>
@@ -429,53 +446,33 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
case WaitDataStatus.SetRunning:
try
{
for (var i = 0; i < parameters.Length; i++)
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
try
{
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
else
{
parameters = null;
}
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
return returnType.GetDefault();
else
{
parameters = null;
}
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:
return returnType.GetDefault();
@@ -531,44 +528,24 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
break;
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
else
{
parameters = null;
}
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
else
{
parameters = null;
}
break;
}
@@ -630,33 +607,14 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
break;
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
break;
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
default:
@@ -719,31 +677,15 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
return returnType.GetDefault();
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:
@@ -794,7 +736,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
rpcPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
await this.DmtpActor.SendAsync(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
@@ -804,33 +746,14 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
break;
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
default:
@@ -881,7 +804,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
rpcPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
await this.DmtpActor.SendAsync(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
@@ -892,31 +815,15 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
return returnType.GetDefault();
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:
@@ -1000,33 +907,14 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
break;
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
break;
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
default:
@@ -1105,31 +993,15 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
return returnType.GetDefault();
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:
@@ -1206,40 +1078,24 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
return;
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
else
{
parameters = null;
}
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
else
{
parameters = null;
}
return;
}
@@ -1315,42 +1171,26 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (waitData.Wait(invokeOption.Timeout))
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (waitData.Wait(invokeOption.Timeout))
CheckWaitDataStatus(waitData.Wait(invokeOption.Timeout));
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
if (resultContext.IsByRef)
{
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
else
{
parameters = null;
}
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
for (var i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
return returnType.GetDefault();
else
{
parameters = null;
}
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:
@@ -1420,7 +1260,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
rpcPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
await this.DmtpActor.SendAsync(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
@@ -1430,33 +1270,14 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
break;
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
break;
}
default:
@@ -1524,7 +1345,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
rpcPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
await this.DmtpActor.SendAsync(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
@@ -1535,31 +1356,15 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
return returnType.GetDefault();
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
case WaitDataStatus.Overtime:
{
throw new TimeoutException("等待结果超时");
}
}
return returnType.GetDefault();
CheckWaitDataStatus(await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait());
var resultContext = (DmtpRpcPackage)waitData.WaitResult;
resultContext.ThrowStatus();
return this.SerializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, returnType);
}
default:

View File

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

View File

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

View File

@@ -22,9 +22,6 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Threading;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Rpc;
namespace ThingsGateway.Foundation.Dmtp.Rpc
{

View File

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

View File

@@ -12,6 +12,7 @@
#if NET6_0_OR_GREATER
using System.Text.Json.Serialization;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp

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