Compare commits

...

28 Commits

Author SHA1 Message Date
Kimdiego2098
c27dde085e 3.0.0.23 2023-10-20 21:38:22 +08:00
Kimdiego2098
d26cc308c0 优化SQLDB实时表模式,插入/更新 2023-10-20 21:38:07 +08:00
Kimdiego2098
fb1efdf290 sqlsugar提示默认中文 2023-10-20 21:37:42 +08:00
Kimdiego2098
3c99f2a472 update touchsocket 2023-10-20 21:03:29 +08:00
Kimdiego2098
affe9a44e0 优化 ModbusServer 内存占用 2023-10-20 01:53:48 +08:00
Kimdiego2098
43730fa519 3.0.0.21 2023-10-20 01:19:18 +08:00
Kimdiego2098
d39aa22b09 优化OPCUAServer,取消注册,提供多url写入 2023-10-20 01:19:05 +08:00
Kimdiego2098
e232a6b6ea 更新赞助名单 2023-10-19 21:15:35 +08:00
Kimdiego2098
71ebb36fe9 更新文档 2023-10-19 20:36:28 +08:00
Kimdiego2098
78a0b86327 更新版本:3.0.0.20 2023-10-19 20:27:31 +08:00
Kimdiego2098
2636c16a97 优化modbusServer内存管理 2023-10-19 20:24:39 +08:00
Kimdiego2098
fd77c0242d update touchsocket 2023-10-19 20:23:43 +08:00
Kimdiego2098
e74819a900 update toucksocket 2023-10-18 21:51:49 +08:00
Kimdiego2098
9b7f696c9b 更新文档 2023-10-18 20:42:10 +08:00
Kimdiego2098
0230d614e7 发布驱动包 2023-10-18 18:04:37 +08:00
Diego2098
252d99ad78 !12 【轻量级 PR】:修正心跳事件中的参数
Merge pull request !12 from youthalan/N/A
2023-10-18 06:59:17 +00:00
youthalan
1ffc200350 修正心跳事件中的参数
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 06:58:03 +00:00
Kimdiego2098
807d89b2b2 更新版本号 2023-10-18 13:13:03 +08:00
Kimdiego2098
4013afa1f1 初始化 采集/上传线程时 直接返回线程控制 2023-10-18 13:11:59 +08:00
Kimdiego2098
a580927ceb 更新OPCUAClient类库 2023-10-18 13:09:25 +08:00
Kimdiego2098
bf2cf52034 更新OPCUAClient类库 2023-10-18 12:45:26 +08:00
Kimdiego2098
81bb8b7c31 更新OPCUAClient类库 2023-10-18 12:44:58 +08:00
Kimdiego2098
a825007fb5 更新版本号与nuget发布 2023-10-18 12:39:42 +08:00
Kimdiego2098
988124d96a 更新OPCUAClient类库 2023-10-18 12:38:20 +08:00
Diego2098
f0de815296 !11 补充OPCClient类库事件的缺失文件
Merge pull request !11 from youthalan/N/A
2023-10-18 04:34:34 +00:00
youthalan
0e2d58c887 补充OPCClient类库事件的缺失文件
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 04:32:39 +00:00
Diego2098
b155382626 !10 添加连接或断开事件
Merge pull request !10 from youthalan/N/A
2023-10-18 04:20:22 +00:00
youthalan
f362d740af 修改OPCUAClient类添加连接或断开事件,修改注入时不需要带参数
Signed-off-by: youthalan <youthalan@126.com>
2023-10-18 03:48:05 +00:00
154 changed files with 2259 additions and 1492 deletions

View File

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

View File

@@ -116,16 +116,16 @@
<ItemGroup >
<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
<!--<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCUA" Version="*" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Siemens" Version="*" />
<!--<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
<PackageReference Include="ThingsGateway.Foundation.Adapter.Siemens" Version="*" />-->
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCDA\ThingsGateway.Foundation.Adapter.OPCDA.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" />
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />-->
<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />
</ItemGroup>
<ItemGroup >

View File

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

View File

@@ -101,62 +101,76 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
}
EasyLock easyLock = new();
/// <inheritdoc/>
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return new OperResult<byte[]>("地址错误");
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return new OperResult<byte[]>("地址错误");
}
Init(mAddress);
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
switch (mAddress.ReadFunction)
{
case 1:
byte[] bytes0 = new byte[len];
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Read(bytes0);
return OperResult.CreateSuccessResult(bytes0);
case 2:
byte[] bytes1 = new byte[len];
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Read(bytes1);
return OperResult.CreateSuccessResult(bytes1);
case 3:
byte[] bytes3 = new byte[len];
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Read(bytes3);
return OperResult.CreateSuccessResult(bytes3);
case 4:
byte[] bytes4 = new byte[len];
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Read(bytes4);
return OperResult.CreateSuccessResult(bytes4);
}
return new OperResult<byte[]>("功能码错误");
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
switch (mAddress.ReadFunction)
finally
{
case 1:
byte[] bytes0 = new byte[len];
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Read(bytes0);
return OperResult.CreateSuccessResult(bytes0);
case 2:
byte[] bytes1 = new byte[len];
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Read(bytes1);
return OperResult.CreateSuccessResult(bytes1);
case 3:
byte[] bytes3 = new byte[len];
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Read(bytes3);
return OperResult.CreateSuccessResult(bytes3);
case 4:
byte[] bytes4 = new byte[len];
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Read(bytes4);
return OperResult.CreateSuccessResult(bytes4);
easyLock.Release();
}
return new OperResult<byte[]>("功能码错误");
}
/// <inheritdoc/>
@@ -173,87 +187,108 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
SerialSession.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return new OperResult(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return new OperResult("地址错误");
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return new OperResult(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return new OperResult("地址错误");
}
Init(mAddress);
}
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
{
case 3:
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
case 4:
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
}
return new OperResult("功能码错误");
}
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
finally
{
case 3:
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
case 4:
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
easyLock.Release();
}
return new OperResult("功能码错误");
}
/// <inheritdoc/>
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return (new OperResult(ex));
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return (new OperResult("地址错误"));
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return (new OperResult(ex));
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return (new OperResult("地址错误"));
}
Init(mAddress);
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
{
case 1:
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
case 2:
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
}
return new OperResult("功能码错误");
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
finally
{
case 1:
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
case 2:
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
easyLock.Release();
}
return new OperResult("功能码错误");
}
/// <inheritdoc/>
@@ -409,13 +444,9 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase
private void Init(ModbusAddress mAddress)
{
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
}
}

View File

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

View File

@@ -104,62 +104,75 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
return PackHelper.LoadSourceRead<T, T2>(this, deviceVariables, maxPack);
}
EasyLock easyLock = new();
/// <inheritdoc/>
public override OperResult<byte[]> Read(string address, int length, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return new OperResult<byte[]>("地址错误");
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return new OperResult<byte[]>(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return new OperResult<byte[]>("地址错误");
}
Init(mAddress);
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
switch (mAddress.ReadFunction)
{
case 1:
byte[] bytes0 = new byte[len];
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Read(bytes0);
return OperResult.CreateSuccessResult(bytes0);
case 2:
byte[] bytes1 = new byte[len];
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Read(bytes1);
return OperResult.CreateSuccessResult(bytes1);
case 3:
byte[] bytes3 = new byte[len];
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Read(bytes3);
return OperResult.CreateSuccessResult(bytes3);
case 4:
byte[] bytes4 = new byte[len];
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Read(bytes4);
return OperResult.CreateSuccessResult(bytes4);
}
return new OperResult<byte[]>("功能码错误");
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
int len = mAddress.ReadFunction == 2 || mAddress.ReadFunction == 1 ? length : length * RegisterByteLength;
switch (mAddress.ReadFunction)
finally
{
case 1:
byte[] bytes0 = new byte[len];
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Read(bytes0);
return OperResult.CreateSuccessResult(bytes0);
case 2:
byte[] bytes1 = new byte[len];
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Read(bytes1);
return OperResult.CreateSuccessResult(bytes1);
case 3:
byte[] bytes3 = new byte[len];
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Read(bytes3);
return OperResult.CreateSuccessResult(bytes3);
case 4:
byte[] bytes4 = new byte[len];
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Read(bytes4);
return OperResult.CreateSuccessResult(bytes4);
easyLock.Release();
}
return new OperResult<byte[]>("功能码错误");
}
/// <inheritdoc/>
@@ -193,84 +206,104 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
/// <inheritdoc/>
public override OperResult Write(string address, byte[] value, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return new OperResult(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return new OperResult("地址错误");
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return new OperResult(ex);
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return new OperResult("地址错误");
}
Init(mAddress);
}
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
{
case 3:
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
case 4:
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
}
return new OperResult("功能码错误");
}
var ModbusServer03ByteBlock = ModbusServer03ByteBlocks[mAddress.Station];
var ModbusServer04ByteBlock = ModbusServer04ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
finally
{
case 3:
ModbusServer03ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer03ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
case 4:
ModbusServer04ByteBlock.Pos = mAddress.AddressStart * RegisterByteLength;
ModbusServer04ByteBlock.Write(value);
return OperResult.CreateSuccessResult();
easyLock.Release();
}
return new OperResult("功能码错误");
}
/// <inheritdoc/>
public override OperResult Write(string address, bool[] value, CancellationToken cancellationToken = default)
{
ModbusAddress mAddress;
try
{
mAddress = ModbusAddress.ParseFrom(address, Station);
}
catch (Exception ex)
{
return (new OperResult(ex));
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
easyLock.Wait();
ModbusAddress mAddress;
try
{
return (new OperResult("地址错误"));
mAddress = ModbusAddress.ParseFrom(address, Station);
}
Init(mAddress);
catch (Exception ex)
{
return (new OperResult(ex));
}
if (MulStation)
{
Init(mAddress);
}
else
{
if (Station != mAddress.Station)
{
return (new OperResult("地址错误"));
}
Init(mAddress);
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
{
case 1:
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
case 2:
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
}
return new OperResult("功能码错误");
}
var ModbusServer01ByteBlock = ModbusServer01ByteBlocks[mAddress.Station];
var ModbusServer02ByteBlock = ModbusServer02ByteBlocks[mAddress.Station];
switch (mAddress.ReadFunction)
finally
{
case 1:
ModbusServer01ByteBlock.Pos = mAddress.AddressStart;
ModbusServer01ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
case 2:
ModbusServer02ByteBlock.Pos = mAddress.AddressStart;
ModbusServer02ByteBlock.Write(value.BoolArrayToByte());
return (OperResult.CreateSuccessResult());
easyLock.Release();
}
return new OperResult("功能码错误");
}
/// <inheritdoc/>
@@ -429,13 +462,9 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase
private void Init(ModbusAddress mAddress)
{
if (ModbusServer01ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer01ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer02ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer02ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer03ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer03ByteBlocks[mAddress.Station].SetLength(1024 * 128);
if (ModbusServer04ByteBlocks.TryAdd(mAddress.Station, new(1024 * 128)))
ModbusServer04ByteBlocks[mAddress.Station].SetLength(1024 * 128);
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a => new ByteBlock(1024 * 128));
}
}

View File

@@ -1,4 +1,5 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
@@ -8,6 +9,7 @@
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Newtonsoft.Json.Linq;
@@ -17,22 +19,23 @@ using Opc.Ua.Client;
using Opc.Ua.Client.ComplexTypes;
using Opc.Ua.Configuration;
//修改自https://github.com/dathlin/OpcUaHelper 与OPC基金会net库
namespace ThingsGateway.Foundation.Adapter.OPCUA;
/// <summary>
/// 订阅委托
/// </summary>
/// <param name="value"></param>
public delegate void DataChangedEventHandler((VariableNode variableNode, DataValue dataValue, JToken jToken) value);
/// <summary>
/// OPCUAClient
/// </summary>
public class OPCUAClient : IDisposable
{
#region
/// <summary>
/// 当前配置
/// </summary>
@@ -48,30 +51,35 @@ public class OPCUAClient : IDisposable
/// </summary>
public List<string> Variables = new();
private readonly Action<byte, object, string, Exception> _logAction;
/// <summary>
/// 当前的变量名称/OPC变量节点
/// </summary>
private readonly Dictionary<string, VariableNode> _variableDicts = new();
private readonly object checkLock = new();
/// <summary>
/// 当前的订阅组,组名称/组
/// </summary>
private readonly Dictionary<string, Subscription> dic_subscriptions = new();
private readonly ApplicationInstance m_application = new();
private readonly ApplicationConfiguration m_configuration;
private SessionReconnectHandler m_reConnectHandler;
private EventHandler m_ReconnectComplete;
private EventHandler m_ReconnectStarting;
private EventHandler<KeepAliveEventArgs> m_KeepAliveComplete;
private EventHandler<bool> m_ConnectComplete;
private EventHandler<OpcUaStatusEventArgs> m_OpcStatusChange;
private ISession m_session;
/// <summary>
/// 默认的构造函数实例化一个新的OPC UA类
/// </summary>
public OPCUAClient(Action<byte, object, string, Exception> log)
public OPCUAClient()
{
_logAction = log;
var certificateValidator = new CertificateValidator();
certificateValidator.CertificateValidation += CertificateValidation;
@@ -90,7 +98,6 @@ public class OPCUAClient : IDisposable
MaxMessageQueueSize = 1000000,
MaxNotificationQueueSize = 1000000,
MaxPublishRequestCount = 10000000,
},
SecurityConfiguration = new SecurityConfiguration
@@ -133,8 +140,6 @@ public class OPCUAClient : IDisposable
StoreType = CertificateStoreType.Directory,
StorePath = AppContext.BaseDirectory + @"OPCUAClientCertificate\pki\trustedUser",
}
},
TransportQuotas = new TransportQuotas
@@ -160,8 +165,6 @@ public class OPCUAClient : IDisposable
m_configuration.Validate(ApplicationType.Client);
m_application.ApplicationConfiguration = m_configuration;
}
/// <summary>
@@ -188,6 +191,52 @@ public class OPCUAClient : IDisposable
/// SessionReconnectHandler
/// </summary>
public SessionReconnectHandler ReConnectHandler => m_reConnectHandler;
/// <summary>
/// Raised when a good keep alive from the server arrives.
/// </summary>
public event EventHandler<KeepAliveEventArgs> KeepAliveComplete
{
add { m_KeepAliveComplete += value; }
remove { m_KeepAliveComplete -= value; }
}
/// <summary>
/// Raised when a reconnect operation starts.
/// </summary>
public event EventHandler ReconnectStarting
{
add { m_ReconnectStarting += value; }
remove { m_ReconnectStarting -= value; }
}
/// <summary>
/// Raised when a reconnect operation completes.
/// </summary>
public event EventHandler ReconnectComplete
{
add { m_ReconnectComplete += value; }
remove { m_ReconnectComplete -= value; }
}
/// <summary>
/// Raised after successfully connecting to or disconnecing from a server.
/// </summary>
public event EventHandler<bool> ConnectComplete
{
add { m_ConnectComplete += value; }
remove { m_ConnectComplete -= value; }
}
/// <summary>
/// Raised after the client status change
/// </summary>
public event EventHandler<OpcUaStatusEventArgs> OpcStatusChange
{
add { m_OpcStatusChange += value; }
remove { m_OpcStatusChange -= value; }
}
/// <summary>
/// 当前活动会话。
/// </summary>
@@ -231,7 +280,7 @@ public class OPCUAClient : IDisposable
}
catch (Exception ex)
{
_logAction?.Invoke(3, this, $"初始化{items[i]}变量订阅失败", ex);
UpdateStatus(3, DateTime.Now, $"初始化{items[i]}变量订阅失败,错误原因:{ex}");
}
}
m_subscription.AddItems(monitoredItems);
@@ -247,9 +296,9 @@ public class OPCUAClient : IDisposable
var isError = m_subscription.MonitoredItems.Any(a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode));
if (isError)
{
_logAction?.Invoke(3, this, $"创建以下变量订阅失败:{Environment.NewLine}{m_subscription.MonitoredItems.Where(
UpdateStatus(3, DateTime.Now, $"创建以下变量订阅失败:{Environment.NewLine}{m_subscription.MonitoredItems.Where(
a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode))
.Select(a => $"{a.StartNodeId.ToString()}{a.Status.Error.ToString()}").ToJsonString()}", null);
.Select(a => $"{a.StartNodeId.ToString()}{a.Status.Error.ToString()}").ToJsonString()}");
}
lock (dic_subscriptions)
@@ -281,7 +330,6 @@ public class OPCUAClient : IDisposable
item.Value.Delete(true);
m_session.RemoveSubscription(item.Value);
try { item.Value.Dispose(); } catch { }
}
dic_subscriptions.Clear();
}
@@ -304,39 +352,40 @@ public class OPCUAClient : IDisposable
dic_subscriptions.RemoveWhere(a => a.Key == subscriptionName);
}
}
}
private void Callback(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs monitoredItemNotificationEventArgs)
{
try
{
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false);
foreach (var value in monitoreditem.DequeueValues())
if (m_session != null)
{
if (value.Value != null)
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false);
foreach (var value in monitoreditem.DequeueValues())
{
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
if (data == null && value.Value != null)
if (value.Value != null)
{
_logAction?.Invoke(3, this, $"{monitoreditem.StartNodeId}转换出错原始值String为{value.Value}", null);
var data1 = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
if (data == null && value.Value != null)
{
UpdateStatus(3, DateTime.Now, $"{monitoreditem.StartNodeId}转换出错原始值String为{value.Value}");
var data1 = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
}
DataChangedHandler?.Invoke((variableNode, value, data));
}
else
{
var data = JValue.CreateNull();
DataChangedHandler?.Invoke((variableNode, value, data));
}
DataChangedHandler?.Invoke((variableNode, value, data));
}
else
{
var data = JValue.CreateNull();
DataChangedHandler?.Invoke((variableNode, value, data));
}
}
}
catch (Exception ex)
{
_logAction?.Invoke(3, this, $"{monitoreditem.StartNodeId}订阅处理错误", ex);
UpdateStatus(3, DateTime.Now, $"{monitoreditem.StartNodeId}订阅处理错误,错误原因:" + ex);
}
}
#endregion
@@ -462,8 +511,8 @@ public class OPCUAClient : IDisposable
#endregion
#region
private ComplexTypeSystem typeSystem;
/// <summary>
@@ -472,7 +521,6 @@ public class OPCUAClient : IDisposable
public async Task ConnectAsync()
{
await ConnectAsync(OPCNode.OPCUrl);
_logAction?.Invoke(1, this, $"连接成功", null);
}
/// <summary>
@@ -484,10 +532,10 @@ public class OPCUAClient : IDisposable
// disconnect any existing session.
if (m_session != null)
{
_logAction?.Invoke(1, this, $"主动断开连接", null);
m_session = null;
}
}
/// <summary>
/// Creates a new session.
/// </summary>
@@ -516,20 +564,24 @@ public class OPCUAClient : IDisposable
//创建本地证书
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
m_session = await Opc.Ua.Client.Session.Create(
m_configuration,
endpoint,
false,
OPCNode.CheckDomain,
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
60000,
userIdentity,
Array.Empty<string>());
m_configuration,
endpoint,
false,
OPCNode.CheckDomain,
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
60000,
userIdentity,
Array.Empty<string>());
typeSystem = new ComplexTypeSystem(m_session);
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
// raise an event.
DoConnectComplete(true);
UpdateStatus(2, DateTime.UtcNow, "Connected");
//如果是订阅模式,连接时添加订阅组
if (OPCNode.ActiveSubscribe)
await AddSubscriptionAsync(Guid.NewGuid().ToString(), Variables.ToArray(), OPCNode.LoadType);
@@ -538,6 +590,9 @@ public class OPCUAClient : IDisposable
private void PrivateDisconnect()
{
bool state = m_session?.Connected == true;
if (m_reConnectHandler != null)
{
try { m_reConnectHandler.Dispose(); } catch { }
@@ -549,8 +604,14 @@ public class OPCUAClient : IDisposable
m_session.Close(10000);
}
if (state)
{
UpdateStatus(2, DateTime.UtcNow, "Disconnected");
DoConnectComplete(false);
}
}
#endregion
#region /
@@ -593,7 +654,6 @@ public class OPCUAClient : IDisposable
valuesToWrite.Add(valueToWrite);
}
var result = await m_session.WriteAsync(
requestHeader: null,
nodesToWrite: valuesToWrite, cancellationToken);
@@ -601,7 +661,6 @@ public class OPCUAClient : IDisposable
ClientBase.ValidateResponse(result.Results, valuesToWrite);
ClientBase.ValidateDiagnosticInfos(result.DiagnosticInfos, valuesToWrite);
var keys = writeInfoLists.Keys.ToList();
for (int i = 0; i < keys.Count; i++)
{
@@ -624,7 +683,6 @@ public class OPCUAClient : IDisposable
}
return results;
}
}
/// <summary>
@@ -706,7 +764,6 @@ public class OPCUAClient : IDisposable
return node;
}
/// <summary>
/// 从服务器读取节点
/// </summary>
@@ -729,18 +786,14 @@ public class OPCUAClient : IDisposable
}
else
{
_logAction?.Invoke(3, this, $"获取服务器节点信息失败{nodes.Item2[i]}", null);
UpdateStatus(3, DateTime.Now, $"获取服务器节点信息失败{nodes.Item2[i]}");
}
}
return nodes.Item1.ToList();
}
#endregion
#region
/// <summary>
@@ -805,7 +858,6 @@ public class OPCUAClient : IDisposable
ResultMask = (uint)BrowseResultMask.All
};
nodesToBrowse.Add(nodeToBrowse);
}
return await ReadNoteAttributeAsync(nodesToBrowse, nodesToRead, cancellationToken);
@@ -968,11 +1020,9 @@ public class OPCUAClient : IDisposable
return nodeAttribute.ToArray();
}
#endregion
/// <inheritdoc/>
public void Dispose()
{
@@ -991,7 +1041,6 @@ public class OPCUAClient : IDisposable
throw new Exception(string.Format("验证证书失败,错误代码:{0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
}
private async Task<Dictionary<string, List<OPCNodeAttribute>>> ReadNoteAttributeAsync(BrowseDescriptionCollection nodesToBrowse, ReadValueIdCollection nodesToRead, CancellationToken cancellationToken)
{
int startOfProperties = nodesToRead.Count;
@@ -1068,7 +1117,6 @@ public class OPCUAClient : IDisposable
}
}
if (nodeAttributes.ContainsKey(nodeToRead.NodeId.ToString()))
{
nodeAttributes[nodeToRead.NodeId.ToString()].Add(item);
@@ -1086,21 +1134,47 @@ public class OPCUAClient : IDisposable
/// </summary>
private void Server_ReconnectComplete(object sender, EventArgs e)
{
if (!Object.ReferenceEquals(sender, m_reConnectHandler))
try
{
return;
if (!Object.ReferenceEquals(sender, m_reConnectHandler))
{
return;
}
m_session = m_reConnectHandler.Session;
m_reConnectHandler.Dispose();
m_reConnectHandler = null;
// raise any additional notifications.
m_ReconnectComplete?.Invoke(this, e);
}
catch (Exception)
{
throw;
}
}
m_session = m_reConnectHandler.Session;
m_reConnectHandler = null;
/// <summary>
/// Report the client status
/// </summary>
/// <param name="logLevel">Whether the status represents an error. </param>
/// <param name="time">The time associated with the status.</param>
/// <param name="status">The status message.</param>
/// <param name="args">Arguments used to format the status message.</param>
private void UpdateStatus(int logLevel, DateTime time, string status, params object[] args)
{
m_OpcStatusChange?.Invoke(this, new OpcUaStatusEventArgs()
{
LogLevel = logLevel,
Time = time.ToLocalTime(),
Text = String.Format(status, args),
});
}
private void Session_KeepAlive(ISession session, KeepAliveEventArgs e)
{
lock (checkLock)
{
if (!Object.ReferenceEquals(session, m_session))
{
return;
@@ -1108,22 +1182,39 @@ public class OPCUAClient : IDisposable
if (ServiceResult.IsBad(e.Status))
{
_logAction?.Invoke(3, this, $"心跳检测错误:{e.Status}", null);
if (m_session.KeepAliveInterval <= 0)
{
UpdateStatus(3, e.CurrentTime, "Communication Error ({0})", e.Status);
return;
}
UpdateStatus(3, e.CurrentTime, "Reconnecting in {0}s", m_session.KeepAliveInterval / 1000);
if (m_reConnectHandler == null)
{
m_ReconnectStarting?.Invoke(this, e);
m_reConnectHandler = new SessionReconnectHandler();
m_reConnectHandler.BeginReconnect(m_session, m_session.KeepAliveInterval, Server_ReconnectComplete);
}
return;
}
// update status.
UpdateStatus(0, e.CurrentTime, "Session_KeepAlive Connected [{0}]", session.Endpoint.EndpointUrl);
// raise any additional notifications.
m_KeepAliveComplete?.Invoke(this, e);
}
}
/// <summary>
/// Raises the connect complete event on the main GUI thread.
/// </summary>
private void DoConnectComplete(bool state)
{
m_ConnectComplete?.Invoke(this, state);
}
#endregion
}

View File

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

View File

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

View File

@@ -24,7 +24,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
public ReadWriteDevicesSerialSessionBase(SerialSession serialSession)
{
SerialSession = serialSession;
WaitingClientEx = SerialSession.CreateWaitingClient(new() { ThrowBreakException = true });
WaitingClientEx = SerialSession.CreateWaitingClient(new() { });
SerialSession.Received -= Received;
SerialSession.Connecting -= Connecting;
SerialSession.Connected -= Connected;
@@ -96,7 +96,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
waitingOptions ??= new WaitingOptions { };
ResponsedData result = SerialSession.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
@@ -111,7 +111,7 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
waitingOptions ??= new WaitingOptions { };
ResponsedData result = await SerialSession.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}

View File

@@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
public ReadWriteDevicesTcpClientBase(TcpClient tcpClient)
{
TcpClient = tcpClient;
WaitingClientEx = TcpClient.CreateWaitingClient(new() { ThrowBreakException = true });
WaitingClientEx = TcpClient.CreateWaitingClient(new() { });
TcpClient.Connecting -= Connecting;
TcpClient.Connected -= Connected;
TcpClient.Disconnecting -= Disconnecting;
@@ -86,7 +86,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, };
waitingOptions ??= new WaitingOptions { };
ResponsedData result = TcpClient.CreateWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}
@@ -101,7 +101,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase
{
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true };
waitingOptions ??= new WaitingOptions { };
ResponsedData result = await TcpClient.CreateWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken);
return OperResult.CreateSuccessResult(result.Data);
}

