mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-26 05:20:16 +08:00
Compare commits
5 Commits
10.11.24.0
...
10.11.29.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e00e8c135 | ||
|
|
34dd2cf0a7 | ||
|
|
8404e20c5e | ||
|
|
662aa162e9 | ||
|
|
5927738c32 |
@@ -738,7 +738,7 @@ namespace ThingsGateway.SqlSugar
|
||||
.Where(it => it.Name == "Insertable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("IReadOnlyCollection")))
|
||||
.Where(it => it.Name == "Insertable");
|
||||
;
|
||||
var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First());
|
||||
InsertMethodInfo result = new InsertMethodInfo()
|
||||
{
|
||||
@@ -751,11 +751,11 @@ namespace ThingsGateway.SqlSugar
|
||||
else
|
||||
{
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Insertable")
|
||||
.Where(it => it.Name == "InsertableT" || it.Name == "Insertable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"))
|
||||
.Where(it => it.Name == "Insertable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"));
|
||||
var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType());
|
||||
|
||||
InsertMethodInfo result = new InsertMethodInfo()
|
||||
{
|
||||
Context = this.Context,
|
||||
@@ -826,8 +826,7 @@ namespace ThingsGateway.SqlSugar
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Deleteable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.Name != "pkValue" && z.ParameterType.Name.StartsWith("IReadOnlyCollection")))
|
||||
.Where(it => it.Name == "Deleteable");
|
||||
.Where(it => it.GetParameters().Any(z => z.Name != "pkValue" && z.ParameterType.Name.StartsWith("IReadOnlyCollection")));
|
||||
var method = methods.FirstOrDefault().MakeGenericMethod(newList.GetType().GetGenericArguments().FirstOrDefault());
|
||||
DeleteMethodInfo result = new DeleteMethodInfo()
|
||||
{
|
||||
@@ -840,10 +839,9 @@ namespace ThingsGateway.SqlSugar
|
||||
else
|
||||
{
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Deleteable")
|
||||
.Where(it => it.Name == "Deleteable" || it.Name == "DeleteableT")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"))
|
||||
.Where(it => it.Name == "Deleteable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"));
|
||||
var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType());
|
||||
DeleteMethodInfo result = new DeleteMethodInfo()
|
||||
{
|
||||
@@ -911,8 +909,7 @@ namespace ThingsGateway.SqlSugar
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Updateable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("IReadOnlyCollection")))
|
||||
.Where(it => it.Name == "Updateable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("IReadOnlyCollection")));
|
||||
var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First());
|
||||
UpdateMethodInfo result = new UpdateMethodInfo()
|
||||
{
|
||||
@@ -925,10 +922,9 @@ namespace ThingsGateway.SqlSugar
|
||||
else
|
||||
{
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Updateable")
|
||||
.Where(it => it.Name == "UpdateableT" || it.Name == "Updateable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"))
|
||||
.Where(it => it.Name == "Updateable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"));
|
||||
var method = methods.Single().MakeGenericMethod(singleEntityObjectOrListObject.GetType());
|
||||
UpdateMethodInfo result = new UpdateMethodInfo()
|
||||
{
|
||||
@@ -943,10 +939,9 @@ namespace ThingsGateway.SqlSugar
|
||||
{
|
||||
UpdateExpressionMethodInfo result = new UpdateExpressionMethodInfo();
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Updateable")
|
||||
.Where(it => it.Name == "UpdateableT" || it.Name == "Updateable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Length == 0)
|
||||
.Where(it => it.Name == "Updateable");
|
||||
.Where(it => it.GetParameters().Length == 0);
|
||||
var method = methods.Single().MakeGenericMethod(entityType);
|
||||
result.Context = this.Context;
|
||||
result.MethodInfo = method;
|
||||
@@ -1109,8 +1104,7 @@ namespace ThingsGateway.SqlSugar
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Storageable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("IEnumerable")))
|
||||
.Where(it => it.Name == "Storageable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name.StartsWith("IEnumerable")));
|
||||
var method = methods.Single().MakeGenericMethod(newList.GetType().GetGenericArguments().First());
|
||||
StorageableMethodInfo result = new StorageableMethodInfo()
|
||||
{
|
||||
@@ -1123,10 +1117,9 @@ namespace ThingsGateway.SqlSugar
|
||||
else
|
||||
{
|
||||
var methods = this.Context.GetType().GetMethods()
|
||||
.Where(it => it.Name == "Storageable")
|
||||
.Where(it => it.Name == "StorageableT" || it.Name == "Storageable")
|
||||
.Where(it => it.GetGenericArguments().Length != 0)
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"))
|
||||
.Where(it => it.Name == "Storageable");
|
||||
.Where(it => it.GetParameters().Any(z => z.ParameterType.Name == "T"));
|
||||
var method = methods.Single().MakeGenericMethod(singleEntityObjectOrList.GetType());
|
||||
StorageableMethodInfo result = new StorageableMethodInfo()
|
||||
{
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SqlSugarCore.Dm" Version="8.8.2" />
|
||||
<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.821" />
|
||||
<PackageReference Include="SqlSugarCore.Kdbndp" Version="9.3.7.905" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.20" />
|
||||
<!--<PackageReference Include="Microsoft.Data.Sqlite" Version="$(NET9Version)" />-->
|
||||
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
||||
<PackageReference Include="Npgsql" Version="9.0.3" />
|
||||
<PackageReference Include="CsvHelper" Version="33.1.0" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.1.8" />
|
||||
<PackageReference Include="TDengine.Connector" Version="3.1.9" />
|
||||
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="23.9.1" />
|
||||
<PackageReference Include="Oscar.Data.SqlClient" Version="4.2.23" />
|
||||
<PackageReference Include="System.Data.Common" Version="4.3.0" />
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.11.24</PluginVersion>
|
||||
<ProPluginVersion>10.11.24</ProPluginVersion>
|
||||
<DefaultVersion>10.11.24</DefaultVersion>
|
||||
<PluginVersion>10.11.29</PluginVersion>
|
||||
<ProPluginVersion>10.11.29</ProPluginVersion>
|
||||
<DefaultVersion>10.11.29</DefaultVersion>
|
||||
<AuthenticationVersion>10.11.3</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.11.3</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.19</NET8Version>
|
||||
|
||||
@@ -49,12 +49,11 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
this.ThrowIfDisposed();
|
||||
this.ThrowIfClientNotConnected();
|
||||
|
||||
|
||||
if (!await this.OnTcpSending(memory).ConfigureAwait(false)) return;
|
||||
|
||||
var transport = this.Transport;
|
||||
var adapter = this.DataHandlingAdapter;
|
||||
var locker = transport.SemaphoreSlimForWriter;
|
||||
var locker = transport.WriteLocker;
|
||||
|
||||
await locker.WaitAsync(token).ConfigureAwait(false);
|
||||
try
|
||||
@@ -62,7 +61,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
// 如果数据处理适配器未设置,则使用默认发送方式。
|
||||
if (adapter == null)
|
||||
{
|
||||
await transport.Output.WriteAsync(memory, token).ConfigureAwait(false);
|
||||
await transport.Writer.WriteAsync(memory, token).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -70,7 +69,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
var ddpSend = new DDPSend(memory, Id, true);
|
||||
ddpSend.Build(ref byteBlock);
|
||||
var newMemory = byteBlock.Memory;
|
||||
var writer = new PipeBytesWriter(transport.Output);
|
||||
var writer = new PipeBytesWriter(transport.Writer);
|
||||
adapter.SendInput(ref writer, in newMemory);
|
||||
await writer.FlushAsync(token).ConfigureAwait(false);
|
||||
}
|
||||
@@ -100,7 +99,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
|
||||
var transport = this.Transport;
|
||||
var adapter = this.DataHandlingAdapter;
|
||||
var locker = transport.SemaphoreSlimForWriter;
|
||||
var locker = transport.WriteLocker;
|
||||
|
||||
await locker.WaitAsync(token).ConfigureAwait(false);
|
||||
try
|
||||
@@ -113,7 +112,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
|
||||
requestInfoBuilder.Build(ref byteBlock);
|
||||
var ddpSend = new DDPSend(byteBlock.Memory, Id, true);
|
||||
|
||||
var writer = new PipeBytesWriter(transport.Output);
|
||||
var writer = new PipeBytesWriter(transport.Writer);
|
||||
adapter.SendInput(ref writer, ddpSend);
|
||||
await writer.FlushAsync(token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation;
|
||||
/// <summary>
|
||||
/// 终端通道
|
||||
/// </summary>
|
||||
public interface IClientChannel : IChannel, ISender, IClient, IClientSender, IOnlineClient
|
||||
public interface IClientChannel : IChannel, ISender, IClient, IClientSender, IOnlineClient, IDependencyClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前通道的数据处理适配器
|
||||
|
||||
@@ -34,7 +34,26 @@ public static class PluginUtil
|
||||
|
||||
if (channelOptions.ChannelType == ChannelTypeEnum.TcpClient)
|
||||
{
|
||||
action += a => a.UseReconnection<ITcpClient>();
|
||||
action += a => a.UseReconnection<IClientChannel>().SetActionForCheck((channel, failCount) =>
|
||||
{
|
||||
if (channel.Online)
|
||||
{
|
||||
return Task.FromResult(ConnectionCheckResult.Alive);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (failCount > 1)
|
||||
{
|
||||
return Task.FromResult(ConnectionCheckResult.Dead);
|
||||
}
|
||||
return Task.FromResult(ConnectionCheckResult.Skip);
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
.SetPollingTick(TimeSpan.FromSeconds(5)
|
||||
|
||||
);
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="$(NET9Version)" />
|
||||
<PackageReference Include="TouchSocket" Version="4.0.0-beta.13" />
|
||||
<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.13" />
|
||||
<PackageReference Include="TouchSocket" Version="4.0.0-beta.25" />
|
||||
<PackageReference Include="TouchSocket.SerialPorts" Version="4.0.0-beta.25" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<Import Project="..\..\PackNuget.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -48,18 +48,6 @@ public class ControlController : ControllerBase, IRpcServer
|
||||
App.CacheService.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除通道/设备缓存
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("removeCache")]
|
||||
[DisplayName("删除通道/设备缓存")]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public void RemoveCache()
|
||||
{
|
||||
App.GetService<IDeviceService>().DeleteDeviceFromCache();
|
||||
App.GetService<IChannelService>().DeleteChannelFromCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控制设备线程暂停
|
||||
@@ -226,6 +214,17 @@ public class ControlController : ControllerBase, IRpcServer
|
||||
return GlobalData.VariableRuntimeService.InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加测试Dtu数据
|
||||
/// </summary>
|
||||
[HttpPost("insertTestDtuData")]
|
||||
[DisplayName("增加测试Dtu数据")]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart = true)
|
||||
{
|
||||
return GlobalData.VariableRuntimeService.InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确认实时报警
|
||||
/// </summary>
|
||||
|
||||
@@ -77,7 +77,7 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
App.GetService<IDevicePageService>().ClearDeviceAsync(restart);
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task ClearRulesAsync() => App.GetService<IRulesService>().ClearRulesAsync();
|
||||
public Task ClearRulesAsync() => App.GetService<IRulesPageService>().ClearRulesAsync();
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task<bool> ClearVariableAsync(bool restart) =>
|
||||
@@ -140,7 +140,7 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
public Task DeleteRuleRuntimesAsync(List<long> ids) => App.GetService<IRulesEngineHostedService>().DeleteRuleRuntimesAsync(ids);
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task<bool> DeleteRulesAsync(List<long> ids) => App.GetService<IRulesService>().DeleteRulesAsync(ids);
|
||||
public Task<bool> DeleteRulesAsync(List<long> ids) => App.GetService<IRulesPageService>().DeleteRulesAsync(ids);
|
||||
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
@@ -200,13 +200,6 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
public Task<List<Variable>> GetVariableListAsync([FromBody] GetListRequest<QueryPageOptions> request) =>
|
||||
App.GetService<IVariablePageService>().GetVariableListAsync(request.Options, request.Max);
|
||||
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
|
||||
public Task<List<Rules>> GetAllRulesAsync() => App.GetService<IRulesService>().GetAllRulesAsync();
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Get)]
|
||||
public Task<string> GetChannelNameAsync(long id) =>
|
||||
@@ -345,6 +338,14 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
public Task InsertTestDataAsync([FromBody] InsertTestDataInput input) =>
|
||||
App.GetService<IVariablePageService>().InsertTestDataAsync(input.TestVariableCount, input.TestDeviceCount, input.SlaveUrl, input.BusinessEnable, input.Restart);
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task InsertTestDtuDataAsync([FromBody] InsertTestDtuDataInput input) =>
|
||||
App.GetService<IVariablePageService>().InsertTestDtuDataAsync(input.TestDeviceCount, input.SlaveUrl, input.Restart);
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task<bool> IsRedundantDeviceAsync(long id) =>
|
||||
@@ -458,7 +459,7 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task<QueryData<Rules>> RulesPageAsync([FromBody] KVQueryPageOptions option) =>
|
||||
App.GetService<IRulesService>().RulesPageAsync(option.Options, option.FilterKeyValueAction);
|
||||
App.GetService<IRulesPageService>().RulesPageAsync(option.Options, option.FilterKeyValueAction);
|
||||
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
@@ -478,7 +479,7 @@ public partial class ManagementController : ControllerBase, IRpcServer
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
public Task<bool> SaveRulesAsync([FromBody] Rules input, ItemChangedType type) =>
|
||||
App.GetService<IRulesService>().SaveRulesAsync(input, type);
|
||||
App.GetService<IRulesPageService>().SaveRulesAsync(input, type);
|
||||
|
||||
[HttpPost]
|
||||
[TouchSocket.WebApi.WebApi(Method = TouchSocket.WebApi.HttpMethodType.Post)]
|
||||
@@ -635,7 +636,12 @@ public class InsertTestDataInput
|
||||
public bool BusinessEnable { get; set; }
|
||||
public bool Restart { get; set; }
|
||||
}
|
||||
|
||||
public class InsertTestDtuDataInput
|
||||
{
|
||||
public int TestDeviceCount { get; set; }
|
||||
public string SlaveUrl { get; set; }
|
||||
public bool Restart { get; set; }
|
||||
}
|
||||
public class LastLogDataInput
|
||||
{
|
||||
public string File { get; set; }
|
||||
|
||||
@@ -61,7 +61,7 @@ public class LogJob : IJob
|
||||
|
||||
//网关通道日志以通道id命名
|
||||
var rulesService = App.RootServices.GetService<IRulesService>();
|
||||
var ruleNames = (await rulesService.GetAllRulesAsync().ConfigureAwait(false)).Select(a => a.Name.ToString()).ToHashSet();
|
||||
var ruleNames = (await rulesService.GetFromDBAsync(a => a.Name.ToString()).ConfigureAwait(false)).ToHashSet();
|
||||
var ruleBaseDir = RulesEngineHostedService.LogDir;
|
||||
Directory.CreateDirectory(ruleBaseDir);
|
||||
|
||||
|
||||
@@ -58,9 +58,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
App.GetService<IDeviceService>().DeleteDeviceFromCache();
|
||||
App.GetService<IVariableService>().DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -87,9 +85,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
App.GetService<IDeviceService>().DeleteDeviceFromCache();
|
||||
App.GetService<IVariableService>().DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -124,9 +120,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
App.GetService<IDeviceService>().DeleteDeviceFromCache();
|
||||
App.GetService<IVariableService>().DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -149,7 +143,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -181,7 +175,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -214,7 +208,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -224,11 +218,6 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DeleteChannelFromCache()
|
||||
{
|
||||
//App.CacheService.Remove(ThingsGatewayCacheConst.Cache_Channel);//删除通道缓存
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -299,7 +288,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -320,7 +309,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteChannelFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -404,7 +393,7 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
DeleteChannelFromCache();
|
||||
|
||||
return upData.Select(a => a.Id).Concat(insertData.Select(a => a.Id)).ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,11 +38,6 @@ internal interface IChannelService
|
||||
/// <param name="ids">待删除通道的ID列表</param>
|
||||
Task<bool> DeleteChannelAsync(IEnumerable<long> ids);
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中删除通道
|
||||
/// </summary>
|
||||
void DeleteChannelFromCache();
|
||||
|
||||
/// <summary>
|
||||
/// 导出通道为文件流结果
|
||||
/// </summary>
|
||||
|
||||
@@ -63,8 +63,6 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
App.GetService<IVariableService>().DeleteVariableCache();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -87,7 +85,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -112,8 +110,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
.WhereIf(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||
.ToList();
|
||||
var result = (await db.Updateable(data).UpdateColumns(differences.Select(a => a.Key).ToArray()).ExecuteCommandAsync().ConfigureAwait(false)) > 0;
|
||||
if (result)
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
@@ -141,7 +138,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -169,7 +166,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -179,12 +176,6 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DeleteDeviceFromCache()
|
||||
{
|
||||
//App.CacheService.Remove(ThingsGatewayCacheConst.Cache_Device);//删除设备缓存
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存/数据库获取全部信息
|
||||
/// </summary>
|
||||
@@ -274,7 +265,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -290,7 +281,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -400,7 +391,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
await db.BulkCopyAsync(insertData, 200000).ConfigureAwait(false);
|
||||
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||
}
|
||||
DeleteDeviceFromCache();
|
||||
|
||||
return upData.Select(a => a.Id).Concat(insertData.Select(a => a.Id)).ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,10 +51,6 @@ internal interface IDeviceService
|
||||
/// <returns>删除是否成功的异步任务</returns>
|
||||
Task<bool> DeleteDeviceAsync(IEnumerable<long> ids);
|
||||
|
||||
/// <summary>
|
||||
/// 删除设备缓存信息。
|
||||
/// </summary>
|
||||
void DeleteDeviceFromCache();
|
||||
|
||||
/// <summary>
|
||||
/// 导出设备信息到文件流。
|
||||
|
||||
@@ -134,12 +134,6 @@ public interface IManagementRpcServer : IRpcServer
|
||||
[DmtpRpc]
|
||||
Task<string> ExportVariableFileAsync(GatewayExportFilter exportFilter);
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存/数据库获取全部信息
|
||||
/// </summary>
|
||||
/// <returns>规则列表</returns>
|
||||
[DmtpRpc]
|
||||
Task<List<Rules>> GetAllRulesAsync();
|
||||
|
||||
[DmtpRpc]
|
||||
Task<List<Channel>> GetChannelListAsync(QueryPageOptions options, int max = 0);
|
||||
@@ -227,7 +221,8 @@ public interface IManagementRpcServer : IRpcServer
|
||||
|
||||
[DmtpRpc]
|
||||
Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart);
|
||||
|
||||
[DmtpRpc]
|
||||
Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart);
|
||||
[DmtpRpc]
|
||||
Task<bool> IsRedundantDeviceAsync(long id);
|
||||
|
||||
@@ -287,6 +282,8 @@ public interface IManagementRpcServer : IRpcServer
|
||||
|
||||
[DmtpRpc]
|
||||
Task RestartDeviceAsync(long id, bool deleteCache);
|
||||
[DmtpRpc]
|
||||
Task RestartRuleRuntimeAsync();
|
||||
|
||||
[DmtpRpc]
|
||||
Task RestartServerAsync();
|
||||
|
||||
@@ -48,7 +48,7 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
public Task<bool> ClearDeviceAsync(bool restart) =>
|
||||
App.GetService<IDevicePageService>().ClearDeviceAsync(restart);
|
||||
|
||||
public Task ClearRulesAsync() => App.GetService<IRulesService>().ClearRulesAsync();
|
||||
public Task ClearRulesAsync() => App.GetService<IRulesPageService>().ClearRulesAsync();
|
||||
|
||||
public Task<bool> ClearVariableAsync(bool restart) =>
|
||||
App.GetService<IVariablePageService>().ClearVariableAsync(restart);
|
||||
@@ -75,7 +75,7 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
|
||||
public Task DeleteRuleRuntimesAsync(List<long> ids) => App.GetService<IRulesEngineHostedService>().DeleteRuleRuntimesAsync(ids);
|
||||
|
||||
public Task<bool> DeleteRulesAsync(List<long> ids) => App.GetService<IRulesService>().DeleteRulesAsync(ids);
|
||||
public Task<bool> DeleteRulesAsync(List<long> ids) => App.GetService<IRulesPageService>().DeleteRulesAsync(ids);
|
||||
|
||||
public Task<bool> DeleteVariableAsync(List<long> ids, bool restart) =>
|
||||
App.GetService<IVariablePageService>().DeleteVariableAsync(ids, restart);
|
||||
@@ -107,8 +107,6 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
|
||||
public Task<string> ExportVariableFileAsync(GatewayExportFilter exportFilter) => App.GetService<IVariablePageService>().ExportVariableFileAsync(exportFilter);
|
||||
|
||||
public Task<List<Rules>> GetAllRulesAsync() => App.GetService<IRulesService>().GetAllRulesAsync();
|
||||
|
||||
public Task<List<Channel>> GetChannelListAsync(QueryPageOptions options, int max = 0) =>
|
||||
App.GetService<IChannelPageService>().GetChannelListAsync(options, max);
|
||||
|
||||
@@ -181,6 +179,10 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
public Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart) =>
|
||||
App.GetService<IVariablePageService>().InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart);
|
||||
|
||||
public Task InsertTestDtuDataAsync(int testDeviceCount, string slaveUrl, bool restart) =>
|
||||
App.GetService<IVariablePageService>().InsertTestDtuDataAsync(testDeviceCount, slaveUrl, restart);
|
||||
|
||||
|
||||
public Task<bool> IsRedundantDeviceAsync(long id) =>
|
||||
App.GetService<IDevicePageService>().IsRedundantDeviceAsync(id);
|
||||
|
||||
@@ -244,7 +246,7 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
|
||||
public Task<string> RulesLogPathAsync(long rulesId) => App.GetService<IRulesEngineHostedService>().RulesLogPathAsync(rulesId);
|
||||
|
||||
public Task<QueryData<Rules>> RulesPageAsync(QueryPageOptions option, FilterKeyValueAction filterKeyValueAction = null) => App.GetService<IRulesService>().RulesPageAsync(option, filterKeyValueAction);
|
||||
public Task<QueryData<Rules>> RulesPageAsync(QueryPageOptions option, FilterKeyValueAction filterKeyValueAction = null) => App.GetService<IRulesPageService>().RulesPageAsync(option, filterKeyValueAction);
|
||||
|
||||
public Task<bool> SaveChannelAsync(Channel input, ItemChangedType type, bool restart) =>
|
||||
App.GetService<IChannelPageService>().SaveChannelAsync(input, type, restart);
|
||||
@@ -254,7 +256,7 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
|
||||
public Task SavePluginByPathAsync(PluginAddPathInput plugin) => App.GetService<IPluginPageService>().SavePluginByPathAsync(plugin);
|
||||
|
||||
public Task<bool> SaveRulesAsync(Rules input, ItemChangedType type) => App.GetService<IRulesService>().SaveRulesAsync(input, type);
|
||||
public Task<bool> SaveRulesAsync(Rules input, ItemChangedType type) => App.GetService<IRulesPageService>().SaveRulesAsync(input, type);
|
||||
|
||||
public Task<bool> SaveVariableAsync(Variable input, ItemChangedType type, bool restart) =>
|
||||
App.GetService<IVariablePageService>().SaveVariableAsync(input, type, restart);
|
||||
@@ -284,4 +286,7 @@ public partial class ManagementRpcServer : IRpcServer, IManagementRpcServer, IBa
|
||||
public Task UnAuthorizeAsync() => App.GetService<IAuthenticationService>().UnAuthorizeAsync();
|
||||
|
||||
public Task<string> UUIDAsync() => App.GetService<IAuthenticationService>().UUIDAsync();
|
||||
|
||||
public Task RestartRuleRuntimeAsync() => App.GetService<IRulesEngineHostedService>().RestartRuleRuntimeAsync();
|
||||
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public partial class ManagementTask : AsyncDisposableObject
|
||||
var config = new TouchSocketConfig()
|
||||
.SetRemoteIPHost(_managementOptions.ServerUri)
|
||||
.SetAdapterOption(new AdapterOption() { MaxPackageSize = 1024 * 1024 * 1024 })
|
||||
.SetDmtpOption(new DmtpOption() { VerifyToken = _managementOptions.VerifyToken })
|
||||
.SetDmtpOption(a => a.VerifyToken = _managementOptions.VerifyToken)
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
a.AddDmtpRouteService();//添加路由策略
|
||||
@@ -134,7 +134,7 @@ public partial class ManagementTask : AsyncDisposableObject
|
||||
.SetTick(TimeSpan.FromMilliseconds(_managementOptions.HeartbeatInterval))
|
||||
.SetMaxFailCount(3);
|
||||
|
||||
a.AddDmtpHandshakedPlugin(async () =>
|
||||
a.AddDmtpCreatedChannelPlugin(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -157,7 +157,7 @@ public partial class ManagementTask : AsyncDisposableObject
|
||||
var config = new TouchSocketConfig()
|
||||
.SetListenIPHosts(_managementOptions.ServerUri)
|
||||
.SetAdapterOption(new AdapterOption() { MaxPackageSize = 1024 * 1024 * 1024 })
|
||||
.SetDmtpOption(new DmtpOption() { VerifyToken = _managementOptions.VerifyToken })
|
||||
.SetDmtpOption(a => a.VerifyToken = _managementOptions.VerifyToken)
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
a.AddDmtpRouteService();//添加路由策略
|
||||
|
||||
@@ -332,7 +332,7 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
|
||||
var config = new TouchSocketConfig()
|
||||
.SetRemoteIPHost(redundancy.MasterUri)
|
||||
.SetAdapterOption(new AdapterOption() { MaxPackageSize = 0x20000000 })
|
||||
.SetDmtpOption(new DmtpOption() { VerifyToken = redundancy.VerifyToken })
|
||||
.SetDmtpOption(a => a.VerifyToken = redundancy.VerifyToken)
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
a.AddLogger(LogMessage);
|
||||
@@ -377,7 +377,7 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
|
||||
var config = new TouchSocketConfig()
|
||||
.SetListenIPHosts(redundancy.MasterUri)
|
||||
.SetAdapterOption(new AdapterOption() { MaxPackageSize = 0x20000000 })
|
||||
.SetDmtpOption(new DmtpOption() { VerifyToken = redundancy.VerifyToken })
|
||||
.SetDmtpOption(a => a.VerifyToken = redundancy.VerifyToken)
|
||||
.ConfigureContainer(a =>
|
||||
{
|
||||
a.AddLogger(LogMessage);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// QQ群:605534569
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public interface IRulesEngineHostedService
|
||||
@@ -18,4 +19,6 @@ public interface IRulesEngineHostedService
|
||||
Task<Rules> GetRuleRuntimesAsync(long rulesId);
|
||||
Task DeleteRuleRuntimesAsync(List<long> ids);
|
||||
Task EditRuleRuntimesAsync(Rules rules);
|
||||
Task RestartRuleRuntimeAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
public interface IRulesService
|
||||
public interface IRulesPageService
|
||||
{
|
||||
/// <summary>
|
||||
/// 清除所有规则
|
||||
@@ -25,12 +27,6 @@ public interface IRulesService
|
||||
/// <param name="ids">待删除规则的ID列表</param>
|
||||
Task<bool> DeleteRulesAsync(List<long> ids);
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存/数据库获取全部信息
|
||||
/// </summary>
|
||||
/// <returns>规则列表</returns>
|
||||
Task<List<Rules>> GetAllRulesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 报表查询
|
||||
/// </summary>
|
||||
@@ -45,3 +41,13 @@ public interface IRulesService
|
||||
/// <param name="type">保存类型</param>
|
||||
Task<bool> SaveRulesAsync(Rules input, ItemChangedType type);
|
||||
}
|
||||
public interface IRulesService : IRulesPageService
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存/数据库获取全部信息
|
||||
/// </summary>
|
||||
/// <returns>规则列表</returns>
|
||||
Task<List<TResult>> GetFromDBAsync<TResult>(Expression<Func<Rules, TResult>> slct, Expression<Func<Rules, bool>> expression = null, SqlSugarClient db = null);
|
||||
|
||||
}
|
||||
@@ -234,13 +234,31 @@ internal sealed class RulesEngineHostedService : BackgroundService, IRulesEngine
|
||||
{
|
||||
await Task.Yield();
|
||||
|
||||
await RestartRuleRuntimeAsync().ConfigureAwait(false);
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var item in Diagrams?.Values?.SelectMany(a => a.Nodes) ?? new List<NodeModel>())
|
||||
{
|
||||
if (item is IExexcuteExpressionsBase)
|
||||
{
|
||||
CSharpScriptEngineExtension.SetExpire((item as TextNode).Text);
|
||||
}
|
||||
}
|
||||
await Task.Delay(60000, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RestartRuleRuntimeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await RestartLock.WaitAsync(cancellationToken).ConfigureAwait(false); // 等待获取锁,以确保只有一个线程可以执行以下代码
|
||||
TokenSource ??= new CancellationTokenSource();
|
||||
await RestartLock.WaitAsync().ConfigureAwait(false);
|
||||
Cancel();
|
||||
Clear();
|
||||
TokenSource ??= new CancellationTokenSource();
|
||||
|
||||
Rules = await App.GetService<IRulesService>().GetAllRulesAsync().ConfigureAwait(false);
|
||||
Rules = await App.GetService<IRulesService>().GetFromDBAsync(a => a).ConfigureAwait(false);
|
||||
Diagrams = new();
|
||||
foreach (var rules in Rules.Where(a => a.Status))
|
||||
{
|
||||
@@ -259,18 +277,6 @@ internal sealed class RulesEngineHostedService : BackgroundService, IRulesEngine
|
||||
{
|
||||
RestartLock.Release(); // 释放锁
|
||||
}
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
foreach (var item in Diagrams?.Values?.SelectMany(a => a.Nodes) ?? new List<NodeModel>())
|
||||
{
|
||||
if (item is IExexcuteExpressionsBase)
|
||||
{
|
||||
CSharpScriptEngineExtension.SetExpire((item as TextNode).Text);
|
||||
}
|
||||
}
|
||||
await Task.Delay(60000, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task StopAsync(CancellationToken cancellationToken)
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
using BootstrapBlazor.Components;
|
||||
|
||||
using System.Data;
|
||||
|
||||
using ThingsGateway.Extension.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -38,15 +36,12 @@ internal sealed class RulesService : BaseService<Rules>, IRulesService
|
||||
var dataScope = await GlobalData.SysUserService.GetCurrentUserDataScopeAsync().ConfigureAwait(false);
|
||||
|
||||
using var db = GetDB();
|
||||
var ids = await db.Queryable<Rules>().WhereIF(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.CreateOrgId))//在指定机构列表查询
|
||||
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||
.Select(a => a.Id).ToListAsync().ConfigureAwait(false);
|
||||
await db.Deleteable<Rules>(a => ids.Contains(a.Id)).ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
var data = (await GetAllRulesAsync().ConfigureAwait(false))
|
||||
.WhereIf(dataScope != null && dataScope?.Count > 0, u => dataScope.Contains(u.CreateOrgId))//在指定机构列表查询
|
||||
.WhereIf(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||
.Select(a => a.Id).ToList();
|
||||
await db.Deleteable<Rules>(a => data.Contains(a.Id)).ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
DeleteRulesFromCache();
|
||||
await RulesEngineHostedService.DeleteRuleRuntimesAsync(data).ConfigureAwait(false);
|
||||
await RulesEngineHostedService.DeleteRuleRuntimesAsync(ids).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[OperDesc("DeleteRules", localizerType: typeof(Rules))]
|
||||
@@ -60,30 +55,20 @@ internal sealed class RulesService : BaseService<Rules>, IRulesService
|
||||
|
||||
.ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
DeleteRulesFromCache();
|
||||
await RulesEngineHostedService.DeleteRuleRuntimesAsync(ids).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
private const string cacheKey = "ThingsGateway:Cache_RulesEngines:List";
|
||||
/// <inheritdoc />
|
||||
public void DeleteRulesFromCache()
|
||||
{
|
||||
App.CacheService.Remove(cacheKey);//删除通道缓存
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存/数据库获取全部信息
|
||||
/// </summary>
|
||||
/// <returns>列表</returns>
|
||||
public async Task<List<Rules>> GetAllRulesAsync()
|
||||
public async Task<List<TResult>> GetFromDBAsync<TResult>(Expression<Func<Rules, TResult>> slct, Expression<Func<Rules, bool>> expression = null, SqlSugarClient db = null)
|
||||
{
|
||||
var channels = App.CacheService.Get<List<Rules>>(cacheKey);
|
||||
if (channels == null)
|
||||
{
|
||||
using var db = GetDB();
|
||||
channels = await db.Queryable<Rules>().ToListAsync().ConfigureAwait(false);
|
||||
App.CacheService.Set(cacheKey, channels);
|
||||
}
|
||||
db ??= GetDB();
|
||||
var channels = await db.Queryable<Rules>().WhereIF(expression != null, expression).OrderBy(a => a.Id).Select(slct).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
@@ -117,7 +102,6 @@ internal sealed class RulesService : BaseService<Rules>, IRulesService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteRulesFromCache();
|
||||
await RulesEngineHostedService.EditRuleRuntimesAsync(input).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -35,5 +35,6 @@ namespace ThingsGateway.Gateway.Application
|
||||
Task<OperResult<object>> OnWriteVariableAsync(long id, string writeData);
|
||||
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableAsync(IBrowserFile a, bool restart);
|
||||
Task<Dictionary<string, ImportPreviewOutputBase>> ImportVariableFileAsync(string filePath, bool restart);
|
||||
Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart);
|
||||
}
|
||||
}
|
||||
@@ -106,10 +106,10 @@ internal interface IVariableService
|
||||
Task UpdateInitValueAsync(List<Variable> variables);
|
||||
|
||||
Task<List<Variable>> GetByDeviceIdAsync(List<long> deviceIds);
|
||||
void DeleteVariableCache();
|
||||
ImportPreviewOutput<Dictionary<string, Variable>> SetVariableData(HashSet<long>? dataScope, IReadOnlyDictionary<string, DeviceRuntime> deviceDicts, Dictionary<string, ImportPreviewOutputBase> ImportPreviews, ImportPreviewOutput<Dictionary<string, Variable>> deviceImportPreview, Dictionary<string, PluginInfo> driverPluginNameDict, ConcurrentDictionary<string, (Type, Dictionary<string, PropertyInfo>, Dictionary<string, PropertyInfo>)> propertysDict, string sheetName, IEnumerable<IDictionary<string, object>> rows);
|
||||
List<VariableRuntime> GetAllVariableRuntime();
|
||||
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(string filePath);
|
||||
Task<HashSet<long>> ImportVariableAsync(List<Variable> upData, List<Variable> insertData);
|
||||
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IFormFile browserFile);
|
||||
Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502");
|
||||
}
|
||||
|
||||
@@ -423,6 +423,45 @@ public class VariableRuntimeService : IVariableRuntimeService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InsertTestDtuDataAsync(int deviceCount, string slaveUrl, bool restart)
|
||||
{
|
||||
try
|
||||
{
|
||||
// await WaitLock.WaitAsync().ConfigureAwait(false);
|
||||
|
||||
var datas = await GlobalData.VariableService.InsertTestDtuDataAsync(deviceCount, slaveUrl).ConfigureAwait(false);
|
||||
|
||||
{
|
||||
var newChannelRuntimes = datas.Item1.AdaptListChannelRuntime();
|
||||
|
||||
//批量修改之后,需要重新加载通道
|
||||
RuntimeServiceHelper.Init(newChannelRuntimes);
|
||||
|
||||
{
|
||||
var newDeviceRuntimes = datas.Item2.AdaptListDeviceRuntime();
|
||||
|
||||
RuntimeServiceHelper.Init(newDeviceRuntimes);
|
||||
}
|
||||
{
|
||||
var newVariableRuntimes = datas.Item3.AdaptListVariableRuntime();
|
||||
RuntimeServiceHelper.Init(newVariableRuntimes);
|
||||
}
|
||||
//根据条件重启通道线程
|
||||
|
||||
if (restart)
|
||||
{
|
||||
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
|
||||
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
//WaitLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile)
|
||||
{
|
||||
return GlobalData.VariableService.PreviewAsync(browserFile);
|
||||
|
||||
@@ -226,9 +226,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
_channelService.DeleteChannelFromCache();//刷新缓存
|
||||
_deviceService.DeleteDeviceFromCache();
|
||||
DeleteVariableCache();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,6 +235,144 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
return (newChannels, newDevices, newVariables);
|
||||
}
|
||||
|
||||
|
||||
public async Task<(List<Channel>, List<Device>, List<Variable>)> InsertTestDtuDataAsync(int deviceCount, string slaveUrl = "127.0.0.1:502")
|
||||
{
|
||||
if (slaveUrl.IsNullOrWhiteSpace()) slaveUrl = "127.0.0.1:502";
|
||||
List<Channel> newChannels = new();
|
||||
List<Device> newDevices = new();
|
||||
List<Variable> newVariables = new();
|
||||
|
||||
ManageHelper.CheckChannelCount(deviceCount);
|
||||
ManageHelper.CheckDeviceCount(deviceCount);
|
||||
ManageHelper.CheckVariableCount(deviceCount);
|
||||
|
||||
|
||||
//DTU
|
||||
|
||||
for (int i = 0; i < deviceCount; i++)
|
||||
{
|
||||
|
||||
Channel serviceChannel = new Channel();
|
||||
Device serviceDevice = new Device();
|
||||
|
||||
{
|
||||
var id = CommonUtils.GetSingleId();
|
||||
var name = $"modbusSlaveChannel{id}";
|
||||
serviceChannel.ChannelType = ChannelTypeEnum.TcpClient;
|
||||
serviceChannel.Name = name;
|
||||
serviceChannel.Enable = true;
|
||||
serviceChannel.Id = id;
|
||||
serviceChannel.CreateUserId = UserManager.UserId;
|
||||
serviceChannel.CreateOrgId = UserManager.OrgId;
|
||||
serviceChannel.RemoteUrl = "127.0.0.1:502";
|
||||
serviceChannel.DtuId = name;
|
||||
serviceChannel.Heartbeat = "ThingsGateway.Plugin.Modbus";
|
||||
serviceChannel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusSlave";
|
||||
newChannels.Add(serviceChannel);
|
||||
}
|
||||
{
|
||||
var id = CommonUtils.GetSingleId();
|
||||
var name = $"modbusSlaveDevice{id}";
|
||||
serviceDevice.Name = name;
|
||||
serviceDevice.Id = id;
|
||||
serviceDevice.CreateUserId = UserManager.UserId;
|
||||
serviceDevice.CreateOrgId = UserManager.OrgId;
|
||||
serviceDevice.ChannelId = serviceChannel.Id;
|
||||
serviceDevice.IntervalTime = "1000";
|
||||
newDevices.Add(serviceDevice);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//SERVICE
|
||||
var dtuids = newChannels.Select(a => a.Name).ToList();
|
||||
Channel channel = new Channel();
|
||||
{
|
||||
var id = CommonUtils.GetSingleId();
|
||||
var name = $"modbusChannel{id}";
|
||||
channel.ChannelType = ChannelTypeEnum.TcpService;
|
||||
channel.Name = name;
|
||||
channel.Id = id;
|
||||
channel.CreateUserId = UserManager.UserId;
|
||||
channel.CreateOrgId = UserManager.OrgId;
|
||||
channel.BindUrl = slaveUrl;
|
||||
channel.Heartbeat = "ThingsGateway.Plugin.Modbus";
|
||||
channel.PluginName = "ThingsGateway.Plugin.Modbus.ModbusMaster";
|
||||
//动态插件属性默认
|
||||
newChannels.Add(channel);
|
||||
}
|
||||
|
||||
foreach (var item in dtuids)
|
||||
{
|
||||
|
||||
Device device = new Device();
|
||||
{
|
||||
var id = CommonUtils.GetSingleId();
|
||||
var name = $"modbusDevice{id}";
|
||||
device.Name = name;
|
||||
device.Id = id;
|
||||
device.ChannelId = channel.Id;
|
||||
device.CreateUserId = UserManager.UserId;
|
||||
device.CreateOrgId = UserManager.OrgId;
|
||||
device.IntervalTime = "1000";
|
||||
device.DevicePropertys = new Dictionary<string, string>()
|
||||
{
|
||||
{
|
||||
nameof(CollectFoundationDtuPackPropertyBase.DtuId),item
|
||||
}
|
||||
};
|
||||
//动态插件属性默认
|
||||
newDevices.Add(device);
|
||||
}
|
||||
{
|
||||
var address = $"400001";
|
||||
var id = CommonUtils.GetSingleId();
|
||||
var name = $"modbus{address}";
|
||||
Variable variable = new Variable();
|
||||
variable.DataType = DataTypeEnum.Int16;
|
||||
variable.Name = name;
|
||||
variable.Id = id;
|
||||
variable.CreateOrgId = UserManager.OrgId;
|
||||
variable.CreateUserId = UserManager.UserId;
|
||||
variable.DeviceId = device.Id;
|
||||
variable.RegisterAddress = address;
|
||||
newVariables.Add(variable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using var db = GetDB();
|
||||
|
||||
var result = await db.UseTranAsync(async () =>
|
||||
{
|
||||
if (GlobalData.HardwareJob.HardwareInfo.MachineInfo.AvailableMemory < 2 * 1024 * 1024 || WebEnableVariable.WebEnable == false)
|
||||
{
|
||||
await db.BulkCopyAsync(newChannels, 10000).ConfigureAwait(false);
|
||||
await db.BulkCopyAsync(newDevices, 10000).ConfigureAwait(false);
|
||||
await db.BulkCopyAsync(newVariables, 10000).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await db.BulkCopyAsync(newChannels, 200000).ConfigureAwait(false);
|
||||
await db.BulkCopyAsync(newDevices, 200000).ConfigureAwait(false);
|
||||
await db.BulkCopyAsync(newVariables, 200000).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
if (result.IsSuccess)//如果成功了
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new(result.ErrorMessage, result.ErrorException);
|
||||
}
|
||||
return (newChannels, newDevices, newVariables);
|
||||
}
|
||||
|
||||
|
||||
#endregion 测试
|
||||
|
||||
/// <summary>
|
||||
@@ -265,7 +401,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +413,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
|
||||
if (result > 0)
|
||||
{
|
||||
DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -300,8 +436,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
.ToList();
|
||||
|
||||
var result = (await db.Updateable(data).UpdateColumns(differences.Select(a => a.Key).ToArray()).ExecuteCommandAsync().ConfigureAwait(false)) > 0;
|
||||
if (result)
|
||||
DeleteVariableCache();
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
@@ -320,8 +455,6 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||
.ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
if (result > 0)
|
||||
DeleteVariableCache();
|
||||
}
|
||||
|
||||
[OperDesc("DeleteVariable", isRecordPar: false, localizerType: typeof(Variable))]
|
||||
@@ -335,8 +468,6 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
.WhereIF(dataScope?.Count == 0, u => u.CreateUserId == UserManager.UserId)
|
||||
.ExecuteCommandAsync().ConfigureAwait(false)) > 0;
|
||||
|
||||
if (result)
|
||||
DeleteVariableCache();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -441,16 +572,13 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
DeleteVariableCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void DeleteVariableCache()
|
||||
{
|
||||
//App.CacheService.Remove(ThingsGatewayCacheConst.Cache_Variable);
|
||||
}
|
||||
|
||||
|
||||
public List<VariableRuntime> GetAllVariableRuntime()
|
||||
{
|
||||
@@ -579,7 +707,7 @@ internal sealed class VariableService : BaseService<Variable>, IVariableService
|
||||
await db.BulkCopyAsync(insertData, 200000).ConfigureAwait(false);
|
||||
await db.BulkUpdateAsync(upData, 200000).ConfigureAwait(false);
|
||||
}
|
||||
DeleteVariableCache();
|
||||
|
||||
return upData.Select(a => a.Id).Concat(insertData.Select(a => a.Id)).ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ public class Startup : AppStartup
|
||||
#region R
|
||||
|
||||
services.AddSingleton<IRulesService, RulesService>();
|
||||
services.AddSingleton<IRulesPageService>(a => a.GetService<IRulesService>());
|
||||
services.AddGatewayHostedService<IRulesEngineHostedService, RulesEngineHostedService>();
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" />
|
||||
<PackageReference Include="Rougamo.Fody" Version="5.0.1" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.3" />
|
||||
<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.13" />
|
||||
<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.13" />-->
|
||||
<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.13" />
|
||||
<PackageReference Include="TouchSocket.Dmtp" Version="4.0.0-beta.25" />
|
||||
<!--<PackageReference Include="TouchSocket.WebApi.Swagger" Version="4.0.0-beta.25" />-->
|
||||
<PackageReference Include="TouchSocket.WebApi" Version="4.0.0-beta.25" />
|
||||
<PackageReference Include="ThingsGateway.Authentication" Version="$(AuthenticationVersion)" />
|
||||
<!--<ProjectReference Include="..\..\PluginPro\ThingsGateway.Authentication\ThingsGateway.Authentication.csproj" />-->
|
||||
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
"BusinessEnable": "BusinessEnable",
|
||||
"SlaveUrl": "SlaveUrl",
|
||||
"Test": "Addition of test variables",
|
||||
"TestDtu": "Addition of test dtu variables",
|
||||
"TestDeviceCount": "TestDeviceCount",
|
||||
"TestVariableCount": "TestVariableCount",
|
||||
"WriteValue": "WriteValue",
|
||||
|
||||
@@ -243,6 +243,7 @@
|
||||
"BusinessEnable": "添加业务设备",
|
||||
"SlaveUrl": "服务端Url",
|
||||
"Test": "一键添加测试变量",
|
||||
"TestDtu": "一键添加Dtu测试变量",
|
||||
"TestDeviceCount": "采集设备数量",
|
||||
"TestVariableCount": "变量数量",
|
||||
"WriteValue": "写入值",
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
@if (WebsiteOption.Value.Demo || App.HostEnvironment.IsDevelopment())
|
||||
{
|
||||
<PopConfirmButton Color=Color.Warning Text="@Localizer["Test"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
|
||||
IsAsync OnConfirm=@(InsertTestDataAsync)>
|
||||
IsAsync OnConfirm=@(InsertTestDataAsync) class="me-1">
|
||||
|
||||
<BodyTemplate>
|
||||
<BootstrapInput @bind-Value=TestVariableCount ShowLabel="true" ShowLabelTooltip="true" />
|
||||
@@ -136,6 +136,16 @@
|
||||
</BodyTemplate>
|
||||
|
||||
</PopConfirmButton>
|
||||
|
||||
|
||||
<PopConfirmButton Color=Color.Warning Text="@Localizer["TestDtu"]" IsKeepDisabled=@(!AuthorizeButton(AdminOperConst.Add))
|
||||
IsAsync OnConfirm=@(InsertTestDtuDataAsync)>
|
||||
|
||||
<BodyTemplate>
|
||||
<BootstrapInput @bind-Value=TestDeviceCount ShowLabel="true" ShowLabelTooltip="true" />
|
||||
</BodyTemplate>
|
||||
|
||||
</PopConfirmButton>
|
||||
}
|
||||
|
||||
</TableToolbarTemplate>
|
||||
|
||||
@@ -481,6 +481,32 @@ finally
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task InsertTestDtuDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Run(() => VariablePageService.InsertTestDtuDataAsync(TestDeviceCount, SlaveUrl, AutoRestartThread));
|
||||
}
|
||||
finally
|
||||
{
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
await ToastService.Default();
|
||||
await table.QueryAsync();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await InvokeAsync(async () => await ToastService.Warn(ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Parameter]
|
||||
public bool AutoRestartThread { get; set; }
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public partial class RulesPage : ThingsGatewayModuleComponentBase
|
||||
{
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IRulesService? RulesService { get; set; }
|
||||
private IRulesPageService? RulesService { get; set; }
|
||||
|
||||
|
||||
protected override async Task InvokeInitAsync()
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using System.Buffers;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using TouchSocket.Sockets;
|
||||
|
||||
@@ -184,10 +185,28 @@ public class ModbusSlave : DeviceBase, IModbusAddress
|
||||
/// <inheritdoc/>
|
||||
private void Init(ModbusRequest mAddress)
|
||||
{
|
||||
//自动扩容
|
||||
ModbusServer01ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var bytes = new ByteBlock(ushort.MaxValue * 2);
|
||||
bytes.SetLength(ushort.MaxValue * 2);
|
||||
var bytes = new ByteBlock(256,
|
||||
(c) =>
|
||||
{
|
||||
var data = ArrayPool<byte>.Shared.Rent(c);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
(m) =>
|
||||
{
|
||||
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(result.Array);
|
||||
}
|
||||
}
|
||||
);
|
||||
bytes.SetLength(256);
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes.WriteByte(0);
|
||||
@@ -197,8 +216,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
|
||||
});
|
||||
ModbusServer02ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var bytes = new ByteBlock(ushort.MaxValue * 2);
|
||||
bytes.SetLength(ushort.MaxValue * 2);
|
||||
var bytes = new ByteBlock(256,
|
||||
(c) =>
|
||||
{
|
||||
var data = ArrayPool<byte>.Shared.Rent(c);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
(m) =>
|
||||
{
|
||||
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(result.Array);
|
||||
}
|
||||
}
|
||||
);
|
||||
bytes.SetLength(256);
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes.WriteByte(0);
|
||||
@@ -208,8 +244,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
|
||||
});
|
||||
ModbusServer03ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var bytes = new ByteBlock(ushort.MaxValue * 2);
|
||||
bytes.SetLength(ushort.MaxValue * 2);
|
||||
var bytes = new ByteBlock(256,
|
||||
(c) =>
|
||||
{
|
||||
var data = ArrayPool<byte>.Shared.Rent(c);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
(m) =>
|
||||
{
|
||||
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(result.Array);
|
||||
}
|
||||
}
|
||||
);
|
||||
bytes.SetLength(256);
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes.WriteByte(0);
|
||||
@@ -219,8 +272,25 @@ public class ModbusSlave : DeviceBase, IModbusAddress
|
||||
});
|
||||
ModbusServer04ByteBlocks.GetOrAdd(mAddress.Station, a =>
|
||||
{
|
||||
var bytes = new ByteBlock(ushort.MaxValue * 2);
|
||||
bytes.SetLength(ushort.MaxValue * 2);
|
||||
var bytes = new ByteBlock(256,
|
||||
(c) =>
|
||||
{
|
||||
var data = ArrayPool<byte>.Shared.Rent(c);
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = 0;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
(m) =>
|
||||
{
|
||||
if (MemoryMarshal.TryGetArray((ReadOnlyMemory<byte>)m, out var result))
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(result.Array);
|
||||
}
|
||||
}
|
||||
);
|
||||
bytes.SetLength(256);
|
||||
for (int i = 0; i < bytes.Length; i++)
|
||||
{
|
||||
bytes.WriteByte(0);
|
||||
@@ -278,16 +348,20 @@ public class ModbusSlave : DeviceBase, IModbusAddress
|
||||
switch (f)
|
||||
{
|
||||
case 1:
|
||||
return OperResult.CreateSuccessResult(ModbusServer01ByteBlock.Memory.Slice(mAddress.StartAddress, len));
|
||||
ModbusServer01ByteBlock.Position = mAddress.StartAddress;
|
||||
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer01ByteBlock.GetMemory(len).Slice(0, len));
|
||||
|
||||
case 2:
|
||||
return OperResult.CreateSuccessResult(ModbusServer02ByteBlock.Memory.Slice(mAddress.StartAddress, len));
|
||||
ModbusServer02ByteBlock.Position = mAddress.StartAddress;
|
||||
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer02ByteBlock.GetMemory(len).Slice(0, len));
|
||||
|
||||
case 3:
|
||||
return OperResult.CreateSuccessResult(ModbusServer03ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
|
||||
ModbusServer03ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
|
||||
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer03ByteBlock.GetMemory(len).Slice(0, len));
|
||||
|
||||
case 4:
|
||||
return OperResult.CreateSuccessResult(ModbusServer04ByteBlock.Memory.Slice(mAddress.StartAddress * RegisterByteLength, len));
|
||||
ModbusServer04ByteBlock.Position = mAddress.StartAddress * RegisterByteLength;
|
||||
return OperResult.CreateSuccessResult((ReadOnlyMemory<byte>)ModbusServer04ByteBlock.GetMemory(len).Slice(0, len));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user