Compare commits

..

3 Commits

Author SHA1 Message Date
Diego
74f6e79625 build: 10.5.7
优化opcua变量缓存
修复cron表达式间隔
2025-04-27 16:35:58 +08:00
Diego
cec43e2ce8 feat: 防呆设计,强制设置通道的最大并发数 2025-04-27 10:13:35 +08:00
Diego
7553b258bb build: 10.5.5 2025-04-26 17:46:31 +08:00
13 changed files with 39 additions and 26 deletions

View File

@@ -32,7 +32,7 @@ public class TimeTick
/// <summary>
/// 上次触发时间
/// </summary>
public DateTime LastTime { get; private set; } = DateTime.Now;
public DateTime LastTime { get; private set; } = DateTime.UtcNow;
/// <summary>
/// 是否触发时间刻度
@@ -62,7 +62,7 @@ public class TimeTick
return result;
}
public DateTime GetNextTime(DateTime currentTime, bool setLastTime = true)
public DateTime GetNextTime(DateTime currentTime, bool setLastTime = false)
{
// 在没有 Cron 表达式的情况下,使用固定间隔
if (cron == null)
@@ -86,7 +86,7 @@ public class TimeTick
}
public DateTime GetNextTime(bool setLastTime = true) => GetNextTime(DateTime.UtcNow, setLastTime);
public DateTime GetNextTime(bool setLastTime = false) => GetNextTime(DateTime.UtcNow, setLastTime);
/// <summary>
/// 是否到达设置的时间间隔

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BootstrapBlazor.FontAwesome" Version="9.0.2" />
<PackageReference Include="BootstrapBlazor" Version="9.5.10" />
<PackageReference Include="BootstrapBlazor" Version="9.5.12" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>

View File

@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<PluginVersion>10.5.4</PluginVersion>
<ProPluginVersion>10.5.4</ProPluginVersion>
<PluginVersion>10.5.7</PluginVersion>
<ProPluginVersion>10.5.7</ProPluginVersion>
<AuthenticationVersion>2.1.7</AuthenticationVersion>
</PropertyGroup>

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CS-Script" Version="4.9.5" />
<PackageReference Include="CS-Script" Version="4.9.6" />
</ItemGroup>
<ItemGroup>

View File

@@ -97,9 +97,17 @@ public abstract class DeviceBase : DisposableObject, IDevice
Channel.Stoping.Add(ChannelStoping);
Channel.Started.Add(ChannelStarted);
Channel.ChannelReceived.Add(ChannelReceived);
SetChannel();
}
}
protected virtual void SetChannel()
{
Channel.ChannelOptions.MaxConcurrentCount = 1;
}
/// <inheritdoc/>
~DeviceBase()
{

View File

@@ -87,12 +87,12 @@ public abstract class BusinessBaseWithCacheIntervalAlarmModel<VarModel, DevModel
// 触发一次设备状态变化和变量值变化事件
CollectDevices?.ForEach(a =>
{
if (a.Value.DeviceStatus == DeviceStatusEnum.OnLine)
if (a.Value.DeviceStatus == DeviceStatusEnum.OnLine && _businessPropertyWithCacheInterval.BusinessUpdateEnum != BusinessUpdateEnum.Interval)
DeviceStatusChange(a.Value, a.Value.Adapt<DeviceBasicData>());
});
IdVariableRuntimes.ForEach(a =>
{
if (a.Value.IsOnline)
if (a.Value.IsOnline && _businessPropertyWithCacheInterval.BusinessUpdateEnum != BusinessUpdateEnum.Interval)
VariableValueChange(a.Value, a.Value.Adapt<VariableBasicData>());
});
}

View File

@@ -85,12 +85,12 @@ public abstract class BusinessBaseWithCacheIntervalDeviceModel<VarModel, DevMode
CollectDevices?.ForEach(a =>
{
if (a.Value.DeviceStatus == DeviceStatusEnum.OnLine)
if (a.Value.DeviceStatus == DeviceStatusEnum.OnLine && _businessPropertyWithCacheInterval.BusinessUpdateEnum != BusinessUpdateEnum.Interval)
DeviceStatusChange(a.Value, a.Value.Adapt<DeviceBasicData>());
});
IdVariableRuntimes.ForEach(a =>
{
if (a.Value.IsOnline)
if (a.Value.IsOnline && _businessPropertyWithCacheInterval.BusinessUpdateEnum != BusinessUpdateEnum.Interval)
VariableValueChange(a.Value, a.Value.Adapt<VariableBasicData>());
});
}

View File

@@ -73,7 +73,7 @@ public abstract class BusinessBaseWithCacheIntervalVariableModel<T> : BusinessBa
// 触发一次变量值变化事件
IdVariableRuntimes.ForEach(a =>
{
if (a.Value.IsOnline)
if (a.Value.IsOnline && _businessPropertyWithCacheInterval.BusinessUpdateEnum != BusinessUpdateEnum.Interval)
VariableValueChange(a.Value, a.Value.Adapt<VariableBasicData>());
});
}

View File

@@ -175,7 +175,7 @@ public class ChannelRuntime : Channel, IChannelOptions, IDisposable
if (a.Value.BindUrl == BindUrl)
return true;
if (a.Value.ChannelType == ChannelTypeEnum.UdpSession)
if (a.Value.BindUrl == BindUrl)
if ((!BindUrl.IsNullOrWhiteSpace()) && a.Value.BindUrl == BindUrl)
return true;
if (a.Value.ChannelType == ChannelTypeEnum.SerialPort)
if (a.Value.PortName == PortName)

View File