View File

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

View File

@@ -51,10 +51,10 @@ public sealed class EasyLock
/// <summary>
/// 进入锁
/// </summary>
public void Wait()
public void Wait(CancellationToken cancellationToken = default)
{
Interlocked.Increment(ref lockWaitCount);
m_waiterLock.Wait();
m_waiterLock.Wait(cancellationToken);
Interlocked.Decrement(ref lockWaitCount);
}
/// <summary>
@@ -71,10 +71,10 @@ public sealed class EasyLock
/// <summary>
/// 进入锁
/// </summary>
public async Task WaitAsync()
public async Task WaitAsync(CancellationToken cancellationToken = default)
{
Interlocked.Increment(ref lockWaitCount);
await m_waiterLock.WaitAsync();
await m_waiterLock.WaitAsync(cancellationToken);
Interlocked.Decrement(ref lockWaitCount);
}
/// <summary>

View File

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

View File

@@ -23,6 +23,8 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Runtime.CompilerServices;
namespace ThingsGateway.Foundation.Core
{
/// <summary>
@@ -49,5 +51,27 @@ namespace ThingsGateway.Foundation.Core
{
task.ConfigureAwait(false).GetAwaiter().GetResult();
}
/// <summary>
/// 配置ConfigureAwait为false。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="task"></param>
/// <returns></returns>
public static ConfiguredTaskAwaitable<T> ConfigureFalseAwait<T>(this Task<T> task)
{
return task.ConfigureAwait(false);
}
/// <summary>
/// 配置ConfigureAwait为false。
/// </summary>
/// <param name="task"></param>
public static ConfiguredTaskAwaitable ConfigureFalseAwait(this Task task)
{
return task.ConfigureAwait(false);
}
}
}

View File

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

View File

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

View File

