Compare commits
5 Commits
10.11.73.0
...
10.11.80.0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
156ed88bd6 | ||
![]() |
2416226eb0 | ||
![]() |
976323a716 | ||
![]() |
3c9e397403 | ||
![]() |
79406ad4a0 |
@@ -21,12 +21,12 @@
|
||||
<link rel="apple-touch-icon" href="favicon.png">
|
||||
<base href="/" />
|
||||
<title>ThingsGateway</title>
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"ThingsGateway.AdminServer.styles.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css") />
|
||||
<link rel="stylesheet" href=@($"ThingsGateway.AdminServer.styles.css") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css") />
|
||||
|
||||
@* <script src=@($"{WebsiteConst.DefaultResourceUrl}js/theme.js") type="module"></script><!-- 初始主题 --> *@
|
||||
<!-- PWA Manifest -->
|
||||
@@ -40,8 +40,8 @@
|
||||
|
||||
<BlazorReconnector @rendermode="new InteractiveServerRenderMode(false)" />
|
||||
|
||||
<script src=@($"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js?v={this.GetType().Assembly.GetName().Version}")></script>
|
||||
<script src=@($"{WebsiteConst.DefaultResourceUrl}js/localStorageUtil.js?v={this.GetType().Assembly.GetName().Version}")></script>
|
||||
<script src=@($"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js")></script>
|
||||
<script src=@($"{WebsiteConst.DefaultResourceUrl}js/localStorageUtil.js")></script>
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
<!-- PWA Service Worker -->
|
||||
<script type="text/javascript">'serviceWorker' in navigator && navigator.serviceWorker.register('./service-worker.js')</script>
|
||||
|
@@ -70,7 +70,7 @@
|
||||
<Button @onclick="ShowAbout" class="layout-header-bar d-none d-lg-flex px-2" Icon="fa fa-info" Color="Color.None" TooltipText="@Localizer[nameof(About)]" />
|
||||
}
|
||||
@* 版本号 *@
|
||||
<div class="px-1 navbar-header-text d-none d-lg-block">@_versionString</div>
|
||||
<div class="px-1 navbar-header-text text-nowrap d-none d-lg-block">@_versionString</div>
|
||||
|
||||
@* 主题切换 *@
|
||||
@* <ThemeToggle /> *@
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.6" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="9.10.3" />
|
||||
<PackageReference Include="BootstrapBlazor" Version="9.11.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@@ -10,7 +10,6 @@
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace ThingsGateway.DataEncryption;
|
||||
|
||||
@@ -36,7 +35,7 @@ public static class PBKDF2Encryption
|
||||
var salt = new byte[saltSize];
|
||||
rng.GetBytes(salt);
|
||||
#if NET10_0_OR_GREATER
|
||||
var hash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(text), salt, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength);
|
||||
var hash = Rfc2898DeriveBytes.Pbkdf2(System.Text.Encoding.UTF8.GetBytes(text), salt, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength);
|
||||
#else
|
||||
using var pbkdf2 = new Rfc2898DeriveBytes(text, salt, iterationCount, HashAlgorithmName.SHA256);
|
||||
var hash = pbkdf2.GetBytes(derivedKeyLength);
|
||||
@@ -70,10 +69,10 @@ public static class PBKDF2Encryption
|
||||
return false;
|
||||
|
||||
#if NET10_0_OR_GREATER
|
||||
var computedHash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(text), saltBytes, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength);
|
||||
var computedHash = Rfc2898DeriveBytes.Pbkdf2(System.Text.Encoding.UTF8.GetBytes(text), saltBytes, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength);
|
||||
#else
|
||||
using var pbkdf2 = new Rfc2898DeriveBytes(text, saltBytes, iterationCount, HashAlgorithmName.SHA256);
|
||||
var computedHash = pbkdf2.GetBytes(derivedKeyLength);
|
||||
using var pbkdf2 = new Rfc2898DeriveBytes(text, saltBytes, iterationCount, HashAlgorithmName.SHA256);
|
||||
var computedHash = pbkdf2.GetBytes(derivedKeyLength);
|
||||
#endif
|
||||
|
||||
return computedHash.SequenceEqual(storedHashBytes);
|
||||
|
@@ -204,7 +204,7 @@ internal sealed partial class SchedulerFactory : ISchedulerFactory
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Schedule hosted service preload completed, and a total of <{Count}> schedulers are appended.", _schedulers.Count);
|
||||
_logger.LogInformation("Schedule hosted service preload completed, and a total of <{Count}> schedulers are appended.", _schedulers.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.11.73</PluginVersion>
|
||||
<ProPluginVersion>10.11.73</ProPluginVersion>
|
||||
<DefaultVersion>10.11.73</DefaultVersion>
|
||||
<PluginVersion>10.11.80</PluginVersion>
|
||||
<ProPluginVersion>10.11.80</ProPluginVersion>
|
||||
<DefaultVersion>10.11.80</DefaultVersion>
|
||||
<AuthenticationVersion>10.11.6</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.11.6</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.20</NET8Version>
|
||||
@@ -12,7 +12,7 @@
|
||||
<IsTrimmable>false</IsTrimmable>
|
||||
<ManagementProPluginVersion>10.11.70</ManagementProPluginVersion>
|
||||
<ManagementPluginVersion>10.11.70</ManagementPluginVersion>
|
||||
<TSVersion>4.0.0-beta.57</TSVersion>
|
||||
<TSVersion>4.0.0-beta.80</TSVersion>
|
||||
|
||||
|
||||
</PropertyGroup>
|
||||
|
@@ -36,7 +36,7 @@
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Handshake" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
|
@@ -42,7 +42,7 @@
|
||||
"PortName": "COM Port",
|
||||
"RemoteUrl": "Remote IP Address",
|
||||
"RtsEnable": "Rts",
|
||||
"StreamAsync": "StreamAsync",
|
||||
"Handshake": "Handshake",
|
||||
"SaveChannel": "Add/Modify Channel",
|
||||
"StopBits": "Stop Bits"
|
||||
},
|
||||
@@ -102,7 +102,7 @@
|
||||
"PortName": "PortName",
|
||||
"RemoteUrl": "RemoteUrl",
|
||||
"RtsEnable": "RtsEnable",
|
||||
"StreamAsync": "StreamAsync",
|
||||
"Handshake": "Handshake",
|
||||
"StopBits": "StopBits"
|
||||
}
|
||||
}
|
@@ -40,7 +40,7 @@
|
||||
"PortName": "COM口",
|
||||
"RemoteUrl": "远程url",
|
||||
"RtsEnable": "Rts",
|
||||
"StreamAsync": "串口流读写",
|
||||
"Handshake": "Handshake",
|
||||
"SaveChannel": "添加/修改通道",
|
||||
"StopBits": "停止位"
|
||||
},
|
||||
@@ -100,7 +100,7 @@
|
||||
"PortName": "COM口",
|
||||
"RemoteUrl": "远程url",
|
||||
"RtsEnable": "Rts",
|
||||
"StreamAsync": "串口流读写",
|
||||
"Handshake": "串口流读写",
|
||||
"StopBits": "停止位"
|
||||
}
|
||||
}
|
@@ -69,9 +69,9 @@ namespace ThingsGateway.Foundation
|
||||
public virtual bool DtrEnable { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// StreamAsync
|
||||
/// Handshake
|
||||
/// </summary>
|
||||
public virtual bool StreamAsync { get; set; } = false;
|
||||
public virtual Handshake Handshake { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// RtsEnable
|
||||
|
@@ -9,7 +9,6 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
using ThingsGateway.NewLife;
|
||||
|
||||
using TouchSocket.SerialPorts;
|
||||
|
||||
@@ -100,16 +99,16 @@ public static class ChannelOptionsExtensions
|
||||
if (channelOptions.MaxClientCount > 0)
|
||||
config.SetMaxCount(channelOptions.MaxClientCount);
|
||||
|
||||
config.SetTransportOption(new TouchSocket.Sockets.TransportOption()
|
||||
config.SetTransportOption(a =>
|
||||
{
|
||||
SendPipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
minimumSegmentSize: 1024,
|
||||
useSynchronizationContext: false),
|
||||
ReceivePipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
a.SendPipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
minimumSegmentSize: 1024,
|
||||
useSynchronizationContext: false);
|
||||
a.ReceivePipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
pauseWriterThreshold: 1024 * 1024,
|
||||
resumeWriterThreshold: 1024 * 512,
|
||||
useSynchronizationContext: false)
|
||||
minimumSegmentSize: 1024,
|
||||
useSynchronizationContext: false);
|
||||
});
|
||||
|
||||
switch (channelType)
|
||||
@@ -141,10 +140,19 @@ public static class ChannelOptionsExtensions
|
||||
/// <returns></returns>
|
||||
private static SerialPortChannel GetSerialPort(this TouchSocketConfig config, IChannelOptions channelOptions)
|
||||
{
|
||||
var serialPortOption = FastMapper.Mapper<IChannelOptions,SerialPortOption>(channelOptions);
|
||||
serialPortOption.ThrowIfNull(nameof(SerialPortOption));
|
||||
channelOptions.ThrowIfNull(nameof(SerialPortOption));
|
||||
channelOptions.Config = config;
|
||||
config.SetSerialPortOption(serialPortOption);
|
||||
config.SetSerialPortOption(options =>
|
||||
{
|
||||
options.PortName = channelOptions.PortName;
|
||||
options.BaudRate = channelOptions.BaudRate;
|
||||
options.DataBits = channelOptions.DataBits;
|
||||
options.Parity = channelOptions.Parity;
|
||||
options.StopBits = channelOptions.StopBits;
|
||||
options.DtrEnable = channelOptions.DtrEnable;
|
||||
options.RtsEnable = channelOptions.RtsEnable;
|
||||
options.Handshake = channelOptions.Handshake;
|
||||
});
|
||||
//载入配置
|
||||
SerialPortChannel serialPortChannel = new SerialPortChannel(channelOptions);
|
||||
return serialPortChannel;
|
||||
|
@@ -72,11 +72,7 @@ public interface IChannelOptions
|
||||
/// </summary>
|
||||
bool RtsEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StreamAsync
|
||||
/// </summary>
|
||||
bool StreamAsync { get; set; }
|
||||
|
||||
Handshake Handshake { get; set; }
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 最大并发数量
|
||||
|
@@ -182,7 +182,7 @@ public class DeviceSingleStreamDataHandleAdapter<TRequest> : CustomDataHandlingA
|
||||
Span<byte> span = default;
|
||||
if (Logger?.LogLevel <= LogLevel.Trace)
|
||||
{
|
||||
span = writer.GetSpan(sendMessage.MaxLength);
|
||||
span = writer.GetSpan(sendMessage.MaxLength);
|
||||
}
|
||||
|
||||
sendMessage.Build(ref writer);
|
||||
|
@@ -18,8 +18,6 @@ using ThingsGateway.NewLife;
|
||||
using ThingsGateway.NewLife.Collections;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
|
||||
using TouchSocket.SerialPorts;
|
||||
|
||||
namespace ThingsGateway.Foundation;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
"PortName": "PortName",
|
||||
"RemoteUrl": "RemoteUrl",
|
||||
"RtsEnable": "RtsEnable",
|
||||
"StreamAsync": "StreamAsync",
|
||||
"Handshake": "Handshake",
|
||||
"StopBits": "StopBits"
|
||||
},
|
||||
"ThingsGateway.Foundation.ConverterConfig": {
|
||||
|
@@ -22,7 +22,7 @@
|
||||
"PortName": "COM口",
|
||||
"RemoteUrl": "远程url",
|
||||
"RtsEnable": "Rts",
|
||||
"StreamAsync": "串口流读写",
|
||||
"Handshake": "Handshake",
|
||||
"StopBits": "停止位"
|
||||
},
|
||||
"ThingsGateway.Foundation.ConverterConfig": {
|
||||
|
@@ -145,6 +145,7 @@ public class TextFileLogger : ThingsGateway.NewLife.Log.TextFileLog, TouchSocket
|
||||
}
|
||||
WriteLog(logLevel, source, message, exception);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
cache.Remove(CacheKey);
|
||||
|
@@ -73,7 +73,7 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
get => endianType; set
|
||||
{
|
||||
endianType = value;
|
||||
TouchSocketBitConverter = new TouchSocketBitConverter(endianType);
|
||||
TouchSocketBitConverter = TouchSocketBitConverter.GetBitConverter(endianType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,13 +188,13 @@ public partial class ThingsGatewayBitConverter : IThingsGatewayBitConverter
|
||||
|
||||
// 更新设备地址为去除附加信息后的地址
|
||||
registerAddress = sb.ToString();
|
||||
var converter = (IThingsGatewayBitConverter)FastMapper.Mapper(this, type);
|
||||
// 如果没有解析出任何附加信息,则直接返回默认的数据转换器
|
||||
if (bcdFormat == null && stringlength == null && encoding == null && dataFormat == null && wstring == null)
|
||||
{
|
||||
//MemoryCache.Set(cacheKey, this!, 3600);
|
||||
return converter;
|
||||
return this;
|
||||
}
|
||||
var converter = (IThingsGatewayBitConverter)FastMapper.Mapper(this, type);
|
||||
|
||||
// 根据默认的数据转换器创建新的数据转换器实例
|
||||
|
||||
|
@@ -16,8 +16,6 @@ using ThingsGateway.NewLife.Json.Extension;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
/// <summary>
|
||||
|
@@ -378,6 +378,8 @@ public abstract class DriverBase : AsyncDisposableObject, IDriver
|
||||
// 记录设备线程已停止的信息
|
||||
LogMessage?.LogInformation(string.Format(AppResource.DeviceTaskStop, DeviceName));
|
||||
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
|
||||
// 执行资源释放操作
|
||||
await this.SafeDisposeAsync().ConfigureAwait(false);
|
||||
|
||||
|
@@ -138,11 +138,11 @@ public class Channel : ChannelOptionsBase, IPrimaryIdEntity, IBaseDataEntity, IB
|
||||
public override bool RtsEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StreamAsync
|
||||
/// Handshake
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "StreamAsync", IsNullable = true)]
|
||||
[SugarColumn(ColumnDescription = "Handshake", IsNullable = true)]
|
||||
[AutoGenerateColumn(Visible = false, Filterable = true, Sortable = true)]
|
||||
public override bool StreamAsync { get; set; } = false;
|
||||
public override Handshake Handshake { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 缓存超时
|
||||
|
@@ -307,7 +307,7 @@
|
||||
"PortName": "PortName",
|
||||
"RemoteUrl": "RemoteUrl",
|
||||
"RtsEnable": "RtsEnable",
|
||||
"StreamAsync": "StreamAsync",
|
||||
"Handshake": "Handshake",
|
||||
"SaveChannel": "Add/Modify Channel",
|
||||
"SortCode": "SortCode",
|
||||
"StopBits": "StopBits",
|
||||
|
@@ -306,7 +306,7 @@
|
||||
"PortName": "COM口",
|
||||
"RemoteUrl": "远程url",
|
||||
"RtsEnable": "Rts",
|
||||
"StreamAsync": "串口流读写",
|
||||
"Handshake": "Handshake",
|
||||
"SaveChannel": "添加/修改通道",
|
||||
"SortCode": "排序",
|
||||
"StopBits": "停止位",
|
||||
|
@@ -84,7 +84,7 @@ public class ChannelRuntime : Channel
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[MapperIgnore]
|
||||
[AutoGenerateColumn(Ignore = true)]
|
||||
internal ConcurrentDictionary<long, DeviceRuntime>? DeviceRuntimes { get; } = new(Environment.ProcessorCount, 1000);
|
||||
internal ConcurrentDictionary<long, DeviceRuntime>? DeviceRuntimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 设备数量
|
||||
|
@@ -251,7 +251,7 @@ public class DeviceRuntime : Device
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[MapperIgnore]
|
||||
[AutoGenerateColumn(Ignore = true)]
|
||||
internal ConcurrentDictionary<string, VariableRuntime>? VariableRuntimes { get; } = new(Environment.ProcessorCount, 1000);
|
||||
internal ConcurrentDictionary<string, VariableRuntime>? VariableRuntimes { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 特殊方法变量
|
||||
|
@@ -177,7 +177,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
|
||||
{
|
||||
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
|
||||
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -209,7 +209,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
|
||||
{
|
||||
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
|
||||
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -241,7 +241,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
|
||||
{
|
||||
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
|
||||
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -110,7 +110,11 @@ internal sealed class ChannelService : BaseService<Channel>, IChannelService
|
||||
|
||||
var device = devices.Keys.ToList();
|
||||
ManageHelper.CheckDeviceCount(device.Count);
|
||||
|
||||
foreach (var item in device)
|
||||
{
|
||||
item.RedundantEnable = false;
|
||||
item.RedundantDeviceId = null;
|
||||
}
|
||||
await db.Insertable(device).ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
var variable = devices.SelectMany(a => a.Value).ToList();
|
||||
|
@@ -205,7 +205,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
|
||||
if (restart)
|
||||
{
|
||||
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(_logger).ConfigureAwait(false);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -53,7 +53,11 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
{
|
||||
var device = devices.Keys.ToList();
|
||||
ManageHelper.CheckDeviceCount(device.Count);
|
||||
|
||||
foreach (var item in device)
|
||||
{
|
||||
item.RedundantEnable = false;
|
||||
item.RedundantDeviceId = null;
|
||||
}
|
||||
await db.Insertable(device).ExecuteCommandAsync().ConfigureAwait(false);
|
||||
|
||||
var variable = devices.SelectMany(a => a.Value).ToList();
|
||||
@@ -263,6 +267,9 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
else
|
||||
ManageHelper.CheckDeviceCount(1);
|
||||
|
||||
if (input.RedundantEnable && GlobalData.IsRedundant(input.RedundantDeviceId ?? 0))
|
||||
throw Oops.Bah($"Redundancy configuration error, backup device has been planned into another redundancy group");
|
||||
|
||||
if (await base.SaveAsync(input, type).ConfigureAwait(false))
|
||||
{
|
||||
|
||||
|
@@ -820,6 +820,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
|
||||
|
||||
LogMessage?.LogInformation(string.Format(AppResource.ChannelDispose, CurrentChannel?.Name ?? string.Empty));
|
||||
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
LogMessage?.Logs?.ForEach(a => a.TryDispose());
|
||||
}
|
||||
finally
|
||||
|
@@ -239,7 +239,7 @@ internal static class RuntimeServiceHelper
|
||||
if (group.Key != null)
|
||||
await group.Key.RestartDeviceAsync(group.Value, false).ConfigureAwait(false);
|
||||
}
|
||||
foreach (var group in GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => a.Driver?.DeviceThreadManage != null).GroupBy(a => a.Driver.DeviceThreadManage))
|
||||
foreach (var group in GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).Where(a => a.Driver?.DeviceThreadManage != null).GroupBy(a => a.Driver.DeviceThreadManage))
|
||||
{
|
||||
if (group.Key != null)
|
||||
await group.Key.RestartDeviceAsync(group.ToArray(), false).ConfigureAwait(false);
|
||||
@@ -260,7 +260,7 @@ internal static class RuntimeServiceHelper
|
||||
await group.Key.RemoveDeviceAsync(group.Value.Select(a => a.Id).ToArray()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var group in GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => a.Driver?.DeviceThreadManage != null).GroupBy(a => a.Driver.DeviceThreadManage))
|
||||
foreach (var group in GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !deviceRuntimes.Contains(a)).Where(a => a.Driver?.DeviceThreadManage != null).GroupBy(a => a.Driver.DeviceThreadManage))
|
||||
{
|
||||
if (group.Key != null)
|
||||
await group.Key.RestartDeviceAsync(group.ToArray(), false).ConfigureAwait(false);
|
||||
@@ -268,9 +268,9 @@ internal static class RuntimeServiceHelper
|
||||
|
||||
}
|
||||
|
||||
public static async Task ChangedDriverAsync(ILogger logger)
|
||||
public static async Task ChangedDriverAsync(DeviceRuntime[] channelDevice, ILogger logger)
|
||||
{
|
||||
var channelDevice = GlobalData.GetAllVariableBusinessDeviceRuntime();
|
||||
|
||||
|
||||
await channelDevice.ParallelForEachAsync(async (item, token) =>
|
||||
{
|
||||
|
@@ -398,22 +398,22 @@ public class VariableRuntimeService : IVariableRuntimeService
|
||||
//批量修改之后,需要重新加载通道
|
||||
RuntimeServiceHelper.Init(newChannelRuntimes);
|
||||
|
||||
{
|
||||
var newDeviceRuntimes = datas.Item2.AdaptListDeviceRuntime();
|
||||
|
||||
RuntimeServiceHelper.Init(newDeviceRuntimes);
|
||||
}
|
||||
{
|
||||
var newVariableRuntimes = datas.Item3.AdaptListVariableRuntime();
|
||||
RuntimeServiceHelper.Init(newVariableRuntimes);
|
||||
}
|
||||
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);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,22 +437,21 @@ public class VariableRuntimeService : IVariableRuntimeService
|
||||
//批量修改之后,需要重新加载通道
|
||||
RuntimeServiceHelper.Init(newChannelRuntimes);
|
||||
|
||||
{
|
||||
var newDeviceRuntimes = datas.Item2.AdaptListDeviceRuntime();
|
||||
|
||||
RuntimeServiceHelper.Init(newDeviceRuntimes);
|
||||
}
|
||||
{
|
||||
var newVariableRuntimes = datas.Item3.AdaptListVariableRuntime();
|
||||
RuntimeServiceHelper.Init(newVariableRuntimes);
|
||||
}
|
||||
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);
|
||||
await RuntimeServiceHelper.ChangedDriverAsync(GlobalData.GetAllVariableBusinessDeviceRuntime().Where(a => !newDeviceRuntimes.Contains(a)).ToArray(), _logger).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -114,7 +114,7 @@
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Handshake" Ignore=@(context.ChannelType != ChannelTypeEnum.SerialPort) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType == ChannelTypeEnum.UdpSession || context.ChannelType == ChannelTypeEnum.Other) />
|
||||
|
@@ -82,7 +82,7 @@
|
||||
<EditorItem @bind-Field="@context.StopBits" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.DtrEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.RtsEnable" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.StreamAsync" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
<EditorItem @bind-Field="@context.Handshake" Ignore=@(context.ChannelType!=ChannelTypeEnum.SerialPort) />
|
||||
|
||||
|
||||
<EditorItem @bind-Field="@context.CacheTimeout" Ignore=@(context.ChannelType==ChannelTypeEnum.UdpSession||context.ChannelType==ChannelTypeEnum.Other) />
|
||||
|
@@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Components.Web;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Admin.Razor;
|
||||
using ThingsGateway.NewLife;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.NewLife.Json.Extension;
|
||||
using ThingsGateway.SqlSugar;
|
||||
@@ -1319,17 +1320,26 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
|
||||
private TreeViewItem<ChannelDeviceTreeItem> UnknownTreeViewItem;
|
||||
|
||||
SmartTriggerScheduler? scheduler;
|
||||
|
||||
private bool _initialized;
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
|
||||
parameters.SetParameterProperties(this);
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
if (!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@@ -1402,19 +1412,29 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
WaitLock WaitLock = new(nameof(ChannelDeviceTree));
|
||||
private async Task Notify(CancellationToken cancellationToken)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
if (Disposed) return;
|
||||
await OnClickSearch(SearchText);
|
||||
|
||||
Value = GetValue(Value);
|
||||
if (ChannelDeviceChanged != null)
|
||||
try
|
||||
{
|
||||
await ChannelDeviceChanged.Invoke(Value);
|
||||
await WaitLock.WaitAsync(cancellationToken);
|
||||
|
||||
await OnClickSearch(SearchText);
|
||||
|
||||
Value = GetValue(Value);
|
||||
if (ChannelDeviceChanged != null)
|
||||
{
|
||||
await ChannelDeviceChanged.Invoke(Value);
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
WaitLock.Release();
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private static ChannelDeviceTreeItem GetValue(ChannelDeviceTreeItem channelDeviceTreeItem)
|
||||
|
@@ -120,6 +120,7 @@ public partial class DeviceEditComponent
|
||||
|
||||
private string ChannelName;
|
||||
private string DeviceName;
|
||||
private bool _initialized;
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
if (ChannelName.IsNullOrEmpty())
|
||||
@@ -127,11 +128,22 @@ public partial class DeviceEditComponent
|
||||
parameters.SetParameterProperties(this);
|
||||
ChannelName = await ChannelPageService.GetChannelNameAsync(Model?.ChannelId ?? 0);
|
||||
DeviceName = await DevicePageService.GetDeviceNameAsync(Model?.RedundantDeviceId ?? 0);
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
if (!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnParametersSet();
|
||||
StateHasChanged();
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -49,6 +49,11 @@ public partial class VariableEditComponent
|
||||
private string DeviceName;
|
||||
private string ChoiceBusinessDeviceName;
|
||||
private bool first = false;
|
||||
|
||||
|
||||
private bool _initialized;
|
||||
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
if (DeviceName.IsNullOrEmpty() && first == false)
|
||||
@@ -56,14 +61,31 @@ public partial class VariableEditComponent
|
||||
first = true;
|
||||
parameters.SetParameterProperties(this);
|
||||
DeviceName = await DevicePageService.GetDeviceNameAsync(Model?.DeviceId ?? 0);
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
if (!_initialized)
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
ChoiceBusinessDeviceId = ChoiceBusinessDeviceId > 0 ? ChoiceBusinessDeviceId : (await DevicePageService.OnDeviceSelectedItemQueryAsync(new VirtualizeQueryOption() { Count = 1 }, false).ConfigureAwait(false)).Items.FirstOrDefault()?.Value?.ToLong() ?? 0;
|
||||
ChoiceBusinessDeviceName = (await DevicePageService.GetDeviceNameAsync(ChoiceBusinessDeviceId)) ?? string.Empty;
|
||||
OnInitialized();
|
||||
await OnInitializedAsync();
|
||||
OnParametersSet();
|
||||
|
||||
ChoiceBusinessDeviceId = ChoiceBusinessDeviceId > 0 ? ChoiceBusinessDeviceId : (await DevicePageService.OnDeviceSelectedItemQueryAsync(new VirtualizeQueryOption() { Count = 1 }, false).ConfigureAwait(false)).Items.FirstOrDefault()?.Value?.ToLong() ?? 0;
|
||||
ChoiceBusinessDeviceName = (await DevicePageService.GetDeviceNameAsync(ChoiceBusinessDeviceId)) ?? string.Empty;
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
OnParametersSet();
|
||||
|
||||
ChoiceBusinessDeviceId = ChoiceBusinessDeviceId > 0 ? ChoiceBusinessDeviceId : (await DevicePageService.OnDeviceSelectedItemQueryAsync(new VirtualizeQueryOption() { Count = 1 }, false).ConfigureAwait(false)).Items.FirstOrDefault()?.Value?.ToLong() ?? 0;
|
||||
ChoiceBusinessDeviceName = (await DevicePageService.GetDeviceNameAsync(ChoiceBusinessDeviceId)) ?? string.Empty;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await OnParametersSetAsync();
|
||||
}
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
await OnParametersSetAsync();
|
||||
|
||||
|
@@ -35,7 +35,8 @@ public partial class RulesPage : ThingsGatewayModuleComponentBase
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
if (firstRender) {
|
||||
if (firstRender)
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@
|
||||
<Button OnClick="ShowAbout" class="layout-header-bar d-none d-lg-flex px-2" Icon="fa fa-info" Color="Color.None" TooltipText="@Localizer[nameof(About)]" />
|
||||
}
|
||||
@* 版本号 *@
|
||||
<div class="px-1 navbar-header-text d-none d-lg-block">@_versionString</div>
|
||||
<div class="px-1 navbar-header-text text-nowrap d-none d-lg-block">@_versionString</div>
|
||||
|
||||
@* 主题切换 *@
|
||||
@* <ThemeToggle /> *@
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using BenchmarkConsoleApp;
|
||||
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
@@ -36,6 +34,10 @@ namespace ThingsGateway.Foundation;
|
||||
[MemoryDiagnoser]
|
||||
public class ModbusBenchmark : IDisposable
|
||||
{
|
||||
public static int ClientCount = 2;
|
||||
public static int TaskNumberOfItems = 4;
|
||||
public static int NumberOfItems = 4;
|
||||
|
||||
private readonly List<IModbusClient> _lgbModbusClients = [];
|
||||
private List<ModbusMaster> thingsgatewaymodbuss = new();
|
||||
private List<IModbusMaster> nmodbuss = new();
|
||||
@@ -45,7 +47,7 @@ public class ModbusBenchmark : IDisposable
|
||||
[GlobalSetup]
|
||||
public async Task Init()
|
||||
{
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
|
||||
var clientConfig = new TouchSocket.Core.TouchSocketConfig();
|
||||
@@ -57,23 +59,23 @@ public class ModbusBenchmark : IDisposable
|
||||
ModbusType = ModbusTypeEnum.ModbusTcp,
|
||||
};
|
||||
thingsgatewaymodbus.InitChannel(clientChannel);
|
||||
await clientChannel.SetupAsync(clientChannel.Config);
|
||||
await clientChannel.SetupAsync(clientChannel.Config);
|
||||
clientChannel.Logger.LogLevel = LogLevel.Warning;
|
||||
await thingsgatewaymodbus.ConnectAsync(CancellationToken.None);
|
||||
await thingsgatewaymodbus.ReadAsync("40001", 100);
|
||||
await thingsgatewaymodbus.ConnectAsync(CancellationToken.None);
|
||||
await thingsgatewaymodbus.ReadAsync("40001", 100);
|
||||
thingsgatewaymodbuss.Add(thingsgatewaymodbus);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
|
||||
var factory = new NModbus.ModbusFactory();
|
||||
var nmodbus = factory.CreateMaster(new TcpClient("127.0.0.1", 502));
|
||||
await nmodbus.ReadHoldingRegistersAsync(1, 0, 100);
|
||||
await nmodbus.ReadHoldingRegistersAsync(1, 0, 100);
|
||||
nmodbuss.Add(nmodbus);
|
||||
}
|
||||
//for (int i = 0; i < Program.ClientCount; i++)
|
||||
//for (int i = 0; i < ClientCount; i++)
|
||||
//{
|
||||
// ModbusTcpNet modbusTcpNet = new();
|
||||
// modbusTcpNet.IpAddress = "127.0.0.1";
|
||||
@@ -83,13 +85,13 @@ public class ModbusBenchmark : IDisposable
|
||||
// modbusTcpNets.Add(modbusTcpNet);
|
||||
//}
|
||||
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
var client = new ModbusTcpMaster();
|
||||
await client.SetupAsync(new TouchSocketConfig()
|
||||
.SetRemoteIPHost("127.0.0.1:502"));
|
||||
await client.ConnectAsync(CancellationToken.None);
|
||||
await client.ReadHoldingRegistersAsync(0, 100);
|
||||
await client.SetupAsync(new TouchSocketConfig()
|
||||
.SetRemoteIPHost("127.0.0.1:502"));
|
||||
await client.ConnectAsync(CancellationToken.None);
|
||||
await client.ReadHoldingRegistersAsync(0, 100);
|
||||
modbusTcpMasters.Add(client);
|
||||
}
|
||||
|
||||
@@ -101,11 +103,11 @@ public class ModbusBenchmark : IDisposable
|
||||
var provider = sc.BuildServiceProvider();
|
||||
var factory = provider.GetRequiredService<IModbusFactory>();
|
||||
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
var client = factory.GetOrCreateTcpMaster();
|
||||
await client.ConnectAsync("127.0.0.1", 502);
|
||||
await client.ReadHoldingRegistersAsync(0x01, 0x00, 10);
|
||||
await client.ConnectAsync("127.0.0.1", 502);
|
||||
await client.ReadHoldingRegistersAsync(0x01, 0x00, 10);
|
||||
|
||||
_lgbModbusClients.Add(client);
|
||||
}
|
||||
@@ -120,11 +122,11 @@ public class ModbusBenchmark : IDisposable
|
||||
foreach (var thingsgatewaymodbus in thingsgatewaymodbuss)
|
||||
{
|
||||
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await thingsgatewaymodbus.ModbusReadAsync(addr).ConfigureAwait(false);
|
||||
if (!result.IsSuccess)
|
||||
@@ -146,11 +148,11 @@ public class ModbusBenchmark : IDisposable
|
||||
foreach (var _lgbModbusClient in _lgbModbusClients)
|
||||
{
|
||||
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
using var cts = new CancellationTokenSource(3000);
|
||||
var task = await _lgbModbusClient.ReadHoldingRegistersAsync(1, 0, 100, cts.Token).ConfigureAwait(false);
|
||||
@@ -167,11 +169,11 @@ public class ModbusBenchmark : IDisposable
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var modbusTcpMaster in modbusTcpMasters)
|
||||
{
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await modbusTcpMaster.ReadHoldingRegistersAsync(0, 100).ConfigureAwait(false);
|
||||
var data = TouchSocketBitConverter.ConvertValues<byte, ushort>(result.Data.Span, EndianType.Little);
|
||||
@@ -193,11 +195,11 @@ public class ModbusBenchmark : IDisposable
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var nmodbus in nmodbuss)
|
||||
{
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await nmodbus.ReadHoldingRegistersAsync(1, 0, 100).ConfigureAwait(false);
|
||||
}
|
||||
@@ -215,11 +217,11 @@ public class ModbusBenchmark : IDisposable
|
||||
// List<Task> tasks = new List<Task>();
|
||||
// foreach (var modbusTcpNet in modbusTcpNets)
|
||||
// {
|
||||
// for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
// for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
// {
|
||||
// tasks.Add(Task.Run(async () =>
|
||||
// {
|
||||
// for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
// for (int i = 0; i < NumberOfItems; i++)
|
||||
// {
|
||||
// var result = await modbusTcpNet.ReadAsync("0", 100);
|
||||
// if (!result.IsSuccess)
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using BenchmarkConsoleApp;
|
||||
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
@@ -29,6 +27,10 @@ namespace ThingsGateway.Foundation;
|
||||
[MemoryDiagnoser]
|
||||
public class S7Benchmark : IDisposable
|
||||
{
|
||||
public static int ClientCount = 5;
|
||||
public static int TaskNumberOfItems = 1;
|
||||
public static int NumberOfItems = 5;
|
||||
|
||||
private List<SiemensS7Master> siemensS7s = new();
|
||||
|
||||
private List<Plc> plcs = new();
|
||||
@@ -39,7 +41,7 @@ public class S7Benchmark : IDisposable
|
||||
|
||||
{
|
||||
{
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
var clientConfig = new TouchSocket.Core.TouchSocketConfig();
|
||||
|
||||
@@ -56,14 +58,14 @@ public class S7Benchmark : IDisposable
|
||||
await siemensS7.ReadAsync("M1", 100);
|
||||
siemensS7s.Add(siemensS7);
|
||||
}
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
var siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500, "127.0.0.1");
|
||||
await siemensS7Net.ConnectServerAsync();
|
||||
await siemensS7Net.ReadAsync("M0", 100);
|
||||
siemensS7Nets.Add(siemensS7Net);
|
||||
}
|
||||
for (int i = 0; i < Program.ClientCount; i++)
|
||||
for (int i = 0; i < ClientCount; i++)
|
||||
{
|
||||
var plc = new Plc(CpuType.S71500, "127.0.0.1", 102, 0, 0);
|
||||
await plc.OpenAsync();//打开plc连接
|
||||
@@ -79,11 +81,11 @@ public class S7Benchmark : IDisposable
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var plc in plcs)
|
||||
{
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await plc.ReadAsync(DataType.Memory, 1, 0, VarType.Byte, 100);
|
||||
}
|
||||
@@ -99,11 +101,11 @@ public class S7Benchmark : IDisposable
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var siemensS7Net in siemensS7Nets)
|
||||
{
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await siemensS7Net.ReadAsync("M0", 100);
|
||||
if (!result.IsSuccess)
|
||||
@@ -129,11 +131,11 @@ public class S7Benchmark : IDisposable
|
||||
List<Task> tasks = new List<Task>();
|
||||
foreach (var siemensS7 in siemensS7s)
|
||||
{
|
||||
for (int i = 0; i < Program.TaskNumberOfItems; i++)
|
||||
for (int i = 0; i < TaskNumberOfItems; i++)
|
||||
{
|
||||
tasks.Add(Task.Run(async () =>
|
||||
{
|
||||
for (int i = 0; i < Program.NumberOfItems; i++)
|
||||
for (int i = 0; i < NumberOfItems; i++)
|
||||
{
|
||||
var result = await siemensS7.S7ReadAsync(siemensS7Address);
|
||||
if (!result.IsSuccess)
|
||||
|
@@ -20,14 +20,11 @@ namespace BenchmarkConsoleApp
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
public static int ClientCount = 50;
|
||||
public static int TaskNumberOfItems = 6;
|
||||
public static int NumberOfItems = 50;
|
||||
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("开始测试前,请先启动ModbusSlave,建议使用本项目自带的ThingsGateway.Debug.Photino软件开启,S7可以用KEPSERVER的S7模拟服务");
|
||||
Console.WriteLine($"多客户端({ClientCount}),多线程({TaskNumberOfItems})并发读取({NumberOfItems})测试,共{ClientCount * TaskNumberOfItems * NumberOfItems}次");
|
||||
await Task.CompletedTask;
|
||||
//ModbusBenchmark modbusBenchmark = new ModbusBenchmark();
|
||||
//System.Diagnostics.Stopwatch stopwatch = new();
|
||||
@@ -46,15 +43,15 @@ namespace BenchmarkConsoleApp
|
||||
//.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
//);
|
||||
|
||||
BenchmarkRunner.Run<MapperBench>(
|
||||
ManualConfig.Create(DefaultConfig.Instance)
|
||||
.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
);
|
||||
// BenchmarkRunner.Run<MapperBench>(
|
||||
//ManualConfig.Create(DefaultConfig.Instance)
|
||||
//.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
//);
|
||||
|
||||
// BenchmarkRunner.Run<ModbusBenchmark>(
|
||||
// ManualConfig.Create(DefaultConfig.Instance)
|
||||
// .WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
//);
|
||||
BenchmarkRunner.Run<ModbusBenchmark>(
|
||||
ManualConfig.Create(DefaultConfig.Instance)
|
||||
.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
);
|
||||
// BenchmarkRunner.Run<S7Benchmark>(
|
||||
//ManualConfig.Create(DefaultConfig.Instance)
|
||||
//.WithOptions(ConfigOptions.DisableOptimizationsValidator)
|
||||
|
@@ -14,7 +14,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
@@ -14,7 +14,6 @@ using ThingsGateway.Common;
|
||||
using ThingsGateway.DB;
|
||||
using ThingsGateway.Debug;
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Gateway.Application;
|
||||
using ThingsGateway.NewLife;
|
||||
using ThingsGateway.NewLife.Extension;
|
||||
using ThingsGateway.NewLife.Threading;
|
||||
|
@@ -45,7 +45,7 @@ public class SQLHistoryValue : IPrimaryIdEntity
|
||||
///<summary>
|
||||
///实时值
|
||||
///</summary>
|
||||
[SugarColumn(ColumnDescription = "实时值")]
|
||||
[SugarColumn(ColumnDescription = "实时值", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
[AutoGenerateColumn(Order = 23, Visible = true, Sortable = true, Filterable = false)]
|
||||
public string Value { get; set; }
|
||||
|
||||
|
@@ -44,7 +44,7 @@ public class SQLRealValue : IPrimaryIdEntity
|
||||
///<summary>
|
||||
///实时值
|
||||
///</summary>
|
||||
[SugarColumn(ColumnDescription = "实时值")]
|
||||
[SugarColumn(ColumnDescription = "实时值", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
|
||||
[AutoGenerateColumn(Order = 21, Visible = true, Sortable = true, Filterable = false)]
|
||||
public string Value { get; set; }
|
||||
|
||||
|
@@ -93,6 +93,8 @@ public partial class SqlHistoryAlarm : BusinessBaseWithCacheAlarm
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_driverPropertys.VariableAlarmEnable == false) return;
|
||||
|
||||
using var db = BusinessDatabaseUtil.GetDb((DbType)_driverPropertys.DbType, _driverPropertys.BigTextConnectStr);
|
||||
if (!_driverPropertys.BigTextScriptHistoryTable.IsNullOrEmpty())
|
||||
{
|
||||
|
@@ -11,8 +11,12 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
#if NET10_0_OR_GREATER
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
#endif
|
||||
using MQTTnet.AspNetCore;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
|
@@ -12,7 +12,6 @@ using CSScripting;
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using MQTTnet;
|
||||
using MQTTnet.Internal;
|
||||
@@ -43,7 +42,7 @@ public partial class MqttServer : BusinessBaseWithCacheIntervalScriptAll
|
||||
|
||||
#if NET10_0_OR_GREATER
|
||||
|
||||
private IHost _webHost { get; set; }
|
||||
private Microsoft.Extensions.Hosting.IHost _webHost { get; set; }
|
||||
|
||||
#else
|
||||
private IWebHost _webHost { get; set; }
|
||||
|
@@ -21,12 +21,12 @@
|
||||
<base href="/" />
|
||||
<title>ThingsGateway</title>
|
||||
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"ThingsGateway.Server.styles.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css?v={this.GetType().Assembly.GetName().Version}") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css") />
|
||||
<link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css") />
|
||||
<link rel="stylesheet" href=@($"ThingsGateway.Server.styles.css") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css") />
|
||||
<link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css") />
|
||||
|
||||
@* <script src=@($"{WebsiteConst.DefaultResourceUrl}js/theme.js") type="module"></script><!-- 初始主题 --> *@
|
||||
<!-- PWA Manifest -->
|
||||
|
@@ -69,7 +69,7 @@
|
||||
<Button @onclick="ShowAbout" class="layout-header-bar d-none d-lg-flex px-2" Icon="fa fa-info" Color="Color.None" TooltipText="@Localizer[nameof(About)]" />
|
||||
}
|
||||
@* 版本号 *@
|
||||
<div class="px-1 navbar-header-text d-none d-lg-block">@_versionString</div>
|
||||
<div class="px-1 navbar-header-text text-nowrap text-nowrap d-none d-lg-block">@_versionString</div>
|
||||
|
||||
@* 主题切换 *@
|
||||
@* <ThemeToggle /> *@
|
||||
|
Reference in New Issue
Block a user