@@ -1299,7 +1299,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
try
{
if (Disposed) return;
await Task.Delay(2000);
await Task.Delay(1000);
await OnClickSearch(SearchText);
Value = GetValue(Value);

View File

@@ -251,7 +251,7 @@ public class OpcUaMaster : IDisposable
DisplayName = subscriptionName
};
List<MonitoredItem> monitoredItems = new();
var variableNodes = loadType ? await ReadNodesAsync(items, cancellationToken).ConfigureAwait(false) : null;
var variableNodes = loadType ? await ReadNodesAsync(items, false, cancellationToken).ConfigureAwait(false) : null;
for (int i = 0; i < items.Length; i++)
{
try
@@ -743,7 +743,7 @@ public class OpcUaMaster : IDisposable
NodeId = new NodeId(item.Key),
AttributeId = Attributes.Value,
};
var variableNode = await ReadNodeAsync(item.Key, false, cancellationToken).ConfigureAwait(false);
var variableNode = await ReadNodeAsync(item.Key, false, false, cancellationToken).ConfigureAwait(false);
var dataValue = JsonUtils.Decode(
m_session.MessageContext,
variableNode.DataType,
@@ -793,9 +793,10 @@ public class OpcUaMaster : IDisposable
{
if (m_session != null)
{
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false);
foreach (var value in monitoreditem.DequeueValues())
{
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false, StatusCode.IsGood(value.StatusCode));
if (value.Value != null)
{
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
@@ -974,7 +975,7 @@ public class OpcUaMaster : IDisposable
List<(string, DataValue, JToken)> jTokens = new();
for (int i = 0; i < results.Count; i++)
{
var variableNode = await ReadNodeAsync(nodeIds[i].ToString(), false, cancellationToken).ConfigureAwait(false);
var variableNode = await ReadNodeAsync(nodeIds[i].ToString(), false, StatusCode.IsGood(results[i].StatusCode), cancellationToken).ConfigureAwait(false);
var type = TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable);
var jToken = JsonUtils.Encode(m_session.MessageContext, type, results[i].Value);
jTokens.Add((variableNode.NodeId.ToString(), results[i], jToken));
@@ -985,7 +986,7 @@ public class OpcUaMaster : IDisposable
/// <summary>
/// 从服务器或缓存读取节点
/// </summary>
private VariableNode ReadNode(string nodeIdStr, bool isOnlyServer = true)
private VariableNode ReadNode(string nodeIdStr, bool isOnlyServer = true, bool cache = true)
{
if (!isOnlyServer)
{
@@ -1025,14 +1026,15 @@ public class OpcUaMaster : IDisposable
VariableNode variableNode = GetVariableNodes(itemsToRead, values, diagnosticInfos, responseHeader).FirstOrDefault();
_variableDicts.AddOrUpdate(nodeIdStr, a => variableNode, (a, b) => variableNode);
if (cache)
_variableDicts.AddOrUpdate(nodeIdStr, a => variableNode, (a, b) => variableNode);
return variableNode;
}
/// <summary>
/// 从服务器或缓存读取节点
/// </summary>
private async Task<VariableNode> ReadNodeAsync(string nodeIdStr, bool isOnlyServer = true, CancellationToken cancellationToken = default)
private async Task<VariableNode> ReadNodeAsync(string nodeIdStr, bool isOnlyServer = true, bool cache = true, CancellationToken cancellationToken = default)
{
if (!isOnlyServer)
{
@@ -1073,7 +1075,9 @@ public class OpcUaMaster : IDisposable
if (OpcUaProperty.LoadType && variableNode.DataType != NodeId.Null && TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable) == BuiltInType.ExtensionObject)
await typeSystem.LoadType(variableNode.DataType, ct: cancellationToken).ConfigureAwait(false);
_variableDicts.AddOrUpdate(nodeIdStr, a => variableNode, (a, b) => variableNode);
if (cache)
_variableDicts.AddOrUpdate(nodeIdStr, a => variableNode, (a, b) => variableNode);
return variableNode;
}
@@ -1127,7 +1131,7 @@ public class OpcUaMaster : IDisposable
/// <summary>
/// 从服务器读取节点
/// </summary>
private async Task<List<Node>> ReadNodesAsync(string[] nodeIdStrs, CancellationToken cancellationToken = default)
private async Task<List<Node>> ReadNodesAsync(string[] nodeIdStrs, bool cache = false, CancellationToken cancellationToken = default)
{
List<Node> result = new(nodeIdStrs.Length);
foreach (var items in nodeIdStrs.ChunkBetter(OpcUaProperty.GroupSize))
@@ -1171,7 +1175,8 @@ public class OpcUaMaster : IDisposable
}
else
{
_variableDicts.AddOrUpdate(nodeIdStrs[i], a => node, (a, b) => node);
if (cache)
_variableDicts.AddOrUpdate(nodeIdStrs[i], a => node, (a, b) => node);
if (node.DataType != NodeId.Null && TypeInfo.GetBuiltInType(node.DataType, m_session.SystemContext.TypeTable) == BuiltInType.ExtensionObject)
{
await typeSystem.LoadType(node.DataType, ct: cancellationToken).ConfigureAwait(false);

View File

@@ -162,7 +162,7 @@ public class FileHostService : BackgroundService, IFileHostService
_log.Exception(ex);
try
{
await TcpDmtpService.StopAsync().ConfigureAwait(false);
await TcpDmtpService.StopAsync(default).ConfigureAwait(false);
}
catch
{

View File

@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<Version>10.5.4</Version>
<Version>10.5.7</Version>
</PropertyGroup>
<ItemGroup>