@@ -27,43 +27,48 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 请求关闭
/// </summary>
public Action<DmtpActor, string> OnClose { get; set; }
public Func<DmtpActor, string, Task> Closed { get; set; }
/// <summary>
/// 当创建通道时
/// </summary>
public Action<DmtpActor, CreateChannelEventArgs> OnCreateChannel { get; set; }
public Func<DmtpActor, CreateChannelEventArgs, Task> CreatedChannel { get; set; }
/// <summary>
/// 查找其他IDmtpActor
/// </summary>
public Func<string, IDmtpActor> OnFindDmtpActor { get; set; }
public Func<string, Task<IDmtpActor>> FindDmtpActor { get; set; }
/// <summary>
/// 在完成握手连接时
/// </summary>
public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaked { get; set; }
public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaked { get; set; }
/// <summary>
/// 握手
/// </summary>
public Action<DmtpActor, DmtpVerifyEventArgs> OnHandshaking { get; set; }
public Func<DmtpActor, DmtpVerifyEventArgs, Task> Handshaking { get; set; }
/// <summary>
/// 重设Id
/// </summary>
public Action<DmtpActor, WaitSetId> OnResetId { get; set; }
public Func<DmtpActor, IdChangedEventArgs, Task> IdChanged { get; set; }
/// <summary>
/// 当需要路由的时候
/// </summary>
public Action<DmtpActor, PackageRouterEventArgs> OnRouting { get; set; }
public Func<DmtpActor, PackageRouterEventArgs, Task> Routing { get; set; }
/// <summary>
/// 发送数据接口
/// </summary>
public Action<DmtpActor, ArraySegment<byte>[]> OutputSend { get; set; }
/// <summary>
/// 异步发送数据接口
/// </summary>
public Func<DmtpActor, ArraySegment<byte>[], Task> OutputSendAsync { get; set; }
#endregion
#region
@@ -119,29 +124,22 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public virtual void Close(bool sendClose, string message)
public void Close(string msg)
{
this.OnClosed(true, msg);
}
/// <inheritdoc/>
public bool SendClose(string msg)
{
try
{
if (this.IsHandshaked)
{
try
{
if (sendClose)
{
this.SendString(0, message);
}
}
catch
{
}
this.IsHandshaked = false;
this.WaitHandlePool.CancelAll();
this.OnClose?.Invoke(this, message);
}
this.SendString(0, msg);
return true;
}
catch
{
return false;
}
}
@@ -165,7 +163,7 @@ namespace ThingsGateway.Foundation.Dmtp
Metadata = metadata
};
this.OnHandshaking?.Invoke(this, args);
this.OnHandshaking(args).GetFalseAwaitResult();
var waitVerify = new WaitVerify()
{
@@ -189,7 +187,8 @@ namespace ThingsGateway.Foundation.Dmtp
{
this.Id = verifyResult.Id;
this.IsHandshaked = true;
this.PrivateHandshaked(new DmtpVerifyEventArgs()
Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs()
{
Id = verifyResult.Id,
Metadata = verifyResult.Metadata,
@@ -201,18 +200,15 @@ namespace ThingsGateway.Foundation.Dmtp
else
{
verifyResult.Handle = true;
this.Close(false, verifyResult.Message);
throw new TokenVerifyException(verifyResult.Message);
}
}
case WaitDataStatus.Overtime:
this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription());
throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription());
case WaitDataStatus.Canceled:
case WaitDataStatus.Disposed:
default:
this.Close(false, null);
return;
throw new OperationCanceledException();
}
}
finally
@@ -240,7 +236,7 @@ namespace ThingsGateway.Foundation.Dmtp
Metadata = metadata
};
this.OnHandshaking?.Invoke(this, args);
await this.OnHandshaking(args).ConfigureFalseAwait();
var waitVerify = new WaitVerify()
{
@@ -253,8 +249,8 @@ namespace ThingsGateway.Foundation.Dmtp
try
{
this.SendJsonObject(P1_Handshake_Request, waitVerify);
switch (await waitData.WaitAsync(timeout))
await this.SendJsonObjectAsync(P1_Handshake_Request, waitVerify).ConfigureFalseAwait();
switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -263,7 +259,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
this.Id = verifyResult.Id;
this.IsHandshaked = true;
this.PrivateHandshaked(new DmtpVerifyEventArgs()
_ = Task.Factory.StartNew(this.PrivateOnHandshaked, new DmtpVerifyEventArgs()
{
Id = verifyResult.Id,
Metadata = verifyResult.Metadata,
@@ -275,18 +271,15 @@ namespace ThingsGateway.Foundation.Dmtp
else
{
verifyResult.Handle = true;
this.Close(false, verifyResult.Message);
throw new TokenVerifyException(verifyResult.Message);
}
}
case WaitDataStatus.Overtime:
this.Close(false, TouchSocketDmtpStatus.Overtime.GetDescription());
throw new TimeoutException(TouchSocketDmtpStatus.Overtime.GetDescription());
case WaitDataStatus.Canceled:
case WaitDataStatus.Disposed:
default:
this.Close(false, null);
return;
throw new OperationCanceledException();
}
}
finally
@@ -295,6 +288,100 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
#region
/// <summary>
/// 当关闭后
/// </summary>
/// <param name="manual"></param>
/// <param name="msg"></param>
protected virtual Task OnClosed(bool manual, string msg)
{
if (this.IsHandshaked)
{
this.IsHandshaked = false;
this.WaitHandlePool.CancelAll();
}
if (manual)
{
return EasyTask.CompletedTask;
}
if (this.Closed != null)
{
return this.Closed.Invoke(this, msg);
}
return EasyTask.CompletedTask;
}
/// <summary>
/// 正在握手连接
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (this.Handshaking != null)
{
return this.Handshaking.Invoke(this, e);
}
return EasyTask.CompletedTask;
}
/// <summary>
/// 握手连接完成
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (this.Handshaked != null)
{
return this.Handshaked.Invoke(this, e);
}
return EasyTask.CompletedTask;
}
/// <summary>
/// 当Id修改时
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task OnIdChanged(IdChangedEventArgs e)
{
if (this.IdChanged != null)
{
return this.IdChanged.Invoke(this, e);
}
return EasyTask.CompletedTask;
}
/// <summary>
/// 当完成创建通道时
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task OnCreatedChannel(CreateChannelEventArgs e)
{
if (this.CreatedChannel != null)
{
return this.CreatedChannel.Invoke(this, e);
}
return EasyTask.CompletedTask;
}
private void PrivateOnHandshaked(object obj)
{
this.OnHandshaked((DmtpVerifyEventArgs)obj);
}
private void PrivateOnCreatedChannel(object obj)
{
this.OnCreatedChannel((CreateChannelEventArgs)obj);
}
#endregion
#region const
/// <summary>
@@ -368,7 +455,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public virtual bool InputReceivedData(DmtpMessage message)
public virtual async Task<bool> InputReceivedData(DmtpMessage message)
{
this.LastActiveTime = DateTime.Now;
var byteBlock = message.BodyByteBlock;
@@ -376,7 +463,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
case P0_Close:
{
this.Close(false, message.GetBodyString());
_ = this.OnClosed(false, message.GetBodyString());
return true;
}
case P1_Handshake_Request:
@@ -391,11 +478,11 @@ namespace ThingsGateway.Foundation.Dmtp
Metadata = waitVerify.Metadata,
Id = waitVerify.Id,
};
this.OnHandshaking?.Invoke(this, args);
await this.OnHandshaking(args).ConfigureFalseAwait();
if (args.Id.HasValue())
{
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, args.Id));
await this.OnIdChanged(new IdChangedEventArgs(this.Id, args.Id)).ConfigureFalseAwait();
this.Id = args.Id;
}
@@ -403,24 +490,23 @@ namespace ThingsGateway.Foundation.Dmtp
{
waitVerify.Id = this.Id;
waitVerify.Status = 1;
this.SendJsonObject(P2_Handshake_Response, waitVerify);
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait();
this.IsHandshaked = true;
args.Message = "Success";
Task.Factory.StartNew(this.PrivateHandshaked, args);
_ = Task.Factory.StartNew(this.PrivateOnHandshaked, args);
}
else//不允许连接
{
waitVerify.Status = 2;
waitVerify.Message = args.Message;
this.SendJsonObject(P2_Handshake_Response, waitVerify);
this.Close(false, args.Message);
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureFalseAwait();
_ = this.OnClosed(false, args.Message);
}
}
catch (Exception ex)
{
this.Logger.Error(this, $"在protocol={message.ProtocolFlags}中发生错误。信息:{ex.Message}");
this.Close(false, ex.Message);
_ = this.OnClosed(false, ex.Message);
}
return true;
}
@@ -449,7 +535,7 @@ namespace ThingsGateway.Foundation.Dmtp
var waitSetId = this.ResolveJsonObject<WaitSetId>(message.GetBodyString());
try
{
this.OnResetId?.Invoke(this, waitSetId);
await this.OnIdChanged(new IdChangedEventArgs(waitSetId.OldId, waitSetId.NewId)).ConfigureFalseAwait();
this.Id = waitSetId.NewId;
waitSetId.Status = 1;
}
@@ -458,7 +544,7 @@ namespace ThingsGateway.Foundation.Dmtp
waitSetId.Status = 2;
waitSetId.Message = ex.Message;
}
this.SendJsonObject(P4_ResetId_Response, waitSetId);
await this.SendJsonObjectAsync(P4_ResetId_Response, waitSetId).ConfigureFalseAwait();
}
catch (Exception ex)
{
@@ -486,11 +572,12 @@ namespace ThingsGateway.Foundation.Dmtp
if (this.AllowRoute && waitPing.Route)
{
if (this.TryRoute(RouteType.Ping, waitPing))
if (await this.TryRoute(new PackageRouterEventArgs(RouteType.Ping, waitPing)).ConfigureFalseAwait())
{
if (this.TryFindDmtpActor(waitPing.TargetId, out var actor))
if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(P5_Ping_Request, byteBlock);
await actor.SendAsync(P5_Ping_Request, byteBlock).ConfigureFalseAwait();
return true;
}
else
@@ -508,7 +595,7 @@ namespace ThingsGateway.Foundation.Dmtp
waitPing.Status = TouchSocketDmtpStatus.Success.ToValue();
}
waitPing.SwitchId();
this.SendJsonObject(P6_Ping_Response, waitPing);
await this.SendJsonObjectAsync(P6_Ping_Response, waitPing).ConfigureFalseAwait();
}
catch (Exception ex)
{
@@ -524,9 +611,9 @@ namespace ThingsGateway.Foundation.Dmtp
if (this.AllowRoute && waitPing.Route)
{
if (this.TryFindDmtpActor(waitPing.TargetId, out var actor))
if (await this.TryFindDmtpActor(waitPing.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(P6_Ping_Response, byteBlock);
await actor.SendAsync(P6_Ping_Response, byteBlock).ConfigureFalseAwait();
}
}
else
@@ -548,11 +635,11 @@ namespace ThingsGateway.Foundation.Dmtp
waitCreateChannel.UnpackageRouter(byteBlock);
if (this.AllowRoute && waitCreateChannel.Route)
{
if (this.TryRoute(RouteType.CreateChannel, waitCreateChannel))
if (await this.TryRoute(new PackageRouterEventArgs(RouteType.CreateChannel, waitCreateChannel)).ConfigureFalseAwait())
{
if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor))
if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(P7_CreateChannel_Request, byteBlock);
await actor.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait();
return true;
}
else
@@ -593,7 +680,7 @@ namespace ThingsGateway.Foundation.Dmtp
waitCreateChannel.SwitchId();
byteBlock.Reset();
waitCreateChannel.Package(byteBlock);
this.Send(P8_CreateChannel_Response, byteBlock);
await this.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait();
}
catch (Exception ex)
{
@@ -609,9 +696,9 @@ namespace ThingsGateway.Foundation.Dmtp
waitCreateChannel.UnpackageRouter(byteBlock);
if (this.AllowRoute && waitCreateChannel.Route)
{
if (this.TryFindDmtpActor(waitCreateChannel.TargetId, out var actor))
if (await this.TryFindDmtpActor(waitCreateChannel.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(P8_CreateChannel_Response, byteBlock);
await actor.SendAsync(P8_CreateChannel_Response, byteBlock).ConfigureFalseAwait();
return true;
}
}
@@ -635,9 +722,9 @@ namespace ThingsGateway.Foundation.Dmtp
channelPackage.UnpackageRouter(byteBlock);
if (this.AllowRoute && channelPackage.Route)
{
if (this.TryFindDmtpActor(channelPackage.TargetId, out var actor))
if (await this.TryFindDmtpActor(channelPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(P9_ChannelPackage, byteBlock);
await actor.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait();
}
else
{
@@ -648,7 +735,7 @@ namespace ThingsGateway.Foundation.Dmtp
channelPackage.DataType = ChannelDataType.DisposeOrder;
byteBlock.Reset();
channelPackage.Package(byteBlock);
this.Send(P9_ChannelPackage, byteBlock);
await this.SendAsync(P9_ChannelPackage, byteBlock).ConfigureFalseAwait();
}
}
else
@@ -683,7 +770,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public virtual bool Ping(string targetId, int timeout = 5000)
{
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
{
return actor.Ping(timeout);
}
@@ -697,15 +784,15 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public virtual Task<bool> PingAsync(string targetId, int timeout = 5000)
public virtual async Task<bool> PingAsync(string targetId, int timeout = 5000)
{
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
{
return actor.PingAsync(timeout);
return await actor.PingAsync(timeout).ConfigureFalseAwait();
}
else
{
return this.PrivatePingAsync(targetId, timeout);
return await this.PrivatePingAsync(targetId, timeout).ConfigureFalseAwait();
}
}
@@ -724,7 +811,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
if (waitData.WaitResult.Status == 1)
{
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id));
this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).GetFalseAwaitResult();
this.Id = id;
}
else
@@ -754,13 +841,13 @@ namespace ThingsGateway.Foundation.Dmtp
this.SendJsonObject(P3_ResetId_Request, waitSetId);
switch (await waitData.WaitAsync(5000))
switch (await waitData.WaitAsync(5000).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
if (waitData.WaitResult.Status == 1)
{
this.OnResetId?.Invoke(this, new WaitSetId(this.Id, id));
await this.OnIdChanged(new IdChangedEventArgs(this.Id, id)).ConfigureFalseAwait();
this.Id = id;
}
else
@@ -801,6 +888,17 @@ namespace ThingsGateway.Foundation.Dmtp
this.Send(protocol, bytes, 0, bytes.Length);
}
private Task SendJsonObjectAsync<T>(ushort protocol, in T obj)
{
#if NET6_0_OR_GREATER
var bytes = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj, typeof(T), TouchSokcetDmtpSourceGenerationContext.Default);
#else
var bytes = SerializeConvert.JsonSerializeToBytes(obj);
#endif
return this.SendAsync(protocol, bytes, 0, bytes.Length);
}
private T ResolveJsonObject<T>(string json)
{
#if NET6_0_OR_GREATER
@@ -836,31 +934,34 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public virtual bool TryFindDmtpActor(string targetId, out DmtpActor actor)
public virtual async Task<DmtpActor> TryFindDmtpActor(string targetId)
{
if (targetId == this.Id)
{
actor = this;
return true;
return this;
}
if (this.OnFindDmtpActor?.Invoke(targetId) is DmtpActor newActor)
if (this.FindDmtpActor != null)
{
actor = newActor;
return true;
if (await this.FindDmtpActor.Invoke(targetId).ConfigureFalseAwait() is DmtpActor newActor)
{
return newActor;
}
}
actor = default;
return false;
return default;
}
/// <inheritdoc/>
public virtual bool TryRoute(RouteType routerType, RouterPackage routerPackage)
public virtual async Task<bool> TryRoute(PackageRouterEventArgs e)
{
try
{
var args = new PackageRouterEventArgs(routerType, routerPackage);
this.OnRouting?.Invoke(this, args);
return args.IsPermitOperation;
if (this.Routing != null)
{
await this.Routing.Invoke(this, e).ConfigureFalseAwait();
return e.IsPermitOperation;
}
return false;
}
catch
{
@@ -868,27 +969,6 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
/// <inheritdoc/>
public virtual bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage)
{
try
{
var args = new PackageRouterEventArgs(routerType, routerPackage);
this.OnRouting?.Invoke(this, args);
routerPackage.Message = args.Message;
return args.IsPermitOperation;
}
catch
{
return false;
}
}
private void PrivateHandshaked(object obj)
{
this.OnHandshaked?.Invoke(this, (DmtpVerifyEventArgs)obj);
}
private bool PrivatePing(string targetId, int timeout)
{
var waitPing = new WaitPing
@@ -942,7 +1022,7 @@ namespace ThingsGateway.Foundation.Dmtp
try
{
this.SendJsonObject(P5_Ping_Request, waitPing);
switch (await waitData.WaitAsync(timeout))
switch (await waitData.WaitAsync(timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -979,16 +1059,15 @@ namespace ThingsGateway.Foundation.Dmtp
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
this.OnClose = null;
this.OnRouting = null;
this.OnFindDmtpActor = null;
this.OnHandshaked = null;
this.OnHandshaking = null;
this.OnResetId = null;
this.Closed = null;
this.Routing = null;
this.FindDmtpActor = null;
this.Handshaked = null;
this.Handshaking = null;
this.IdChanged = null;
this.OutputSend = null;
this.OnClosed(true, nameof(Dispose));
this.WaitHandlePool.SafeDispose();
this.Close(false, nameof(Dispose));
base.Dispose(disposing);
}
@@ -1005,7 +1084,7 @@ namespace ThingsGateway.Foundation.Dmtp
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
};
this.OutputSend?.Invoke(this, transferBytes);
this.OutputSend.Invoke(this, transferBytes);
this.LastActiveTime = DateTime.Now;
}
@@ -1022,10 +1101,20 @@ namespace ThingsGateway.Foundation.Dmtp
/// <inheritdoc/>
public virtual Task SendAsync(ushort protocol, byte[] buffer, int offset, int length)
{
return Task.Run(() =>
var transferBytes = new ArraySegment<byte>[]
{
this.Send(protocol, buffer, offset, length);
});
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(protocol)),
new ArraySegment<byte>(TouchSocketBitConverter.BigEndian.GetBytes(length)),
new ArraySegment<byte>(buffer,offset,length)
};
this.LastActiveTime = DateTime.Now;
return this.OutputSendAsync.Invoke(this, transferBytes);
}
/// <inheritdoc/>
public virtual Task SendAsync(ushort protocol, ByteBlock byteBlock)
{
return this.SendAsync(protocol, byteBlock.Buffer, 0, byteBlock.Len);
}
#endregion
@@ -1059,7 +1148,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
}
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
{
return actor.CreateChannel(id, metadata);
}
@@ -1077,7 +1166,7 @@ namespace ThingsGateway.Foundation.Dmtp
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
}
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && this.TryFindDmtpActor(targetId).GetFalseAwaitResult() is DmtpActor actor)
{
return actor.CreateChannel(metadata);
}
@@ -1100,37 +1189,37 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default)
public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, int id, Metadata metadata = default)
{
if (string.IsNullOrEmpty(targetId))
{
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
}
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
{
return actor.CreateChannelAsync(id, metadata);
return await actor.CreateChannelAsync(id, metadata).ConfigureFalseAwait();
}
else
{
return this.PrivateCreateChannelAsync(targetId, false, id, metadata);
return await this.PrivateCreateChannelAsync(targetId, false, id, metadata).ConfigureFalseAwait();
}
}
/// <inheritdoc/>
public virtual Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default)
public virtual async Task<IDmtpChannel> CreateChannelAsync(string targetId, Metadata metadata = default)
{
if (string.IsNullOrEmpty(targetId))
{
throw new ArgumentException($"“{nameof(targetId)}”不能为 null 或空。", nameof(targetId));
}
if (this.AllowRoute && this.TryFindDmtpActor(targetId, out var actor))
if (this.AllowRoute && await this.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor actor)
{
return actor.CreateChannelAsync(metadata);
return await actor.CreateChannelAsync(metadata).ConfigureFalseAwait();
}
else
{
return this.PrivateCreateChannelAsync(targetId, true, 0, metadata);
return await this.PrivateCreateChannelAsync(targetId, true, 0, metadata).ConfigureFalseAwait();
}
}
@@ -1208,9 +1297,14 @@ namespace ThingsGateway.Foundation.Dmtp
var channel = new InternalChannel(this, targetId, result.Metadata);
channel.SetId(result.ChannelId);
channel.SetUsing();
return this.m_userChannels.TryAdd(result.ChannelId, channel)
? (IDmtpChannel)channel
: throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
if (this.m_userChannels.TryAdd(result.ChannelId, channel))
{
return channel;
}
else
{
throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
}
}
case TouchSocketDmtpStatus.ClientNotFind:
{
@@ -1269,8 +1363,8 @@ namespace ThingsGateway.Foundation.Dmtp
try
{
waitCreateChannel.Package(byteBlock);
this.Send(P7_CreateChannel_Request, byteBlock);
switch (await waitData.WaitAsync(10 * 1000))
await this.SendAsync(P7_CreateChannel_Request, byteBlock).ConfigureFalseAwait();
switch (await waitData.WaitAsync(10 * 1000).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -1282,9 +1376,14 @@ namespace ThingsGateway.Foundation.Dmtp
var channel = new InternalChannel(this, targetId, result.Metadata);
channel.SetId(result.ChannelId);
channel.SetUsing();
return this.m_userChannels.TryAdd(result.ChannelId, channel)
? (IDmtpChannel)channel
: throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
if (this.m_userChannels.TryAdd(result.ChannelId, channel))
{
return channel;
}
else
{
throw new Exception(TouchSocketDmtpStatus.UnknownError.GetDescription());
}
}
case TouchSocketDmtpStatus.ClientNotFind:
{
@@ -1333,7 +1432,7 @@ namespace ThingsGateway.Foundation.Dmtp
channel.SetId(id);
if (this.m_userChannels.TryAdd(id, channel))
{
Task.Factory.StartNew(this.ThisRequestCreateChannel, new CreateChannelEventArgs(id, metadata));
Task.Factory.StartNew(this.PrivateOnCreatedChannel, new CreateChannelEventArgs(id, metadata));
return true;
}
else
@@ -1344,16 +1443,6 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
private void ThisRequestCreateChannel(object state)
{
try
{
this.OnCreateChannel?.Invoke(this, (CreateChannelEventArgs)state);
}
catch
{
}
}
#endregion IDmtpChannel
}

View File

@@ -152,9 +152,8 @@ namespace ThingsGateway.Foundation.Dmtp
/// <summary>
/// 关闭
/// </summary>
/// <param name="sendClose">是否发送close报文</param>
/// <param name="message">传递消息</param>
void Close(bool sendClose, string message);
void Close(string message);
/// <summary>
/// 向当前对点发送一个Ping报文并且等待回应。
@@ -226,6 +225,14 @@ namespace ThingsGateway.Foundation.Dmtp
/// <param name="length"></param>
Task SendAsync(ushort protocol, byte[] buffer, int offset, int length);
/// <summary>
/// 异步发送字节块
/// </summary>
/// <param name="protocol"></param>
/// <param name="byteBlock"></param>
/// <returns></returns>
Task SendAsync(ushort protocol, ByteBlock byteBlock);
/// <summary>
/// 以Fast序列化发送小64K对象。接收方需要使用ReadObject读取对象。
/// </summary>
@@ -260,25 +267,20 @@ namespace ThingsGateway.Foundation.Dmtp
/// 尝试获取指定Id的DmtpActor。一般此方法仅在Service下有效。
/// </summary>
/// <param name="targetId"></param>
/// <param name="actor"></param>
/// <returns></returns>
bool TryFindDmtpActor(string targetId, out DmtpActor actor);
Task<DmtpActor> TryFindDmtpActor(string targetId);
/// <summary>
/// 尝试请求路由,触发路由相关插件。
/// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgPermitEventArgs.Message"/>中传递消息。
/// </summary>
/// <param name="routerType"></param>
/// <param name="routerPackage"></param>
/// <returns></returns>
bool TryRoute(RouteType routerType, RouterPackage routerPackage);
Task<bool> TryRoute(PackageRouterEventArgs e);
/// <summary>
/// 尝试请求路由,触发路由相关插件。并在路由失败时向<see cref="MsgRouterPackage.Message"/>中传递消息。
/// 发送Close请求
/// </summary>
/// <param name="routerType"></param>
/// <param name="routerPackage"></param>
/// <returns></returns>
bool TryRoute(RouteType routerType, WaitRouterPackage routerPackage);
/// <param name="msg"></param>
bool SendClose(string msg);
#endregion
}

View File

@@ -10,6 +10,12 @@
//------------------------------------------------------------------------------
#endregion
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -17,17 +23,22 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
public class TcpDmtpAdapter : CustomFixedHeaderByteBlockDataHandlingAdapter<DmtpMessage>
{
private SpinLock m_locker = new SpinLock();
private readonly SemaphoreSlim m_locker = new SemaphoreSlim(1, 1);
/// <inheritdoc/>
public override bool CanSendRequestInfo => true;
/// <inheritdoc/>
public override bool CanSplicingSend => false;
public override bool CanSplicingSend => true;
/// <inheritdoc/>
public override int HeaderLength => 6;
/// <summary>
/// 最大拼接
/// </summary>
public const int MaxSplicing = 1024 * 64;
/// <inheritdoc/>
protected override DmtpMessage GetInstance()
{
@@ -40,6 +51,25 @@ namespace ThingsGateway.Foundation.Dmtp
request.SafeDispose();
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(IRequestInfo requestInfo)
{
if (!(requestInfo is DmtpMessage message))
{
throw new Exception($"无法将{nameof(requestInfo)}转换为{nameof(DmtpMessage)}");
}
if (message.BodyByteBlock != null && message.BodyByteBlock.Length > this.MaxPackageSize)
{
throw new Exception("发送的BodyLength={requestInfo.BodyLength},大于设定的MaxPackageSize={this.MaxPackageSize}");
}
using (var byteBlock = new ByteBlock(message.GetLength()))
{
message.Build(byteBlock);
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
}
/// <inheritdoc/>
protected override void PreviewSend(IRequestInfo requestInfo)
{
@@ -58,6 +88,54 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
/// <inheritdoc/>
protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes)
{
if (transferBytes.Count == 0)
{
return;
}
var length = 0;
foreach (var item in transferBytes)
{
length += item.Count;
}
if (length > this.MaxPackageSize)
{
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
if (length > this.MaxPackageSize)
{
try
{
await this.m_locker.WaitAsync();
foreach (var item in transferBytes)
{
await this.GoSendAsync(item.Array, item.Offset, item.Count);
}
}
finally
{
this.m_locker.Release();
}
}
else
{
using (var byteBlock = new ByteBlock(length))
{
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len);
}
}
}
/// <inheritdoc/>
protected override void PreviewSend(IList<ArraySegment<byte>> transferBytes)
{
@@ -77,20 +155,31 @@ namespace ThingsGateway.Foundation.Dmtp
throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送");
}
var lockTaken = false;
try
if (length > this.MaxPackageSize)
{
this.m_locker.Enter(ref lockTaken);
foreach (var item in transferBytes)
try
{
this.GoSend(item.Array, item.Offset, item.Count);
this.m_locker.Wait();
foreach (var item in transferBytes)
{
this.GoSend(item.Array, item.Offset, item.Count);
}
}
finally
{
this.m_locker.Release();
}
}
finally
else
{
if (lockTaken)
using (var byteBlock = new ByteBlock(length))
{
this.m_locker.Exit(false);
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.GoSend(byteBlock.Buffer, 0, byteBlock.Len);
}
}
}

View File

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

View File

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

View File

@@ -33,8 +33,8 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private bool m_allowRoute;
private Func<string, IDmtpActor> m_findDmtpActor;
private DmtpActor m_smtpActor;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
private DmtpActor m_dmtpActor;
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
#endregion
@@ -45,7 +45,7 @@ namespace ThingsGateway.Foundation.Dmtp
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
#region
@@ -78,7 +78,7 @@ namespace ThingsGateway.Foundation.Dmtp
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
return this;
@@ -114,7 +114,7 @@ namespace ThingsGateway.Foundation.Dmtp
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
@@ -156,7 +156,7 @@ namespace ThingsGateway.Foundation.Dmtp
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
return this;
@@ -184,7 +184,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
if (!this.Online)
{
await base.ConnectAsync(timeout, token);
await base.ConnectAsync(timeout);
}
var request = new HttpRequest()
@@ -197,7 +197,7 @@ namespace ThingsGateway.Foundation.Dmtp
if (response.StatusCode == 101)
{
this.SwitchProtocolToDmtp();
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
@@ -215,19 +215,44 @@ namespace ThingsGateway.Foundation.Dmtp
#endregion
#region
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.DmtpActor.SafeDispose();
this.m_dmtpActor?.SafeDispose();
base.Dispose(disposing);
}
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public override void Close(string msg = "")
{
if (this.m_dmtpActor != null)
{
this.m_dmtpActor.SendClose(msg);
this.m_dmtpActor.Close(msg);
}
base.Close(msg);
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.m_dmtpActor?.Close(e.Message);
await base.OnDisconnected(e);
}
#endregion
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
{
if (!this.m_smtpActor.InputReceivedData(message))
if (!await this.m_dmtpActor.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
{
@@ -250,25 +275,19 @@ namespace ThingsGateway.Foundation.Dmtp
}
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
await base.OnDisconnected(e);
this.DmtpActor.Close(false, e.Message);
}
#region ResetId
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
public void ResetId(string id)
{
this.m_smtpActor.ResetId(id);
this.m_dmtpActor.ResetId(id);
}
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
public Task ResetIdAsync(string newId)
{
return this.m_smtpActor.ResetIdAsync(newId);
return this.m_dmtpActor.ResetIdAsync(newId);
}
#endregion ResetId
@@ -277,72 +296,47 @@ namespace ThingsGateway.Foundation.Dmtp
{
this.Protocol = DmtpUtility.DmtpProtocol;
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute)
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
{
OutputSend = DmtpActorSend,
OnRouting = OnDmtpActorRouting,
OnHandshaking = this.OnDmtpActorHandshaking,
OnHandshaked = OnDmtpActorHandshaked,
OnClose = OnDmtpActorClose,
OnCreateChannel = this.OnDmtpActorCreateChannel,
OutputSend = this.DmtpActorSend,
OutputSendAsync = this.DmtpActorSendAsync,
Routing = this.OnDmtpActorRouting,
Handshaking = this.OnDmtpActorHandshaking,
Handshaked = this.OnDmtpActorHandshaked,
Closed = OnDmtpActorClose,
CreatedChannel = this.OnDmtpActorCreateChannel,
Logger = this.Logger,
Client = this,
OnFindDmtpActor = this.m_findDmtpActor
FindDmtpActor = this.m_findDmtpActor
};
}
#region
private void OnDmtpActorClose(DmtpActor actor, string msg)
private Task OnDmtpActorClose(DmtpActor actor, string msg)
{
base.Close(msg);
base.BreakOut(false, msg);
return EasyTask.CompletedTask;
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.OnCreateChannel(e);
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
return this.OnHandshaked(e);
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
return this.OnHandshaking(e);
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
this.OnRouting(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
return this.OnRouting(e);
}
private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
@@ -350,6 +344,11 @@ namespace ThingsGateway.Foundation.Dmtp
base.Send(transferBytes);
}
private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
return base.SendAsync(transferBytes);
}
#endregion
#region
@@ -358,32 +357,53 @@ namespace ThingsGateway.Foundation.Dmtp
/// 当创建通道
/// </summary>
/// <param name="e"></param>
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
/// 在完成握手连接时
/// </summary>
/// <param name="e"></param>
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
/// 即将握手连接时
/// </summary>
/// <param name="e">参数</param>
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
/// 当需要转发路由包时
/// </summary>
/// <param name="e"></param>
protected virtual void OnRouting(PackageRouterEventArgs e)
protected virtual async Task OnRouting(PackageRouterEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

@@ -46,7 +46,7 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private bool m_allowRoute;
private Func<string, IDmtpActor> m_findDmtpActor;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
#endregion
@@ -68,17 +68,28 @@ namespace ThingsGateway.Foundation.Dmtp
await base.OnConnected(socketClient, e);
}
private IDmtpActor OnServiceFindDmtpActor(string id)
{
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
}
private DmtpActor PrivateOnRpcActorInit()
{
return new SealedDmtpActor(this.m_allowRoute)
{
OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null
FindDmtpActor = this.FindDmtpActor
};
}
private async Task<IDmtpActor> FindDmtpActor(string id)
{
if (this.m_allowRoute)
{
if (this.m_findDmtpActor != null)
{
return await this.m_findDmtpActor.Invoke(id);
}
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
}
else
{
return null;
}
}
}
}

View File

@@ -31,14 +31,14 @@ namespace ThingsGateway.Foundation.Dmtp
public class HttpDmtpSocketClient : HttpSocketClient, IHttpDmtpSocketClient
{
internal Func<DmtpActor> m_internalOnRpcActorInit;
private DmtpActor m_smtpActor;
private DmtpActor m_dmtpActor;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc/>
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
/// <summary>
/// 验证超时时间,默认为3000ms
/// </summary>
@@ -49,97 +49,67 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
public string VerifyToken => this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty);
#region
/// <inheritdoc/>
public override void Close(string msg = "")
{
if (this.m_smtpActor == null)
if (this.m_dmtpActor != null)
{
base.Close(msg);
return;
this.m_dmtpActor.SendClose(msg);
this.m_dmtpActor.Close(msg);
}
this.m_smtpActor.Close(true, msg);
base.Close(msg);
}
#region ResetId
/// <inheritdoc cref="IDmtpActor.ResetId(string)"/>
public override void ResetId(string newId)
{
if (this.m_smtpActor == null)
{
base.ResetId(newId);
return;
}
this.m_smtpActor.ResetId(newId);
}
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
public async Task ResetIdAsync(string newId)
{
if (this.m_smtpActor == null)
{
base.ResetId(newId);
return;
}
await this.m_smtpActor.ResetIdAsync(newId);
}
#endregion ResetId
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
this.DmtpActor?.SafeDispose();
this.m_dmtpActor?.SafeDispose();
base.Dispose(disposing);
}
///// <inheritdoc/>
//protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
//{
// if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message)
// {
// if (!this.m_smtpActor.InputReceivedData(message))
// {
// if (this.PluginsManager.Enable)
// {
// this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
// }
// }
// return false;
// }
// else
// {
// return base.HandleReceivedData(byteBlock, requestInfo);
// }
//}
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
{
if (!this.m_smtpActor.InputReceivedData(message))
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
await base.ReceivedData(e);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="e"></param>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.DmtpActor?.Close(false, e.Message);
this.m_dmtpActor?.Close(e.Message);
await base.OnDisconnected(e);
}
#endregion
#region ResetId
/// <inheritdoc cref="IDmtpActor.ResetId(string)"/>
public override void ResetId(string newId)
{
if (this.m_dmtpActor == null)
{
base.ResetId(newId);
return;
}
this.m_dmtpActor.ResetId(newId);
}
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
public async Task ResetIdAsync(string newId)
{
if (this.m_dmtpActor == null)
{
base.ResetId(newId);
return;
}
await this.m_dmtpActor.ResetIdAsync(newId);
}
#endregion ResetId
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -158,66 +128,73 @@ namespace ThingsGateway.Foundation.Dmtp
await base.OnReceivedHttpRequest(request);
}
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message)
{
if (!await this.m_dmtpActor.InputReceivedData(message))
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
}
await base.ReceivedData(e);
}
private Task OnDmtpIdChanged(DmtpActor actor, IdChangedEventArgs e)
{
this.DirectResetId(e.NewId);
return EasyTask.CompletedTask;
}
private void SetRpcActor(DmtpActor actor)
{
actor.Id = this.Id;
actor.OnResetId = this.ThisOnResetId;
actor.IdChanged = this.OnDmtpIdChanged;
actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync;
actor.OutputSend = this.ThisDmtpActorOutputSend;
actor.Client = this;
actor.OnClose = this.OnDmtpActorClose;
actor.OnRouting = this.OnDmtpActorRouting;
actor.OnHandshaked = this.OnDmtpActorHandshaked;
actor.OnHandshaking = this.OnDmtpActorHandshaking;
actor.OnCreateChannel = this.OnDmtpActorCreateChannel;
actor.Closed = this.OnDmtpActorClose;
actor.Routing = this.OnDmtpActorRouting;
actor.Handshaked = this.OnDmtpActorHandshaked;
actor.Handshaking = this.OnDmtpActorHandshaking;
actor.CreatedChannel = this.OnDmtpActorCreatedChannel;
actor.Logger = this.Logger;
this.m_smtpActor = actor;
this.m_dmtpActor = actor;
this.Protocol = DmtpUtility.DmtpProtocol;
this.SetDataHandlingAdapter(new TcpDmtpAdapter());
}
private void ThisOnResetId(DmtpActor actor, WaitSetId waitSetId)
{
this.DirectResetId(waitSetId.NewId);
}
private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
base.Send(transferBytes);
}
private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
return base.SendAsync(transferBytes);
}
#region
private void OnDmtpActorClose(DmtpActor actor, string msg)
private Task OnDmtpActorClose(DmtpActor actor, string msg)
{
base.Close(msg);
base.BreakOut(false, msg);
return EasyTask.CompletedTask;
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.OnCreatedChannel(e);
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
return this.OnHandshaked(e);
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
if (e.Token == this.VerifyToken)
{
@@ -228,25 +205,12 @@ namespace ThingsGateway.Foundation.Dmtp
e.Message = "Token不受理";
}
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
return this.OnHandshaking(e);
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
this.OnRouting(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
return this.OnRouting(e);
}
#endregion
@@ -257,32 +221,53 @@ namespace ThingsGateway.Foundation.Dmtp
/// 当创建通道
/// </summary>
/// <param name="e"></param>
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
/// 在完成握手连接时
/// </summary>
/// <param name="e"></param>
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
/// 在验证Token时
/// </summary>
/// <param name="e">参数</param>
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
/// 在需要转发路由包时。
/// </summary>
/// <param name="e"></param>
protected virtual void OnRouting(PackageRouterEventArgs e)
protected virtual async Task OnRouting(PackageRouterEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

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

View File

@@ -39,7 +39,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc cref="IDmtpActor.Id"/>
public string Id => this.DmtpActor.Id;
@@ -48,14 +48,16 @@ namespace ThingsGateway.Foundation.Dmtp
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
private bool m_allowRoute;
private Func<string, IDmtpActor> m_findDmtpActor;
private SealedDmtpActor m_smtpActor;
private SealedDmtpActor m_dmtpActor;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
#endregion
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
#region
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
/// </summary>
@@ -63,10 +65,27 @@ namespace ThingsGateway.Foundation.Dmtp
/// <returns></returns>
public override void Close(string msg = "")
{
this.DmtpActor.Close(true, msg);
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
base.Close(msg);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_dmtpActor?.SafeDispose();
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.m_dmtpActor?.Close(e.Message);
await base.OnDisconnected(e).ConfigureFalseAwait();
}
#endregion
#region
/// <summary>
@@ -87,7 +106,7 @@ namespace ThingsGateway.Foundation.Dmtp
base.Connect(timeout);
}
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
return this;
}
@@ -107,7 +126,7 @@ namespace ThingsGateway.Foundation.Dmtp
base.Connect(timeout);
}
this.m_smtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
return this;
}
@@ -129,11 +148,10 @@ namespace ThingsGateway.Foundation.Dmtp
}
if (!this.Online)
{
await base.ConnectAsync(timeout);
await base.ConnectAsync(timeout).ConfigureFalseAwait();
}
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None).ConfigureFalseAwait();
return this;
}
finally
@@ -154,11 +172,10 @@ namespace ThingsGateway.Foundation.Dmtp
}
if (!this.Online)
{
await base.ConnectAsync(timeout, token);
await base.ConnectAsync(timeout).ConfigureFalseAwait();
}
await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token);
await this.m_dmtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty), timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), token).ConfigureFalseAwait();
return this;
}
finally
@@ -174,13 +191,13 @@ namespace ThingsGateway.Foundation.Dmtp
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
public void ResetId(string id)
{
this.m_smtpActor.ResetId(id);
this.m_dmtpActor.ResetId(id);
}
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
public Task ResetIdAsync(string newId)
{
return this.m_smtpActor.ResetIdAsync(newId);
return this.m_dmtpActor.ResetIdAsync(newId);
}
#endregion ResetId
@@ -229,13 +246,6 @@ namespace ThingsGateway.Foundation.Dmtp
#endregion
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.DmtpActor.SafeDispose();
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override void LoadConfig(TouchSocketConfig config)
{
@@ -246,37 +256,31 @@ namespace ThingsGateway.Foundation.Dmtp
this.m_allowRoute = true;
this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor;
}
this.m_smtpActor = new SealedDmtpActor(this.m_allowRoute)
this.m_dmtpActor = new SealedDmtpActor(this.m_allowRoute)
{
OutputSend = this.DmtpActorSend,
OnRouting = this.OnDmtpActorRouting,
OnHandshaking = this.OnDmtpActorHandshaking,
OnHandshaked = this.OnDmtpActorHandshaked,
OnClose = this.OnDmtpActorClose,
OutputSendAsync = this.DmtpActorSendAsync,
Routing = this.OnDmtpActorRouting,
Handshaking = this.OnDmtpActorHandshaking,
Handshaked = this.OnDmtpActorHandshaked,
Closed = this.OnDmtpActorClose,
Logger = this.Logger,
Client = this,
OnFindDmtpActor = this.m_findDmtpActor,
OnCreateChannel = this.OnDmtpActorCreateChannel
FindDmtpActor = this.m_findDmtpActor,
CreatedChannel = this.OnDmtpActorCreateChannel
};
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
await base.OnDisconnected(e);
this.DmtpActor.Close(false, e.Message);
}
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
var message = (DmtpMessage)e.RequestInfo;
if (!this.m_smtpActor.InputReceivedData(message))
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
await base.ReceivedData(e);
await base.ReceivedData(e).ConfigureFalseAwait();
}
#region
@@ -286,52 +290,35 @@ namespace ThingsGateway.Foundation.Dmtp
base.Send(transferBytes);
}
private void OnDmtpActorClose(DmtpActor actor, string msg)
private Task DmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
base.Close(msg);
return base.SendAsync(transferBytes);
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorClose(DmtpActor actor, string msg)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
this.BreakOut(false, msg);
return EasyTask.CompletedTask;
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
return this.OnCreatedChannel(e);
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
return this.OnHandshaked(e);
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
this.OnRouting(e);
return this.OnHandshaking(e);
}
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
return this.OnRouting(e);
}
#endregion
@@ -342,32 +329,53 @@ namespace ThingsGateway.Foundation.Dmtp
/// 当创建通道
/// </summary>
/// <param name="e"></param>
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
protected virtual async Task OnCreatedChannel(CreateChannelEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 在完成握手连接时
/// </summary>
/// <param name="e"></param>
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 即将握手连接时
/// </summary>
/// <param name="e">参数</param>
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 当需要转发路由包时
/// </summary>
/// <param name="e"></param>
protected virtual void OnRouting(PackageRouterEventArgs e)
protected virtual async Task OnRouting(PackageRouterEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e).ConfigureFalseAwait();
}
#endregion

View File

@@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private bool m_allowRoute;
private Func<string, IDmtpActor> m_findDmtpActor;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
#endregion
@@ -73,14 +73,25 @@ namespace ThingsGateway.Foundation.Dmtp
socketClient.SetDmtpActor(new SealedDmtpActor(this.m_allowRoute)
{
Id = e.Id,
OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null
FindDmtpActor = this.FindDmtpActor
});
await base.OnConnecting(socketClient, e);
}
private IDmtpActor OnServiceFindDmtpActor(string id)
private async Task<IDmtpActor> FindDmtpActor(string id)
{
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
if (this.m_allowRoute)
{
if (this.m_findDmtpActor != null)
{
return await this.m_findDmtpActor.Invoke(id);
}
return this.TryGetSocketClient(id, out var client) ? client.DmtpActor : null;
}
else
{
return null;
}
}
}
}

View File

@@ -30,7 +30,7 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
public partial class TcpDmtpSocketClient : SocketClient, ITcpDmtpSocketClient
{
private DmtpActor m_smtpActor;
private DmtpActor m_dmtpActor;
/// <summary>
/// TcpDmtpSocketClient
@@ -41,7 +41,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
/// <inheritdoc/>
public IDmtpActor DmtpActor { get => this.m_smtpActor; }
public IDmtpActor DmtpActor { get => this.m_dmtpActor; }
/// <inheritdoc cref="IDmtpActor.IsHandshaked"/>
public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked;
@@ -58,36 +58,23 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private void OnDmtpActorClose(DmtpActor actor, string msg)
private Task OnDmtpActorClose(DmtpActor actor, string msg)
{
base.Close(msg);
base.BreakOut(false, msg);
return EasyTask.CompletedTask;
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.OnCreateChannel(e);
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
return this.OnHandshaked(e);
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
private async Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
if (e.Token == this.VerifyToken)
{
@@ -98,25 +85,12 @@ namespace ThingsGateway.Foundation.Dmtp
e.Message = "Token不受理";
}
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
await this.OnHandshaking(e).ConfigureFalseAwait();
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
this.OnRouting(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
return this.OnRouting(e);
}
#endregion
@@ -127,99 +101,138 @@ namespace ThingsGateway.Foundation.Dmtp
/// 当创建通道
/// </summary>
/// <param name="e"></param>
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 在完成握手连接时
/// </summary>
/// <param name="e"></param>
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 在验证Token时
/// </summary>
/// <param name="e">参数</param>
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e).ConfigureFalseAwait();
}
/// <summary>
/// 在需要转发路由包时。
/// </summary>
/// <param name="e"></param>
protected virtual void OnRouting(PackageRouterEventArgs e)
protected virtual async Task OnRouting(PackageRouterEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion
/// <inheritdoc/>
#region
/// <summary>
/// 发送<see cref="IDmtpActor"/>关闭消息。
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public override void Close(string msg = "")
{
this.m_smtpActor.Close(true, msg);
this.m_dmtpActor?.SendClose(msg);
this.m_dmtpActor?.Close(msg);
base.Close(msg);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_dmtpActor?.SafeDispose();
base.Dispose(disposing);
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.m_dmtpActor?.Close(e.Message);
await base.OnDisconnected(e).ConfigureFalseAwait();
}
#endregion
#region ResetId
///<inheritdoc cref="IDmtpActor.ResetId(string)"/>
public override void ResetId(string id)
{
this.m_smtpActor.ResetId(id);
this.m_dmtpActor.ResetId(id);
}
///<inheritdoc cref="IDmtpActor.ResetIdAsync(string)"/>
public Task ResetIdAsync(string newId)
{
return this.m_smtpActor.ResetIdAsync(newId);
return this.m_dmtpActor.ResetIdAsync(newId);
}
#endregion ResetId
internal void SetDmtpActor(DmtpActor actor)
{
actor.OnResetId = this.ThisOnResetId;
actor.IdChanged = this.ThisOnResetId;
actor.OutputSend = this.ThisDmtpActorOutputSend;
actor.OutputSendAsync = this.ThisDmtpActorOutputSendAsync;
actor.Client = this;
actor.OnClose = this.OnDmtpActorClose;
actor.OnRouting = this.OnDmtpActorRouting;
actor.OnHandshaked = this.OnDmtpActorHandshaked;
actor.OnHandshaking = this.OnDmtpActorHandshaking;
actor.OnCreateChannel = this.OnDmtpActorCreateChannel;
actor.Closed = this.OnDmtpActorClose;
actor.Routing = this.OnDmtpActorRouting;
actor.Handshaked = this.OnDmtpActorHandshaked;
actor.Handshaking = this.OnDmtpActorHandshaking;
actor.CreatedChannel = this.OnDmtpActorCreateChannel;
actor.Logger = this.Logger;
this.m_smtpActor = actor;
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.DmtpActor.SafeDispose();
base.Dispose(disposing);
this.m_dmtpActor = actor;
}
/// <inheritdoc/>
protected override async Task ReceivedData(ReceivedDataEventArgs e)
{
var message = (DmtpMessage)e.RequestInfo;
if (!this.m_smtpActor.InputReceivedData(message))
if (!await this.m_dmtpActor.InputReceivedData(message).ConfigureFalseAwait())
{
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)).ConfigureFalseAwait();
}
await base.ReceivedData(e);
await base.ReceivedData(e).ConfigureFalseAwait();
}
/// <inheritdoc/>
protected override async Task OnConnected(ConnectedEventArgs e)
{
this.m_smtpActor.Id = this.Id;
await base.OnConnected(e);
this.m_dmtpActor.Id = this.Id;
await base.OnConnected(e).ConfigureFalseAwait();
_ = Task.Run(async () =>
{
await Task.Delay(this.VerifyTimeout);
await Task.Delay(this.VerifyTimeout).ConfigureFalseAwait();
if (!this.IsHandshaked)
{
this.TryShutdown();
@@ -228,21 +241,20 @@ namespace ThingsGateway.Foundation.Dmtp
});
}
/// <inheritdoc/>
protected override async Task OnDisconnected(DisconnectEventArgs e)
{
this.DmtpActor.Close(false, e.Message);
await base.OnDisconnected(e);
}
private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
base.Send(transferBytes);
}
private void ThisOnResetId(DmtpActor rpcActor, WaitSetId waitSetId)
private Task ThisDmtpActorOutputSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
this.DirectResetId(waitSetId.NewId);
return base.SendAsync(transferBytes);
}
private Task ThisOnResetId(DmtpActor rpcActor, IdChangedEventArgs e)
{
this.DirectResetId(e.NewId);
return EasyTask.CompletedTask;
}
#region

View File

@@ -84,7 +84,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
var message = DmtpMessage.CreateFrom(e.ByteBlock);
if (!client.InputReceivedData(message))
if (!await client.InputReceivedData(message))
{
if (this.PluginsManager.Enable)
{

View File

@@ -22,7 +22,11 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Net;
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Sockets;
namespace ThingsGateway.Foundation.Dmtp.Rpc
{
@@ -45,16 +49,17 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
this.Id = endPoint.ToString();
this.OutputSend = this.RpcActorSend;
this.OnCreateChannel = this.OnDmtpActorCreateChannel;
this.OutputSendAsync = this.RpcActorSendAsync;
this.CreatedChannel = this.OnDmtpActorCreatedChannel;
this.m_udpSession = udpSession;
this.m_endPoint = endPoint;
this.Logger = logger;
this.Client = this;
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorCreatedChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.pluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.pluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
public bool Created(IPluginsManager pluginsManager)
@@ -117,5 +122,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
this.m_udpSession.Send(this.m_endPoint, transferBytes);
}
private Task RpcActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
return this.m_udpSession.SendAsync(this.m_endPoint, transferBytes);
}
}
}

View File

@@ -22,7 +22,12 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
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
{
@@ -50,15 +55,16 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1);
private readonly SemaphoreSlim m_semaphoreForSend = new SemaphoreSlim(1, 1);
private ClientWebSocket m_client;
private SealedDmtpActor m_dmtpActor;
private Func<string, IDmtpActor> m_findDmtpActor;
private Func<string, Task<IDmtpActor>> m_findDmtpActor;
private int m_receiveBufferSize = 1024 * 10;
private ValueCounter m_receiveCounter;
private int m_sendBufferSize = 1024 * 10;
private ValueCounter m_sendCounter;
private TcpDmtpAdapter m_smtpAdapter;
private TcpDmtpAdapter m_dmtpAdapter;
#endregion
@@ -115,56 +121,15 @@ namespace ThingsGateway.Foundation.Dmtp
/// <returns></returns>
public void Close(string msg = "")
{
this.DmtpActor.Close(true, msg);
this.m_dmtpActor.SendClose(msg);
this.m_dmtpActor.Close(msg);
this.PrivateClose(msg);
}
/// <inheritdoc/>
public async Task ConnectAsync(int timeout = 5000)
public Task ConnectAsync(int timeout = 5000)
{
try
{
await this.m_semaphore.WaitAsync();
if (this.IsHandshaked)
{
return;
}
if (this.m_client == null || this.m_client.State != WebSocketState.Open)
{
this.m_client.SafeDispose();
this.m_client = new ClientWebSocket();
await this.m_client.ConnectAsync(this.RemoteIPHost, default);
this.m_dmtpActor = new SealedDmtpActor(false)
{
OutputSend = this.OnDmtpActorSend,
OnRouting = this.OnDmtpActorRouting,
OnHandshaking = this.OnDmtpActorHandshaking,
OnHandshaked = this.OnDmtpActorHandshaked,
OnClose = this.OnDmtpActorClose,
Logger = this.Logger,
Client = this,
OnFindDmtpActor = this.m_findDmtpActor,
OnCreateChannel = this.OnDmtpActorCreateChannel
};
this.m_smtpAdapter = new TcpDmtpAdapter()
{
ReceivedCallBack = this.PrivateHandleReceivedData
};
_ = this.BeginReceive();
}
this.m_dmtpActor.Handshake(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty),
this.Config.GetValue(DmtpConfigExtension.DefaultIdProperty),
timeout, this.Config.GetValue(DmtpConfigExtension.MetadataProperty), CancellationToken.None);
this.IsHandshaked = true;
}
finally
{
this.m_semaphore.Release();
}
return this.ConnectAsync(CancellationToken.None, timeout);
}
/// <inheritdoc/>
@@ -172,7 +137,7 @@ namespace ThingsGateway.Foundation.Dmtp
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForConnect.WaitAsync();
if (this.IsHandshaked)
{
return;
@@ -187,17 +152,18 @@ namespace ThingsGateway.Foundation.Dmtp
this.m_dmtpActor = new SealedDmtpActor(false)
{
OutputSend = this.OnDmtpActorSend,
OnRouting = this.OnDmtpActorRouting,
OnHandshaking = this.OnDmtpActorHandshaking,
OnHandshaked = this.OnDmtpActorHandshaked,
OnClose = this.OnDmtpActorClose,
OutputSendAsync = this.OnDmtpActorSendAsync,
Routing = this.OnDmtpActorRouting,
Handshaking = this.OnDmtpActorHandshaking,
Handshaked = this.OnDmtpActorHandshaked,
Closed = this.OnDmtpActorClose,
Logger = this.Logger,
Client = this,
OnFindDmtpActor = this.m_findDmtpActor,
OnCreateChannel = this.OnDmtpActorCreateChannel
};
FindDmtpActor = this.m_findDmtpActor,
CreatedChannel = this.OnDmtpActorCreateChannel
}; ;
this.m_smtpAdapter = new TcpDmtpAdapter()
this.m_dmtpAdapter = new TcpDmtpAdapter()
{
ReceivedCallBack = this.PrivateHandleReceivedData
};
@@ -211,7 +177,7 @@ namespace ThingsGateway.Foundation.Dmtp
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForConnect.Release();
}
}
@@ -315,7 +281,7 @@ namespace ThingsGateway.Foundation.Dmtp
byteBlock.SetLength(result.Count);
this.m_receiveCounter.Increment(result.Count);
this.m_smtpAdapter.ReceivedInput(byteBlock);
this.m_dmtpAdapter.ReceivedInput(byteBlock);
}
}
@@ -337,7 +303,7 @@ namespace ThingsGateway.Foundation.Dmtp
this.m_client.CloseAsync(WebSocketCloseStatus.NormalClosure, msg, CancellationToken.None);
this.m_client.SafeDispose();
this.DmtpActor.SafeDispose();
this.m_smtpAdapter.SafeDispose();
this.m_dmtpAdapter.SafeDispose();
this.OnDisconnected(new DisconnectEventArgs(manual, msg));
}
}
@@ -403,7 +369,7 @@ namespace ThingsGateway.Foundation.Dmtp
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
var message = (DmtpMessage)requestInfo;
if (!this.m_dmtpActor.InputReceivedData(message))
if (!this.m_dmtpActor.InputReceivedData(message).GetFalseAwaitResult())
{
this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message));
}
@@ -411,70 +377,81 @@ namespace ThingsGateway.Foundation.Dmtp
#region
private void OnDmtpActorClose(DmtpActor actor, string arg2)
private Task OnDmtpActorClose(DmtpActor actor, string arg2)
{
this.PrivateClose(arg2);
return EasyTask.CompletedTask;
}
private void OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
private Task OnDmtpActorCreateChannel(DmtpActor actor, CreateChannelEventArgs e)
{
this.OnCreateChannel(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
return this.OnCreateChannel(e);
}
private void OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaked(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaked(e);
if (e.Handled)
{
return;
}
if (this.PluginsManager.Raise(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e))
{
return;
}
return this.OnHandshaked(e);
}
private void OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
private Task OnDmtpActorHandshaking(DmtpActor actor, DmtpVerifyEventArgs e)
{
this.OnHandshaking(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
return this.OnHandshaking(e);
}
private void OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
private Task OnDmtpActorRouting(DmtpActor actor, PackageRouterEventArgs e)
{
if (this.PluginsManager.Raise(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e))
{
return;
}
this.OnRouting(e);
return this.OnRouting(e);
}
private void OnDmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
for (var i = 0; i < transferBytes.Length; i++)
try
{
Task task;
if (i == transferBytes.Length - 1)
this.m_semaphoreForSend.Wait();
for (var i = 0; i < transferBytes.Length; i++)
{
task = this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, true, CancellationToken.None);
Task task;
if (i == transferBytes.Length - 1)
{
task = this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, true, CancellationToken.None);
}
else
{
task = this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, false, CancellationToken.None);
}
task.GetFalseAwaitResult();
this.m_sendCounter.Increment(transferBytes[i].Count);
}
else
{
task = this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, false, CancellationToken.None);
}
task.GetFalseAwaitResult();
this.m_sendCounter.Increment(transferBytes[i].Count);
}
finally
{
this.m_semaphoreForSend.Release();
}
}
private async Task OnDmtpActorSendAsync(DmtpActor actor, ArraySegment<byte>[] transferBytes)
{
try
{
await this.m_semaphoreForSend.WaitAsync();
for (var i = 0; i < transferBytes.Length; i++)
{
if (i == transferBytes.Length - 1)
{
await this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, true, CancellationToken.None);
}
else
{
await this.m_client.SendAsync(transferBytes[i], WebSocketMessageType.Binary, false, CancellationToken.None);
}
this.m_sendCounter.Increment(transferBytes[i].Count);
}
}
finally
{
this.m_semaphoreForSend.Release();
}
}
#endregion
@@ -485,32 +462,53 @@ namespace ThingsGateway.Foundation.Dmtp
/// 当创建通道
/// </summary>
/// <param name="e"></param>
protected virtual void OnCreateChannel(CreateChannelEventArgs e)
protected virtual async Task OnCreateChannel(CreateChannelEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpCreateChannelPlugin.OnCreateChannel), this, e);
}
/// <summary>
/// 在完成握手连接时
/// </summary>
/// <param name="e"></param>
protected virtual void OnHandshaked(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaked(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakedPlugin.OnDmtpHandshaked), this, e);
}
/// <summary>
/// 即将握手连接时
/// </summary>
/// <param name="e">参数</param>
protected virtual void OnHandshaking(DmtpVerifyEventArgs e)
protected virtual async Task OnHandshaking(DmtpVerifyEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpHandshakingPlugin.OnDmtpHandshaking), this, e);
}
/// <summary>
/// 当需要转发路由包时
/// </summary>
/// <param name="e"></param>
protected virtual void OnRouting(PackageRouterEventArgs e)
protected virtual async Task OnRouting(PackageRouterEventArgs e)
{
if (e.Handled)
{
return;
}
await this.PluginsManager.RaiseAsync(nameof(IDmtpRoutingPlugin.OnDmtpRouting), this, e);
}
#endregion

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,11 @@
//------------------------------------------------------------------------------
#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
@@ -22,10 +27,10 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <summary>
/// 创建一个<see cref="DmtpFileTransferActor"/>
/// </summary>
/// <param name="smtpActor"></param>
public DmtpFileTransferActor(IDmtpActor smtpActor)
/// <param name="dmtpActor"></param>
public DmtpFileTransferActor(IDmtpActor dmtpActor)
{
this.DmtpActor = smtpActor;
this.DmtpActor = dmtpActor;
}
#region
@@ -61,12 +66,8 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
#endregion
/// <summary>
/// 处理收到的消息
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public bool InputReceivedData(DmtpMessage message)
/// <inheritdoc/>
public async Task<bool> InputReceivedData(DmtpMessage message)
{
var byteBlock = message.BodyByteBlock;
if (message.ProtocolFlags == this.m_pullFileResourceInfo_Request)
@@ -77,11 +78,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_pullFileResourceInfo_Request, byteBlock);
return true;
}
else
@@ -96,12 +97,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.SwitchId();
byteBlock.Reset();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
else
{
waitFileResource.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPullFileResourceInfo, waitFileResource);
_ = this.RequestPullFileResourceInfo(waitFileResource);
}
}
catch (Exception ex)
@@ -118,9 +119,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
else
@@ -143,9 +144,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileSection_Request, byteBlock);
await actor.SendAsync(this.m_pullFileSection_Request, byteBlock);
}
else
{
@@ -153,7 +154,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.SwitchId();
byteBlock.Reset();
waitFileSection.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileSection_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileSection_Response, byteBlock);
}
}
else
@@ -177,9 +178,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullFileSection_Response, byteBlock);
await actor.SendAsync(this.m_pullFileSection_Response, byteBlock);
}
}
else
@@ -202,11 +203,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (waitFileResource.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitFileResource))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitFileResource)))
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_pushFileResourceInfo_Request, byteBlock);
return true;
}
else
@@ -221,12 +222,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
else
{
waitFileResource.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPushFileResourceInfo, waitFileResource);
_ = this.RequestPushFileResourceInfo(waitFileResource);
}
}
catch (Exception ex)
@@ -243,9 +244,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileResource.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileResource.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileResource.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
}
else
@@ -268,9 +269,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileSection_Request, byteBlock);
await actor.SendAsync(this.m_pushFileSection_Request, byteBlock);
}
else
{
@@ -278,7 +279,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.SwitchId();
byteBlock.Reset();
waitFileSection.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileSection_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileSection_Response, byteBlock);
}
}
else
@@ -303,9 +304,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFileSection.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFileSection.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFileSection.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushFileSection_Response, byteBlock);
await actor.SendAsync(this.m_pushFileSection_Response, byteBlock);
}
}
else
@@ -328,9 +329,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_finishedFileResourceInfo_Request, byteBlock);
await actor.SendAsync(this.m_finishedFileResourceInfo_Request, byteBlock);
}
else
{
@@ -338,13 +339,13 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.SwitchId();
byteBlock.Reset();
waitFinishedPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
}
else
{
waitFinishedPackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestFinishedFileResourceInfo, waitFinishedPackage);
_ = this.RequestFinishedFileResourceInfo(waitFinishedPackage);
}
}
catch (Exception ex)
@@ -361,9 +362,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitFinishedPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitFinishedPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitFinishedPackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await actor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
}
else
@@ -386,11 +387,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullSmallFile_Request, byteBlock);
await actor.SendAsync(this.m_pullSmallFile_Request, byteBlock);
return true;
}
else
@@ -405,12 +406,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitSmallFilePackage.SwitchId();
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
}
else
{
waitSmallFilePackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPullSmallFile, waitSmallFilePackage);
_ = this.RequestPullSmallFile(waitSmallFilePackage);
}
}
catch (Exception ex)
@@ -427,9 +428,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pullSmallFile_Response, byteBlock);
await actor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
}
}
else
@@ -452,11 +453,11 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
waitSmallFilePackage.UnpackageRouter(byteBlock);
if (waitSmallFilePackage.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.PullFile, waitSmallFilePackage))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.PullFile, waitSmallFilePackage)))
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushSmallFile_Request, byteBlock);
await actor.SendAsync(this.m_pushSmallFile_Request, byteBlock);
return true;
}
else
@@ -472,12 +473,12 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
byteBlock.Reset();
waitSmallFilePackage.SwitchId();
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
}
else
{
waitSmallFilePackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.RequestPushSmallFile, waitSmallFilePackage);
_ = this.RequestPushSmallFile(waitSmallFilePackage);
}
}
catch (Exception ex)
@@ -495,9 +496,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
if (this.DmtpActor.AllowRoute && waitSmallFilePackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(waitSmallFilePackage.TargetId) is DmtpActor actor)
{
actor.Send(this.m_pushSmallFile_Response, byteBlock);
await actor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
}
}
else
@@ -568,24 +569,20 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.FileController.GetFullPath(this.m_rootPath, path);
}
private bool TryFindDmtpFileTransferActor(string targetId, out DmtpFileTransferActor rpcActor)
private async Task<DmtpFileTransferActor> TryFindDmtpFileTransferActor(string targetId)
{
if (targetId == this.DmtpActor.Id)
{
rpcActor = this;
return true;
return this;
}
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
{
if (smtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
if (dmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor newActor)
{
rpcActor = newActor;
return true;
return newActor;
}
}
rpcActor = default;
return false;
return default;
}
#region Id传输
@@ -598,9 +595,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivateFinishedFileResourceInfo(targetId, fileResourceInfo, code, metadata, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
return actor.FinishedFileResourceInfo(fileResourceInfo, code, metadata, timeout, token);
}
else
{
@@ -625,9 +622,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePullFileResourceInfo(targetId, path, metadata, fileSectionSize, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
return actor.PullFileResourceInfo(path, metadata, fileSectionSize, timeout, token);
}
else
{
@@ -652,9 +649,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePullFileSection(targetId, fileSection, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PullFileSection(fileSection, timeout, token);
return actor.PullFileSection(fileSection, timeout, token);
}
else
{
@@ -679,9 +676,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePushFileResourceInfo(targetId, savePath, fileResourceLocator, metadata, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
return actor.PushFileResourceInfo(savePath, fileResourceLocator, metadata, timeout, token);
}
else
{
@@ -715,9 +712,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
return this.PrivatePushFileSection(targetId, fileResourceLocator, fileSection, timeout, token);
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
return actor.PushFileSection(fileResourceLocator, fileSection, timeout, token);
}
else
{
@@ -1261,7 +1258,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFinishedPackage.SwitchId();
waitFinishedPackage.Package(byteBlock);
this.DmtpActor.Send(this.m_finishedFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_finishedFileResourceInfo_Response, byteBlock);
}
var args = new FileTransferedEventArgs(transferType, waitFinishedPackage?.Metadata, resourceInfo?.FileInfo, waitFinishedPackage.Code == ResultCode.Canceled ? Result.Canceled : resultThis)
@@ -1332,7 +1329,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pullFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullFileResourceInfo_Response, byteBlock);
}
}
catch
@@ -1454,7 +1451,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitFileResource.SwitchId();
waitFileResource.Package(byteBlock);
this.DmtpActor.Send(this.m_pushFileResourceInfo_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushFileResourceInfo_Response, byteBlock);
}
}
catch
@@ -1528,7 +1525,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <inheritdoc/>
public PullSmallFileResult PullSmallFile(string targetId, string path, Metadata metadata = null, int timeout = 5000, CancellationToken token = default)
{
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var actor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return actor.PullSmallFile(path, metadata, timeout, token);
}
@@ -1565,9 +1562,9 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <inheritdoc/>
public Result PushSmallFile(string targetId, string savePath, FileInfo fileInfo, Metadata metadata = null, int timeout = 5000, CancellationToken token = default)
{
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpFileTransferActor(targetId).GetFalseAwaitResult() is DmtpFileTransferActor actor)
{
return rpcActor.PushSmallFile(savePath, fileInfo, metadata, timeout, token);
return actor.PushSmallFile(savePath, fileInfo, metadata, timeout, token);
}
else
{
@@ -1827,7 +1824,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
waitSmallFilePackage.SwitchId();
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pullSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pullSmallFile_Response, byteBlock);
}
var resultArgs = new FileTransferedEventArgs(
@@ -1891,7 +1888,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
using (var byteBlock = new ByteBlock())
{
waitSmallFilePackage.Package(byteBlock);
this.DmtpActor.Send(this.m_pushSmallFile_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_pushSmallFile_Response, byteBlock);
}
var resultArgs = new FileTransferedEventArgs(

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp.FileTransfer
{
/// <summary>
@@ -48,7 +49,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <inheritdoc/>
public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
{
var smtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor)
var dmtpFileTransferActor = new DmtpFileTransferActor(client.DmtpActor)
{
FileController = this.m_fileResourceController,
OnFileTransfering = this.OnFileTransfering,
@@ -56,25 +57,25 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
RootPath = this.RootPath,
MaxSmallFileLength = this.MaxSmallFileLength
};
smtpFileTransferActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetDmtpFileTransferActor(smtpFileTransferActor);
dmtpFileTransferActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetDmtpFileTransferActor(dmtpFileTransferActor);
return e.InvokeNext();
}
/// <inheritdoc/>
public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
{
if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor smtpFileTransferActor)
if (client.DmtpActor.GetDmtpFileTransferActor() is DmtpFileTransferActor dmtpFileTransferActor)
{
if (smtpFileTransferActor.InputReceivedData(e.DmtpMessage))
if (await dmtpFileTransferActor.InputReceivedData(e.DmtpMessage))
{
e.Handled = true;
return EasyTask.CompletedTask;
return;
}
}
return e.InvokeNext();
await e.InvokeNext();
}
/// <inheritdoc cref="IDmtpFileTransferActor.MaxSmallFileLength"/>

View File

@@ -48,21 +48,21 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer
/// <summary>
/// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpFileTransferActor"/>
/// </summary>
/// <param name="smtpActor"></param>
/// <param name="dmtpActor"></param>
/// <returns></returns>
public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor smtpActor)
public static IDmtpFileTransferActor GetDmtpFileTransferActor(this IDmtpActor dmtpActor)
{
return smtpActor.GetValue(DmtpFileTransferActorProperty);
return dmtpActor.GetValue(DmtpFileTransferActorProperty);
}
/// <summary>
/// 向<see cref="DmtpActor"/>中设置<see cref="DmtpFileTransferActor"/>
/// </summary>
/// <param name="smtpActor"></param>
/// <param name="smtpRpcActor"></param>
internal static void SetDmtpFileTransferActor(this IDmtpActor smtpActor, DmtpFileTransferActor smtpRpcActor)
/// <param name="dmtpActor"></param>
/// <param name="dmtpRpcActor"></param>
internal static void SetDmtpFileTransferActor(this IDmtpActor dmtpActor, DmtpFileTransferActor dmtpRpcActor)
{
smtpActor.SetValue(DmtpFileTransferActorProperty, smtpRpcActor);
dmtpActor.SetValue(DmtpFileTransferActorProperty, dmtpRpcActor);
}
/// <summary>

View File

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

View File

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

View File

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

View File

@@ -22,10 +22,10 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
/// <summary>
/// DmtpRedisActor
/// </summary>
/// <param name="smtpActor"></param>
public DmtpRedisActor(IDmtpActor smtpActor)
/// <param name="dmtpActor"></param>
public DmtpRedisActor(IDmtpActor dmtpActor)
{
this.DmtpActor = smtpActor;
this.DmtpActor = dmtpActor;
}
/// <inheritdoc/>
@@ -241,7 +241,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public bool InputReceivedData(DmtpMessage message)
public async Task<bool> InputReceivedData(DmtpMessage message)
{
if (message.ProtocolFlags == this.m_redis_Request)
{
@@ -311,7 +311,7 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
using (var byteBlock = new ByteBlock())
{
waitResult.Package(byteBlock);
this.DmtpActor.Send(this.m_redis_Response, byteBlock);
await this.DmtpActor.SendAsync(this.m_redis_Response, byteBlock);
}
return true;
}

View File

@@ -22,6 +22,8 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using ThingsGateway.Foundation.Core;
using ThingsGateway.Foundation.Resources;
namespace ThingsGateway.Foundation.Dmtp.Redis
@@ -52,16 +54,16 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
/// <summary>
/// 从<see cref="DmtpActor"/>中获得<see cref="IDmtpRedisActor"/>
/// </summary>
/// <param name="smtpActor"></param>
/// <param name="dmtpActor"></param>
/// <returns></returns>
public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor smtpActor)
public static IDmtpRedisActor GetDmtpRedisActor(this IDmtpActor dmtpActor)
{
return smtpActor.GetValue(DmtpRedisActorProperty);
return dmtpActor.GetValue(DmtpRedisActorProperty);
}
internal static void SetStmpRedisActor(this IDmtpActor smtpActor, DmtpRedisActor redisClient)
internal static void SetStmpRedisActor(this IDmtpActor dmtpActor, DmtpRedisActor redisClient)
{
smtpActor.SetValue(DmtpRedisActorProperty, redisClient);
dmtpActor.SetValue(DmtpRedisActorProperty, redisClient);
}
/// <summary>

View File

@@ -22,6 +22,8 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Threading.Tasks;
using ThingsGateway.Foundation.Core;
namespace ThingsGateway.Foundation.Dmtp.Redis
{
@@ -58,30 +60,30 @@ namespace ThingsGateway.Foundation.Dmtp.Redis
/// <inheritdoc/>
public Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
{
var smtpRedisActor = new DmtpRedisActor(client.DmtpActor)
var dmtpRedisActor = new DmtpRedisActor(client.DmtpActor)
{
ICache = this.ICache,
Converter = this.Converter
};
smtpRedisActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetStmpRedisActor(smtpRedisActor);
dmtpRedisActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetStmpRedisActor(dmtpRedisActor);
return e.InvokeNext();
}
/// <inheritdoc/>
public Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
public async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
{
if (client.DmtpActor.GetDmtpRedisActor() is DmtpRedisActor redisClient)
{
if (redisClient.InputReceivedData(e.DmtpMessage))
if (await redisClient.InputReceivedData(e.DmtpMessage))
{
e.Handled = true;
return EasyTask.CompletedTask;
return;
}
}
return e.InvokeNext();
await e.InvokeNext();
}
/// <summary>

View File

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

View File

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

View File

@@ -36,10 +36,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
/// <summary>
/// 创建一个DmtpRpcActor
/// </summary>
/// <param name="smtpActor"></param>
public DmtpRpcActor(IDmtpActor smtpActor)
/// <param name="dmtpActor"></param>
public DmtpRpcActor(IDmtpActor dmtpActor)
{
this.DmtpActor = smtpActor;
this.DmtpActor = dmtpActor;
}
/// <inheritdoc/>
@@ -69,7 +69,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public bool InputReceivedData(DmtpMessage message)
public async Task<bool> InputReceivedData(DmtpMessage message)
{
var byteBlock = message.BodyByteBlock;
@@ -77,14 +77,13 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
try
{
//Console.WriteLine(byteBlock.Len);
var rpcPackage = new DmtpRpcPackage();
rpcPackage.UnpackageRouter(byteBlock);
if (rpcPackage.Route && this.DmtpActor.AllowRoute)
{
if (this.DmtpActor.TryRoute(RouteType.Rpc, rpcPackage))
if (await this.DmtpActor.TryRoute(new PackageRouterEventArgs(RouteType.Rpc, rpcPackage)).ConfigureFalseAwait())
{
if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(this.m_invoke_Request, byteBlock);
return true;
@@ -108,8 +107,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
else
{
rpcPackage.UnpackageBody(byteBlock);
Task.Factory.StartNew(this.InvokeThis, rpcPackage);
//this.InvokeThis(rpcPackage);
_ = Task.Factory.StartNew(this.InvokeThis, rpcPackage);
}
}
catch (Exception ex)
@@ -126,7 +124,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
rpcPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && rpcPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(rpcPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(this.m_invoke_Response, byteBlock);
}
@@ -151,7 +149,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
canceledPackage.UnpackageRouter(byteBlock);
if (this.DmtpActor.AllowRoute && canceledPackage.Route)
{
if (this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId, out var actor))
if (await this.DmtpActor.TryFindDmtpActor(canceledPackage.TargetId).ConfigureFalseAwait() is DmtpActor actor)
{
actor.Send(this.m_cancelInvoke, byteBlock);
}
@@ -203,7 +201,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
try
{
var rpcPackage = (DmtpRpcPackage)o;
//Console.WriteLine(rpcPackage.MethodName);
var psData = rpcPackage.ParametersBytes;
if (rpcPackage.Feedback == FeedbackType.WaitSend)
{
@@ -227,7 +225,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var invokeResult = new InvokeResult();
object[] ps = null;
var methodInstance = this.GetInvokeMethod?.Invoke(rpcPackage.MethodName);
var methodInstance = this.GetInvokeMethod.Invoke(rpcPackage.MethodName);
DmtpRpcCallContext callContext = null;
if (methodInstance != null)
{
@@ -283,7 +281,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
{
transientRpcServer.CallContext = callContext;
}
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext);
invokeResult = await RpcStore.ExecuteAsync(rpcServer, ps, callContext).ConfigureFalseAwait();
}
if (rpcPackage.Feedback == FeedbackType.OnlySend)
@@ -369,24 +367,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
}
private bool TryFindDmtpRpcActor(string targetId, out DmtpRpcActor rpcActor)
private async Task<DmtpRpcActor> TryFindDmtpRpcActor(string targetId)
{
if (targetId == this.DmtpActor.Id)
{
rpcActor = this;
return true;
return this;
}
if (this.DmtpActor.TryFindDmtpActor(targetId, out var smtpActor))
if (await this.DmtpActor.TryFindDmtpActor(targetId).ConfigureFalseAwait() is DmtpActor dmtpActor)
{
if (smtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
if (dmtpActor.GetDmtpRpcActor() is DmtpRpcActor newActor)
{
rpcActor = newActor;
return true;
return newActor;
}
}
rpcActor = default;
return false;
return default;
}
#region Rpc
@@ -504,8 +498,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -532,7 +524,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -689,8 +680,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -722,7 +711,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -779,8 +767,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetWaitDataAsync(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -818,7 +804,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
@@ -832,7 +818,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -898,7 +884,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -907,7 +892,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
@@ -918,7 +903,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -961,7 +946,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
actor.Invoke(invokeKey, invokeOption, parameters);
return;
@@ -977,7 +962,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1009,7 +993,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1069,9 +1052,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
return rpcActor.Invoke(returnType, invokeKey, invokeOption, parameters);
return actor.Invoke(returnType, invokeKey, invokeOption, parameters);
}
var rpcPackage = new DmtpRpcPackage
@@ -1084,10 +1067,8 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
{
if (invokeOption == default)
@@ -1116,7 +1097,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1175,9 +1155,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
rpcActor.Invoke(invokeKey, invokeOption, ref parameters, types);
actor.Invoke(invokeKey, invokeOption, ref parameters, types);
return;
}
@@ -1191,7 +1171,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1219,7 +1198,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1289,9 +1267,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId).GetFalseAwaitResult() is DmtpRpcActor actor)
{
return rpcActor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
return actor.Invoke(returnType, invokeKey, invokeOption, ref parameters, types);
}
var rpcPackage = new DmtpRpcPackage
@@ -1304,7 +1282,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitData(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1330,7 +1307,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1400,9 +1376,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var actor))
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
{
await actor.InvokeAsync(invokeKey, invokeOption, parameters);
await actor.InvokeAsync(invokeKey, invokeOption, parameters).ConfigureFalseAwait();
return;
}
@@ -1416,7 +1392,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
var waitData = this.DmtpActor.WaitHandlePool.GetReverseWaitDataAsync(rpcPackage);
try
{
using (var byteBlock = new ByteBlock())
@@ -1448,7 +1423,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1456,7 +1430,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
break;
@@ -1470,7 +1444,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{
@@ -1508,9 +1482,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
throw new ArgumentException($"“{nameof(invokeKey)}”不能为 null 或空。", nameof(invokeKey));
}
if (this.DmtpActor.AllowRoute && this.TryFindDmtpRpcActor(targetId, out var rpcActor))
if (this.DmtpActor.AllowRoute && await this.TryFindDmtpRpcActor(targetId).ConfigureFalseAwait() is DmtpRpcActor actor)
{
return await rpcActor.InvokeAsync(returnType, invokeKey, invokeOption, parameters);
return await actor.InvokeAsync(returnType, invokeKey, invokeOption, parameters).ConfigureFalseAwait();
}
var rpcPackage = new DmtpRpcPackage
@@ -1553,8 +1527,6 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
this.DmtpActor.Send(this.m_invoke_Request, byteBlock.Buffer, 0, byteBlock.Len);
}
switch (invokeOption.FeedbackType)
{
case FeedbackType.OnlySend:
@@ -1563,7 +1535,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitSend:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.Overtime:
{
@@ -1574,7 +1546,7 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
}
case FeedbackType.WaitInvoke:
{
switch (await waitData.WaitAsync(invokeOption.Timeout))
switch (await waitData.WaitAsync(invokeOption.Timeout).ConfigureFalseAwait())
{
case WaitDataStatus.SetRunning:
{

View File

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

View File

@@ -42,11 +42,11 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
/// <summary>
/// 从<see cref="DmtpActor"/>中获取<see cref="IDmtpRpcActor"/>
/// </summary>
/// <param name="smtpActor"></param>
/// <param name="dmtpActor"></param>
/// <returns></returns>
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor smtpActor)
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActor dmtpActor)
{
return smtpActor.GetValue(DmtpRpcActorProperty);
return dmtpActor.GetValue(DmtpRpcActorProperty);
}
/// <summary>
@@ -57,12 +57,12 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
/// <exception cref="ArgumentNullException"></exception>
public static IDmtpRpcActor GetDmtpRpcActor(this IDmtpActorObject client)
{
var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
if (smtpRpcActor is null)
var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
if (dmtpRpcActor is null)
{
throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
}
return smtpRpcActor;
return dmtpRpcActor;
}
/// <summary>
@@ -73,22 +73,22 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
/// <exception cref="ArgumentNullException"></exception>
public static TDmtpRpcActor GetDmtpRpcActor<TDmtpRpcActor>(this IDmtpActorObject client) where TDmtpRpcActor : IDmtpRpcActor
{
var smtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
if (smtpRpcActor is null)
var dmtpRpcActor = client.DmtpActor.GetDmtpRpcActor();
if (dmtpRpcActor is null)
{
throw new ArgumentNullException(nameof(smtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
throw new ArgumentNullException(nameof(dmtpRpcActor), TouchSocketDmtpResource.DmtpRpcActorArgumentNull.GetDescription());
}
return (TDmtpRpcActor)smtpRpcActor;
return (TDmtpRpcActor)dmtpRpcActor;
}
/// <summary>
/// 向<see cref="DmtpActor"/>中设置<see cref="IDmtpRpcActor"/>
/// </summary>
/// <param name="smtpActor"></param>
/// <param name="smtpRpcActor"></param>
internal static void SetDmtpRpcActor(this IDmtpActor smtpActor, IDmtpRpcActor smtpRpcActor)
/// <param name="dmtpActor"></param>
/// <param name="dmtpRpcActor"></param>
internal static void SetDmtpRpcActor(this IDmtpActor dmtpActor, IDmtpRpcActor dmtpRpcActor)
{
smtpActor.SetValue(DmtpRpcActorProperty, smtpRpcActor);
dmtpActor.SetValue(DmtpRpcActorProperty, dmtpRpcActor);
}
#region

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp.Rpc
{
/// <summary>
@@ -94,9 +95,9 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
return this.ActionMap.GetMethodInstance(name);
}
private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor smtpActor)
private DmtpRpcActor PrivateCreateDmtpRpcActor(IDmtpActor dmtpActor)
{
return new DmtpRpcActor(smtpActor);
return new DmtpRpcActor(dmtpActor);
}
#region Rpc配置
@@ -135,31 +136,30 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
pluginsManager.Add<IDmtpActorObject, DmtpMessageEventArgs>(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this.OnDmtpReceived);
}
private Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
private async Task OnDmtpHandshaking(IDmtpActorObject client, DmtpVerifyEventArgs e)
{
var smtpRpcActor = CreateDmtpRpcActor(client.DmtpActor);
smtpRpcActor.RpcStore = this.RpcStore;
smtpRpcActor.SerializationSelector = this.SerializationSelector;
smtpRpcActor.GetInvokeMethod = this.GetInvokeMethod;
var dmtpRpcActor = this.CreateDmtpRpcActor(client.DmtpActor);
dmtpRpcActor.RpcStore = this.RpcStore;
dmtpRpcActor.SerializationSelector = this.SerializationSelector;
dmtpRpcActor.GetInvokeMethod = this.GetInvokeMethod;
smtpRpcActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetDmtpRpcActor(smtpRpcActor);
dmtpRpcActor.SetProtocolFlags(this.StartProtocol);
client.DmtpActor.SetDmtpRpcActor(dmtpRpcActor);
return e.InvokeNext();
await e.InvokeNext();
}
private Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
private async Task OnDmtpReceived(IDmtpActorObject client, DmtpMessageEventArgs e)
{
if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor smtpRpcActor)
if (client.DmtpActor.GetDmtpRpcActor() is DmtpRpcActor dmtpRpcActor)
{
if (smtpRpcActor.InputReceivedData(e.DmtpMessage))
if (await dmtpRpcActor.InputReceivedData(e.DmtpMessage).ConfigureFalseAwait())
{
e.Handled = true;
return EasyTask.CompletedTask;
return;
}
}
return e.InvokeNext();
await e.InvokeNext();
}
#endregion Config

View File

@@ -108,10 +108,10 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc
internal void LoadInvokeOption(IInvokeOption option)
{
if (option is DmtpInvokeOption smtpInvokeOption)
if (option is DmtpInvokeOption dmtpInvokeOption)
{
this.Feedback = smtpInvokeOption.FeedbackType;
this.SerializationType = smtpInvokeOption.SerializationType;
this.Feedback = dmtpInvokeOption.FeedbackType;
this.SerializationType = dmtpInvokeOption.SerializationType;
}
else if (option is InvokeOption invokeOption)
{

View File

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

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -27,6 +28,6 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
/// <param name="message"></param>
/// <returns>当满足本协议时,应当返回<see langword="true"/>,其他时候应该返回<see langword="false"/>.</returns>
public bool InputReceivedData(DmtpMessage message);
public Task<bool> InputReceivedData(DmtpMessage message);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,9 @@
//------------------------------------------------------------------------------
#endregion
using System;
using System.Threading.Tasks;
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -18,8 +21,8 @@ namespace ThingsGateway.Foundation.Dmtp
public class DmtpRouteService : IDmtpRouteService
{
/// <summary>
/// 查找路由的委托
/// <inheritdoc/>
/// </summary>
public Func<string, IDmtpActor> FindDmtpActor { get; set; }
public Func<string, Task<IDmtpActor>> FindDmtpActor { get ; set ; }
}
}

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
#endregion
namespace ThingsGateway.Foundation.Dmtp
{
/// <summary>
@@ -31,12 +32,26 @@ namespace ThingsGateway.Foundation.Dmtp
/// </summary>
/// <param name="container"></param>
/// <param name="func"></param>
public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> func)
public static void AddDmtpRouteService(this IContainer container, Func<string, Task<IDmtpActor>> func)
{
container.RegisterSingleton<IDmtpRouteService>(new DmtpRouteService()
{
FindDmtpActor = func
});
}
/// <summary>
/// 添加基于设定委托的Dmtp路由服务。
/// </summary>
/// <param name="container"></param>
/// <param name="action"></param>
public static void AddDmtpRouteService(this IContainer container, Func<string, IDmtpActor> action)
{
AddDmtpRouteService(container, async (id) =>
{
await EasyTask.CompletedTask;
return action.Invoke(id);
});
}
}
}

View File

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

View File

@@ -72,7 +72,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
{
return new WebSocketReceiveResult(this.ComplateRead, null);
}
await this.m_resetEventForRead.WaitOneAsync(token);
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame);
}
#if NET6_0_OR_GREATER
@@ -82,7 +82,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
{
return new WebSocketReceiveResult(this.ComplateRead, null);
}
await this.m_resetEventForRead.WaitOneAsync(token);
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame);
}
#endif
@@ -146,7 +146,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets
{
return true;
}
if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10)))
if (await this.m_resetEventForComplateRead.WaitOneAsync(TimeSpan.FromSeconds(10)).ConfigureFalseAwait())
{
return true;
}

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System.Diagnostics;
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
@@ -40,13 +39,12 @@ public class SerialCore : IDisposable, ISender
public readonly object SyncRoot = new object();
private long m_bufferRate;
private SpinLock m_lock;
private bool m_online => m_serialPort?.IsOpen == true;
private int m_receiveBufferSize = 1024 * 10;
private ValueCounter m_receiveCounter;
private int m_sendBufferSize = 1024 * 10;
private ValueCounter m_sendCounter;
private readonly EasyLock m_semaphore = new EasyLock();
private readonly EasyLock m_semaphoreForSend = new EasyLock();
private SerialPort m_serialPort;
#endregion
@@ -56,7 +54,6 @@ public class SerialCore : IDisposable, ISender
/// </summary>
public SerialCore()
{
this.m_lock = new SpinLock(Debugger.IsAttached);
this.m_receiveCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
@@ -215,7 +212,6 @@ public class SerialCore : IDisposable, ISender
this.OnBreakOut = null;
this.UserToken = null;
this.m_bufferRate = 1;
this.m_lock = new SpinLock();
this.m_receiveBufferSize = this.MinBufferSize;
this.m_sendBufferSize = this.MinBufferSize;
}
@@ -231,15 +227,14 @@ public class SerialCore : IDisposable, ISender
/// <param name="length"></param>
public virtual void Send(byte[] buffer, int offset, int length)
{
var lockTaken = false;
try
{
this.m_lock.Enter(ref lockTaken);
this.m_semaphoreForSend.Wait();
this.m_serialPort.Write(buffer, offset, length);
}
finally
{
if (lockTaken) this.m_lock.Exit(false);
this.m_semaphoreForSend.Release();
}
this.m_sendCounter.Increment(length);
}
@@ -256,13 +251,13 @@ public class SerialCore : IDisposable, ISender
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForSend.WaitAsync();
this.m_serialPort.Write(buffer, offset, length);
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForSend.Release();
}
this.m_sendCounter.Increment(length);

View File

@@ -255,7 +255,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
this.MainSerialPort.TryClose();
this.BreakOut(default, true, msg);
this.BreakOut(true, msg);
}
}
}
@@ -272,7 +272,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
if (this.m_online)
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
}
}
base.Dispose(disposing);
@@ -361,7 +361,16 @@ public class SerialSessionBase : BaseSerial, ISerialSession
#endregion
private void BreakOut(SerialCore core, bool manual, string msg)
private void SerialCoreBreakOut(SerialCore core, bool manual, string msg)
{
this.BreakOut(manual, msg);
}
/// <summary>
/// BreakOut。
/// </summary>
/// <param name="manual"></param>
/// <param name="msg"></param>
protected void BreakOut(bool manual, string msg)
{
lock (this.SyncRoot)
{
@@ -759,8 +768,16 @@ public class SerialSessionBase : BaseSerial, ISerialSession
}
this.m_serialCore.Reset(serialPort);
this.m_serialCore.OnReceived = this.HandleReceived;
this.m_serialCore.OnBreakOut = this.BreakOut;
this.m_serialCore.OnBreakOut = this.SerialCoreBreakOut;
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
{
this.m_serialCore.MinBufferSize = minValue;
}
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
{
this.m_serialCore.MaxBufferSize = maxValue;
}
}
private void HandleReceived(SerialCore core, ByteBlock byteBlock)

View File

@@ -10,7 +10,6 @@
//------------------------------------------------------------------------------
#endregion
using System.Diagnostics;
using System.Net.Security;
using System.Net.Sockets;
@@ -41,14 +40,13 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
public readonly object SyncRoot = new object();
private long m_bufferRate;
private SpinLock m_lock;
private volatile bool m_online;
private int m_receiveBufferSize = 1024 * 10;
private ValueCounter m_receiveCounter;
private int m_sendBufferSize = 1024 * 10;
private ValueCounter m_sendCounter;
private Socket m_socket;
private readonly EasyLock m_semaphore = new();
private readonly EasyLock m_semaphoreForSend = new();
#endregion
/// <summary>
@@ -56,7 +54,6 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
/// </summary>
public TcpCore()
{
this.m_lock = new SpinLock(Debugger.IsAttached);
this.m_receiveCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
@@ -295,7 +292,6 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
this.OnBreakOut = null;
this.UserToken = null;
this.m_bufferRate = 1;
this.m_lock = new SpinLock();
this.m_receiveBufferSize = this.MinBufferSize;
this.m_sendBufferSize = this.MinBufferSize;
this.m_online = false;
@@ -318,10 +314,9 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
}
else
{
var lockTaken = false;
try
{
this.m_lock.Enter(ref lockTaken);
this.m_semaphoreForSend.Wait();
while (length > 0)
{
var r = this.m_socket.Send(buffer, offset, length, SocketFlags.None);
@@ -335,7 +330,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
}
finally
{
if (lockTaken) this.m_lock.Exit(false);
this.m_semaphoreForSend.Release();
}
}
this.m_sendCounter.Increment(length);
@@ -363,7 +358,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForSend.WaitAsync();
while (length > 0)
{
@@ -378,7 +373,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForSend.Release();
}
}
#else
@@ -390,7 +385,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
{
try
{
await this.m_semaphore.WaitAsync();
await this.m_semaphoreForSend.WaitAsync();
while (length > 0)
{
@@ -405,7 +400,7 @@ public class TcpCore : SocketAsyncEventArgs, IDisposable, ISender
}
finally
{
this.m_semaphore.Release();
this.m_semaphoreForSend.Release();
}
}
#endif

View File

@@ -149,7 +149,7 @@ namespace ThingsGateway.Foundation.Sockets
}
catch (Exception ex)
{
this.BreakOut(default, false, ex.ToString());
this.BreakOut(false, ex.ToString());
}
}
@@ -226,11 +226,30 @@ namespace ThingsGateway.Foundation.Sockets
var tcpCore = this.Service.RentTcpCore();
tcpCore.Reset(socket);
tcpCore.OnReceived = this.HandleReceived;
tcpCore.OnBreakOut = this.BreakOut;
tcpCore.OnBreakOut = this.TcpCoreBreakOut;
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
{
tcpCore.MinBufferSize = minValue;
}
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
{
tcpCore.MaxBufferSize = maxValue;
}
this.m_tcpCore = tcpCore;
}
private void BreakOut(TcpCore core, bool manual, string msg)
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
{
this.BreakOut(manual, msg);
}
/// <summary>
/// 中断连接
/// </summary>
/// <param name="manual"></param>
/// <param name="msg"></param>
protected void BreakOut(bool manual, string msg)
{
if (this.GetSocketCliectCollection().TryRemove(this.Id, out _))
{
@@ -388,7 +407,7 @@ namespace ThingsGateway.Foundation.Sockets
{
var tcp = this.m_tcpCore;
this.m_tcpCore = null;
this.Service?.ReturnTcpCore(tcp);
this.Service.ReturnTcpCore(tcp);
}
}
@@ -415,7 +434,7 @@ namespace ThingsGateway.Foundation.Sockets
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
this.MainSocket.TryClose();
this.BreakOut(default, true, msg);
this.BreakOut(true, msg);
}
}
}
@@ -496,7 +515,7 @@ namespace ThingsGateway.Foundation.Sockets
if (this.Online)
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
}
base.Dispose(disposing);

View File

@@ -280,7 +280,7 @@ namespace ThingsGateway.Foundation.Sockets
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg));
this.MainSocket.TryClose();
this.BreakOut(default, true, msg);
this.BreakOut(true, msg);
}
}
}
@@ -297,7 +297,7 @@ namespace ThingsGateway.Foundation.Sockets
if (this.m_online)
{
Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开"));
this.BreakOut(default, true, $"{nameof(Dispose)}主动断开");
this.BreakOut(true, $"{nameof(Dispose)}主动断开");
}
}
base.Dispose(disposing);
@@ -497,7 +497,22 @@ namespace ThingsGateway.Foundation.Sockets
#endregion
private void BreakOut(TcpCore core, bool manual, string msg)
/// <inheritdoc/>
public override string ToString()
{
return this.GetIPPort();
}
private void TcpCoreBreakOut(TcpCore core, bool manual, string msg)
{
this.BreakOut(manual, msg);
}
/// <summary>
/// BreakOut。
/// </summary>
/// <param name="manual"></param>
/// <param name="msg"></param>
protected void BreakOut(bool manual, string msg)
{
lock (this.SyncRoot)
{
@@ -930,8 +945,16 @@ namespace ThingsGateway.Foundation.Sockets
}
this.m_tcpCore.Reset(socket);
this.m_tcpCore.OnReceived = this.HandleReceived;
this.m_tcpCore.OnBreakOut = this.BreakOut;
this.m_tcpCore.OnBreakOut = this.TcpCoreBreakOut;
if (this.Config.GetValue(TouchSocketConfigExtension.MinBufferSizeProperty) is int minValue)
{
this.m_tcpCore.MinBufferSize = minValue;
}
if (this.Config.GetValue(TouchSocketConfigExtension.MaxBufferSizeProperty) is int maxValue)
{
this.m_tcpCore.MaxBufferSize = maxValue;
}
}
private void HandleReceived(TcpCore core, ByteBlock byteBlock)

View File

@@ -209,7 +209,7 @@ namespace ThingsGateway.Foundation.Sockets
/// <param name="e"></param>
protected virtual Task OnDisconnecting(TClient socketClient, DisconnectEventArgs e)
{
if (this.Disconnected != null)
if (this.Disconnecting != null)
{
return this.Disconnecting.Invoke(socketClient, e);
}

View File

@@ -155,6 +155,11 @@ namespace ThingsGateway.Foundation.Sockets
/// <param name="tcpCore"></param>
public void ReturnTcpCore(TcpCore tcpCore)
{
if (this.DisposedValue)
{
tcpCore.SafeDispose();
return;
}
this.m_tcpCores.Push(tcpCore);
}

View File

@@ -204,7 +204,7 @@ namespace ThingsGateway.Foundation.Sockets
public class UdpPackageAdapter : UdpDataHandlingAdapter
{
private readonly SnowflakeIdGenerator m_iDGenerator;
private readonly ConcurrentDictionary<long, UdpPackage> revStore;
private readonly ConcurrentDictionary<long, UdpPackage> m_revStore;
private int m_mtu = 1472;
/// <summary>
@@ -212,7 +212,7 @@ namespace ThingsGateway.Foundation.Sockets
/// </summary>
public UdpPackageAdapter()
{
this.revStore = new ConcurrentDictionary<long, UdpPackage>();
this.m_revStore = new ConcurrentDictionary<long, UdpPackage>();
this.m_iDGenerator = new SnowflakeIdGenerator(4);
}
@@ -250,17 +250,17 @@ namespace ThingsGateway.Foundation.Sockets
var udpFrame = new UdpFrame();
if (udpFrame.Parse(byteBlock.Buffer, 0, byteBlock.Len))
{
var udpPackage = this.revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.revStore));
var udpPackage = this.m_revStore.GetOrAdd(udpFrame.Id, (i) => new UdpPackage(i, this.Timeout, this.m_revStore));
udpPackage.Add(udpFrame);
if (udpPackage.Length > this.MaxPackageSize)
{
this.revStore.TryRemove(udpPackage.Id, out _);
this.m_revStore.TryRemove(udpPackage.Id, out _);
this.Logger?.Error("数据长度大于设定的最大值。");
return;
}
if (udpPackage.IsComplated)
{
if (this.revStore.TryRemove(udpPackage.Id, out _))
if (this.m_revStore.TryRemove(udpPackage.Id, out _))
{
using (var block = new ByteBlock(udpPackage.Length))
{

View File

@@ -51,6 +51,54 @@ namespace ThingsGateway.Foundation.Sockets
public static readonly DependencyProperty<Func<UdpDataHandlingAdapter>> UdpDataHandlingAdapterProperty = DependencyProperty<Func<UdpDataHandlingAdapter>>.Register("UdpDataHandlingAdapter", () => { return new NormalUdpDataHandlingAdapter(); });
/// <summary>
/// 最小缓存池尺寸
/// 所需类型<see cref="int"/>
/// </summary>
public static readonly DependencyProperty<int?> MinBufferSizeProperty = DependencyProperty<int?>.Register("MinBufferSize", default);
/// <summary>
/// 最大缓存池尺寸
/// 所需类型<see cref="int"/>
/// </summary>
public static readonly DependencyProperty<int?> MaxBufferSizeProperty = DependencyProperty<int?>.Register("MinBufferSize", default);
/// <summary>
/// 最小缓存容量,默认缺省。
/// <list type="number">
/// </list>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig MinBufferSize(this TouchSocketConfig config, int value)
{
if (value < 1024)
{
throw new ArgumentOutOfRangeException(nameof(value), value, "数值不能小于1024");
}
config.SetValue(MinBufferSizeProperty, value);
return config;
}
/// <summary>
/// 最大缓存容量,默认缺省。
/// <list type="number">
/// </list>
/// </summary>
/// <param name="config"></param>
/// <param name="value"></param>
/// <returns></returns>
public static TouchSocketConfig MaxBufferSize(this TouchSocketConfig config, int value)
{
if (value < 1024)
{
throw new ArgumentOutOfRangeException(nameof(value), value, "数值不能小于1024");
}
config.SetValue(MaxBufferSizeProperty, value);
return config;
}
/// <summary>
/// 发送超时设定单位毫秒默认为0。意为禁用该配置。
/// </summary>

View File

@@ -22,7 +22,13 @@ namespace ThingsGateway.Foundation.Sockets
private readonly AsyncAutoResetEvent m_resetEventForRead = new AsyncAutoResetEvent(false);
private ByteBlock m_byteBlock;
private IRequestInfo m_requestInfo;
/// <summary>
/// Receiver
/// </summary>
~Receiver()
{
this.Dispose(false);
}
/// <summary>
/// Receiver
/// </summary>
@@ -36,7 +42,7 @@ namespace ThingsGateway.Foundation.Sockets
public async Task<ReceiverResult> ReadAsync(CancellationToken token)
{
this.ThrowIfDisposed();
await this.m_resetEventForRead.WaitOneAsync(token);
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo);
}
@@ -45,7 +51,7 @@ namespace ThingsGateway.Foundation.Sockets
public async ValueTask<ReceiverResult> ValueReadAsync(CancellationToken token)
{
this.ThrowIfDisposed();
await this.m_resetEventForRead.WaitOneAsync(token);
await this.m_resetEventForRead.WaitOneAsync(token).ConfigureFalseAwait();
return new ReceiverResult(this.ComplateRead, this.m_byteBlock, this.m_requestInfo);
}
#endif
@@ -74,9 +80,15 @@ namespace ThingsGateway.Foundation.Sockets
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
this.m_client.ClearReceiver();
//this.m_resetEventForComplateRead.SafeDispose();
this.m_resetEventForRead.SafeDispose();
if (disposing)
{
this.m_client.ClearReceiver();
}
else
{
this.m_resetEventForRead.SafeDispose();
}
this.m_byteBlock = null;
base.Dispose(disposing);
}

View File

@@ -28,7 +28,6 @@ namespace ThingsGateway.Foundation.Sockets
internal class WaitingClient<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, ISender
{
private readonly EasyLock m_semaphoreSlim = new();
private volatile bool m_breaked;
private CancellationTokenSource m_cancellationTokenSource;
@@ -75,8 +74,7 @@ namespace ThingsGateway.Foundation.Sockets
{
try
{
this.m_semaphoreSlim.Wait();
this.m_breaked = false;
this.m_semaphoreSlim.Wait(token);
if (token.CanBeCanceled)
{
this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
@@ -85,7 +83,7 @@ namespace ThingsGateway.Foundation.Sockets
{
this.m_cancellationTokenSource = new CancellationTokenSource(5000);
}
using (m_cancellationTokenSource)
using (this.m_cancellationTokenSource)
{
if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session)
{
@@ -113,7 +111,6 @@ namespace ThingsGateway.Foundation.Sockets
{
if (receiverResult.IsClosed)
{
this.m_breaked = true;
this.Cancel();
}
var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo);
@@ -135,10 +132,6 @@ namespace ThingsGateway.Foundation.Sockets
}
}
}
catch (OperationCanceledException)
{
return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException();
}
finally
{
this.m_cancellationTokenSource = null;
@@ -156,8 +149,7 @@ namespace ThingsGateway.Foundation.Sockets
{
try
{
await this.m_semaphoreSlim.WaitAsync();
this.m_breaked = false;
await this.m_semaphoreSlim.WaitAsync(token);
if (token.CanBeCanceled)
{
this.m_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token);
@@ -166,7 +158,7 @@ namespace ThingsGateway.Foundation.Sockets
{
this.m_cancellationTokenSource = new CancellationTokenSource(5000);
}
using (m_cancellationTokenSource)
using (this.m_cancellationTokenSource)
{
if (this.WaitingOptions.RemoteIPHost != null && this.Client is IUdpSession session)
{
@@ -194,7 +186,6 @@ namespace ThingsGateway.Foundation.Sockets
{
if (receiverResult.IsClosed)
{
this.m_breaked = true;
this.Cancel();
}
var response = new ResponsedData(receiverResult.ByteBlock?.ToArray(), receiverResult.RequestInfo);
@@ -216,10 +207,6 @@ namespace ThingsGateway.Foundation.Sockets
}
}
}
catch (OperationCanceledException)
{
return this.WaitingOptions.ThrowBreakException && this.m_breaked ? throw new Exception("等待已终止。可能是客户端已掉线,或者被注销。") : throw new TimeoutException();
}
finally
{
this.m_cancellationTokenSource = null;

View File

@@ -30,22 +30,11 @@ namespace ThingsGateway.Foundation.Sockets
/// </summary>
public class WaitingOptions
{
/// <summary>
/// 当Client为Tcp系时。是否在断开连接时立即触发结果。默认会返回null。当<see cref="ThrowBreakException"/>为<see langword="true"/>时,会触发异常。
/// </summary>
public bool BreakTrigger { get; set; }
/// <summary>
/// 远程地址(仅在Udp模式下生效)
/// </summary>
public IPHost RemoteIPHost { get; set; }
/// <summary>
/// 当Client为Tcp系时。是否在断开连接时以异常返回结果。
/// </summary>
public bool ThrowBreakException { get; set; } = true;
/// <summary>
/// 筛选函数

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.0.0.16</Version>
<Version>3.0.0.23</Version>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>

View File

@@ -177,6 +177,8 @@ public class OPCUAClient : CollectBase
if (_plc != null)
{
_plc.DataChangedHandler -= DataChangedHandler;
_plc.OpcStatusChange -= _plc_OpcStatusChange;
_plc.Disconnect();
_plc.SafeDispose();
_plc = null;
@@ -204,13 +206,19 @@ public class OPCUAClient : CollectBase
};
if (_plc == null)
{
_plc = new((arg1, arg2, arg3, arg4) => Log_Out((LogLevel)arg1, arg2, arg3, arg4));
_plc = new();
_plc.OpcStatusChange += _plc_OpcStatusChange;
_plc.DataChangedHandler += DataChangedHandler;
}
_plc.OPCNode = opcNode;
}
private void _plc_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
{
Log_Out((LogLevel)e.LogLevel, null, e.Text, null);
}
/// <inheritdoc/>
protected override Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken cancellationToken)
{

View File

@@ -0,0 +1,39 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Opc.Ua.Configuration;
namespace ThingsGateway.Plugin.OPCUA;
public partial class OPCUAServer
{
public class ApplicationMessageDlg : IApplicationMessageDlg
{
private string message = string.Empty;
private ILog _log;
public ApplicationMessageDlg(ILog log)
{
_log = log;
}
public override void Message(string text, bool ask)
{
message = text;
}
public override async Task<bool> ShowAsync()
{
_log.Warning(message);
return await Task.FromResult(true);
}
}
}

View File

@@ -0,0 +1,59 @@
#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using Microsoft.Extensions.Logging;
namespace ThingsGateway.Plugin.OPCUA;
public partial class OPCUAServer
{
private class OPCUALogger : ILogger
{
private ILog _log;
public OPCUALogger(ILog log)
{
_log = log;
}
/// <summary>
/// Set the log level
/// </summary>
public Microsoft.Extensions.Logging.LogLevel LogLevel { get; set; } = Microsoft.Extensions.Logging.LogLevel.Trace;
/// <inheritdoc/>
public IDisposable BeginScope<TState>(TState state) => default;
/// <inheritdoc/>
public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) => logLevel >= LogLevel;
/// <inheritdoc/>
public void Log<TState>(
Microsoft.Extensions.Logging.LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
else
{
var message = formatter(state, exception);
_log.Log((Foundation.Core.LogLevel)(byte)logLevel, state, message, exception);
if (logLevel > Microsoft.Extensions.Logging.LogLevel.Information)
{
}
}
}
}
}

View File

@@ -63,7 +63,7 @@ public partial class OPCUAServer : UpLoadBase
public override async Task BeforStartAsync(CancellationToken cancellationToken)
{
// 启动服务器。
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
await m_application.CheckApplicationInstanceCertificate(false, 0, 1200);
await m_application.Start(m_server);
}
/// <inheritdoc/>
@@ -90,7 +90,7 @@ public partial class OPCUAServer : UpLoadBase
}
catch (Exception ex)
{
LogMessage.LogWarning(ex);
LogMessage.LogWarning(ex);
}
}
@@ -98,7 +98,7 @@ public partial class OPCUAServer : UpLoadBase
}
catch (Exception ex)
{
LogMessage.LogWarning(ex);
LogMessage.LogWarning(ex);
}
if (driverPropertys.CycleInterval > UploadDeviceThread.CycleInterval + 50)
{
@@ -138,9 +138,13 @@ public partial class OPCUAServer : UpLoadBase
_uploadVariables = null;
CollectVariableRunTimes.Clear();
}
/// <inheritdoc/>
protected override void Init(UploadDeviceRunTime device)
{
ApplicationInstance.MessageDlg = new ApplicationMessageDlg(LogMessage);//默认返回true
//Utils.SetLogger(new OPCUALogger(LogMessage)); //调试用途
m_application = new ApplicationInstance();
m_configuration = GetDefaultConfiguration();
m_configuration.Validate(ApplicationType.Server).GetAwaiter().GetResult();
@@ -169,7 +173,7 @@ public partial class OPCUAServer : UpLoadBase
private ApplicationConfiguration GetDefaultConfiguration()
{
ApplicationConfiguration config = new();
string url = driverPropertys.OpcUaStringUrl;
var urls = driverPropertys.OpcUaStringUrl.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
// 签名及加密验证
ServerSecurityPolicyCollection policies = new();
var userTokens = new UserTokenPolicyCollection();
@@ -242,13 +246,14 @@ public partial class OPCUAServer : UpLoadBase
config.ApplicationName = "ThingsGateway OPCUAServer";
config.ApplicationType = ApplicationType.Server;
config.ApplicationUri = Utils.Format(@"urn:{0}:thingsgatewayopcuaserver", System.Net.Dns.GetHostName());
config.ApplicationUri = driverPropertys.ApplicationUri;
config.ServerConfiguration = new ServerConfiguration()
{
// 配置登录的地址
BaseAddresses = new string[] { url },
BaseAddresses = urls,
SecurityPolicies = policies,
UserTokenPolicies = userTokens,
ShutdownDelay = 1,
@@ -269,7 +274,7 @@ public partial class OPCUAServer : UpLoadBase
MaxNotificationQueueSize = 100, // 为每个被监视项目保存在队列中的最大证书数
MaxNotificationsPerPublish = 1000, // 每次发布的最大通知数
MinMetadataSamplingInterval = 1000, // 元数据的最小采样间隔
MaxRegistrationInterval = 30000, // 两次注册尝试之间的最大时间(以毫秒为单位)
MaxRegistrationInterval = -1, // 两次注册尝试之间的最大时间(以毫秒为单位)//不提供注册
};
config.SecurityConfiguration = new SecurityConfiguration()
@@ -283,7 +288,8 @@ public partial class OPCUAServer : UpLoadBase
{
StoreType = CertificateStoreType.X509Store,
StorePath = "CurrentUser\\UAServer_ThingsGateway",
SubjectName = "CN=ThingsGateway OPCUAServer, C=CN, S=GUANGZHOU, O=ThingsGateway, DC=" + System.Net.Dns.GetHostName(),
SubjectName = driverPropertys.SubjectName,
//ValidationOptions = CertificateValidationOptions.SuppressHostNameInvalid,
},
TrustedPeerCertificates = new CertificateTrustList()
@@ -323,7 +329,7 @@ public partial class OPCUAServer : UpLoadBase
config.CertificateValidator = new CertificateValidator();
config.CertificateValidator.Update(config);
config.CertificateValidator.Update(config).GetAwaiter().GetResult();
config.Extensions = new XmlElementCollection();
return config;

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Opc.Ua;
namespace ThingsGateway.Plugin.OPCUA;
/// <inheritdoc/>
@@ -18,8 +20,21 @@ public class OPCUAServerProperty : UpDriverPropertyBase
/// <summary>
/// 服务地址
/// </summary>
[DeviceProperty("服务地址", "")]
[DeviceProperty("服务地址", "分号分割数组可设置多个url")]
public string OpcUaStringUrl { get; set; } = "opc.tcp://127.0.0.1:49321";
/// <summary>
/// SubjectName
/// </summary>
[DeviceProperty("SubjectName", "")]
public string SubjectName { get; set; } = "CN=ThingsGateway OPCUAServer, C=CN, S=GUANGZHOU, O=ThingsGateway, DC=" + System.Net.Dns.GetHostName();
/// <summary>
/// ApplicationUri
/// </summary>
[DeviceProperty("ApplicationUri", "")]
public string ApplicationUri { get; set; } = Utils.Format(@"urn:{0}:thingsgatewayopcuaserver", System.Net.Dns.GetHostName());
/// <summary>
/// 安全策略
/// </summary>

View File

@@ -36,16 +36,24 @@ public partial class OPCUAClientPage
/// </summary>
public void Dispose()
{
OPC.OpcStatusChange -= OPC_OpcStatusChange;
OPC.SafeDispose();
}
/// <inheritdoc/>
protected override void OnInitialized()
{
OPC = new ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient(LogOut);
OPC = new ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient();
OPC.OpcStatusChange += OPC_OpcStatusChange;
base.OnInitialized();
}
private void OPC_OpcStatusChange(object sender, OpcUaStatusEventArgs e)
{
if (e.LogLevel > 0)
LogAction?.Invoke((LogLevel)e.LogLevel, null, e.Text, null);
}
private async Task ConnectAsync()
{
try
@@ -75,6 +83,4 @@ public partial class OPCUAClientPage
return OPC;
}
private void LogOut(byte logLevel, object source, string message, Exception exception) => LogAction?.Invoke((LogLevel)logLevel, source, message, exception);
}

View File

@@ -67,6 +67,8 @@ public class SQLDB : UpLoadBase
await Task.CompletedTask;
}
private bool readDBInitSuccess;
public override async Task ExecuteAsync(CancellationToken cancellationToken)
{
var db = GetHisDbAsync();
@@ -75,14 +77,33 @@ public class SQLDB : UpLoadBase
{
if (exRealTimerTick.IsTickHappen())
{
try
{
var varList = _uploadVariables.ToList().Adapt<List<SQLRealValue>>();
if (!readDBInitSuccess)
{
//事务
var result = db.UseTran(() =>
{
db.Storageable(varList).As(driverPropertys.ReadDBTableName).PageSize(10000).ExecuteSqlBulkCopy();
//db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkMerge(varList);
});
if (result.IsSuccess)//如果成功了
{
readDBInitSuccess = true;
}
else
{
throw new(result.ErrorMessage);
}
}
if (varList?.Count != 0)
{
//var result = await db.Storageable(varList).As(driverPropertys.ReadDBTableName).ExecuteCommandAsync(cancellationToken);
await db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdateAsync(varList);
db.Fastest<SQLRealValue>().AS(driverPropertys.ReadDBTableName).PageSize(100000).BulkUpdate(varList);
}
}
catch (Exception ex)
@@ -180,6 +201,7 @@ public class SQLDB : UpLoadBase
{
try
{
readDBInitSuccess = false;
_globalDeviceData?.AllVariables?.ForEach(a => a.VariableValueChange -= VariableValueChange);
_uploadVariables = null;
}
@@ -307,7 +329,7 @@ public class SQLDB : UpLoadBase
}
catch (Exception ex)
{
LogMessage.LogWarning(ex);
LogMessage.LogWarning(ex);
}
@@ -316,7 +338,7 @@ public class SQLDB : UpLoadBase
}
catch (Exception ex)
{
LogMessage.LogWarning(ex);
LogMessage.LogWarning(ex);
await CacheDb.AddCacheData("", dbInserts.ToJsonString(), driverPropertys.CacheMaxCount);
}

View File

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

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>3.0.0.16</Version>
<Version>3.0.0.23</Version>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
@@ -11,7 +11,6 @@
<SignAssembly>True</SignAssembly>
<DelaySign>False</DelaySign>
<SatelliteResourceLanguages>zh-Hans</SatelliteResourceLanguages>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>

View File

@@ -2,6 +2,7 @@
<PropertyGroup>
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>

View File

@@ -2,6 +2,7 @@
<PropertyGroup>
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>

View File

@@ -164,6 +164,7 @@ public class CollectDeviceThread : IAsyncDisposable
var stoppingToken = StoppingTokens.Last().Token;
DeviceTask = await Task.Factory.StartNew(async () =>
{
await Task.Yield();
var channelResult = CollectDeviceCores.FirstOrDefault().Driver.GetShareChannel();
LoggerGroup log = CollectDeviceCores.FirstOrDefault().Driver.LogMessage;
foreach (var device in CollectDeviceCores)

View File

@@ -153,6 +153,7 @@ public class UploadDeviceThread : IAsyncDisposable
var stoppingToken = StoppingTokens.Last().Token;
DeviceTask = await Task.Factory.StartNew(async () =>
{
await Task.Yield();
LoggerGroup log = UploadDeviceCores.FirstOrDefault().Driver.LogMessage;
foreach (var device in UploadDeviceCores)
{
@@ -225,5 +226,7 @@ public class UploadDeviceThread : IAsyncDisposable
}
, TaskCreationOptions.LongRunning);
}
}

View File

@@ -9,6 +9,7 @@
//"DbType": "MySql", //数据库类型
"ConnectionString": "Data Source=Admin.db;", //连接字符串
"DbType": "Sqlite", //数据库类型
"LanguageType": "Chinese",//中文提示
"IsAutoCloseConnection": true, //是否自动释放
"IsInitDb": true, //是否初始化数据库,适用于codefirst
"IsUnderLine": false, //是否驼峰转下划线
@@ -21,6 +22,7 @@
//"DbType": "MySql", //数据库类型
"ConnectionString": "Data Source=Log.db", //连接字符串
"DbType": "Sqlite", //数据库类型
"LanguageType": "Chinese", //中文提示
"IsAutoCloseConnection": true, //是否自动释放
"IsInitDb": true, //是否初始化数据库,适用于codefirst
"IsUnderLine": false, //是否驼峰转下划线
@@ -33,6 +35,7 @@
//"DbType": "MySql", //数据库类型
"ConnectionString": "Data Source=ThingsGateway.db", //连接字符串
"DbType": "Sqlite", //数据库类型
"LanguageType": "Chinese", //中文提示
"IsAutoCloseConnection": true, //是否自动释放
"IsInitDb": true, //是否初始化数据库,适用于codefirst
"IsUnderLine": false, //是否驼峰转下划线

View File

@@ -6,7 +6,7 @@ export const language = ["en","zh"];
export const removeDefaultStopWordFilter = false;
export const removeDefaultStemmer = false;
export { default as Mark } from "E:\\Tg\\ThingsGateway\\ThingsGateway-DEV\\handbook\\node_modules\\mark.js\\dist\\mark.js"
export const searchIndexUrl = "search-index{dir}.json?_=590a19da";
export const searchIndexUrl = "search-index{dir}.json?_=264c6792";
export const searchResultLimits = 8;
export const searchResultContextMaxLength = 50;
export const explicitSearchResultPath = true;

View File

@@ -227,9 +227,9 @@
"179": {
"js": [
{
"file": "assets/js/main.4e65a7c4.js",
"hash": "7245ddb629dafe73",
"publicPath": "/thingsgateway-docs/assets/js/main.4e65a7c4.js"
"file": "assets/js/main.90bffab9.js",
"hash": "6774eb8ed9189628",
"publicPath": "/thingsgateway-docs/assets/js/main.90bffab9.js"
}
]
},
@@ -299,9 +299,9 @@
"1303": {
"js": [
{
"file": "assets/js/runtime~main.7f6e9c09.js",
"hash": "aedff306f0f845ba",
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.7f6e9c09.js"
"file": "assets/js/runtime~main.2d62406a.js",
"hash": "fc67bb23388f4a51",
"publicPath": "/thingsgateway-docs/assets/js/runtime~main.2d62406a.js"
}
]
},
@@ -326,9 +326,9 @@
"1822": {
"js": [
{
"file": "assets/js/f05a39b7.bfb8e652.js",
"hash": "3d8f498000b417cb",
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.bfb8e652.js"
"file": "assets/js/f05a39b7.a300eca8.js",
"hash": "67b94ba06477a5ab",
"publicPath": "/thingsgateway-docs/assets/js/f05a39b7.a300eca8.js"
}
]
},
@@ -398,9 +398,9 @@
"3371": {
"js": [
{
"file": "assets/js/d22033f9.6a725d32.js",
"hash": "edd7fef77b05ef57",
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.6a725d32.js"
"file": "assets/js/d22033f9.838d285d.js",
"hash": "b8c8ee41012bac15",
"publicPath": "/thingsgateway-docs/assets/js/d22033f9.838d285d.js"
}
]
},
@@ -619,9 +619,9 @@
"8707": {
"js": [
{
"file": "assets/js/4c79e569.3f1e7d8c.js",
"hash": "5ca0c0dec325073e",
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.3f1e7d8c.js"
"file": "assets/js/4c79e569.b07342bd.js",
"hash": "c0362a85c0105049",
"publicPath": "/thingsgateway-docs/assets/js/4c79e569.b07342bd.js"
}
]
},

View File

@@ -12,8 +12,8 @@
"tags": [],
"version": "current",
"lastUpdatedBy": "Kimdiego2098",
"lastUpdatedAt": 1695729838,
"formattedLastUpdatedAt": "Sep 26, 2023",
"lastUpdatedAt": 1697449154,
"formattedLastUpdatedAt": "Oct 16, 2023",
"frontMatter": {
"id": "enterprise",
"title": "Pro版相关"

View File

@@ -11,9 +11,9 @@
"editUrl": "https://gitee.com/diego2098/ThingsGateway/tree/master/handbook/docs/upgrade.mdx",
"tags": [],
"version": "current",
"lastUpdatedBy": "Diego2098",
"lastUpdatedAt": 1691418711,
"formattedLastUpdatedAt": "Aug 7, 2023",
"lastUpdatedBy": "Kimdiego2098",
"lastUpdatedAt": 1697718988,
"formattedLastUpdatedAt": "Oct 19, 2023",
"frontMatter": {
"id": "upgrade",
"title": "历史更新"

File diff suppressed because one or more lines are too long

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