mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 10:50:48 +08:00
10.11.83
This commit is contained in:
@@ -45,6 +45,7 @@ public class VerificatInfo : PrimaryIdEntity
|
||||
/// 登录IP
|
||||
/// </summary>
|
||||
[AutoGenerateColumn(Filterable = true, Sortable = true, Width = 200)]
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string LoginIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -78,5 +79,6 @@ public class VerificatInfo : PrimaryIdEntity
|
||||
/// 登录设备
|
||||
/// </summary>
|
||||
[AutoGenerateColumn(Filterable = true, Sortable = true, Width = 100)]
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string Device { get; set; }
|
||||
}
|
||||
|
@@ -145,7 +145,7 @@ public class AdminOAuthHandler<TOptions>(
|
||||
var loginEvent = new LoginEvent
|
||||
{
|
||||
Ip = appService.RemoteIpAddress,
|
||||
Device = appService.UserAgent?.Platform,
|
||||
Device = appService.UserAgent?.Platform ?? "Unknown",
|
||||
Expire = expire,
|
||||
SysUser = sysUser,
|
||||
VerificatId = CommonUtils.GetSingleId()
|
||||
@@ -156,7 +156,7 @@ public class AdminOAuthHandler<TOptions>(
|
||||
//生成verificat信息
|
||||
var verificatInfo = new VerificatInfo
|
||||
{
|
||||
Device = loginEvent.Device,
|
||||
Device = loginEvent.Device ?? "Unknown",
|
||||
Expire = loginEvent.Expire,
|
||||
VerificatTimeout = tokenTimeout,
|
||||
Id = loginEvent.VerificatId,
|
||||
|
@@ -235,7 +235,7 @@ public class AuthService : IAuthService
|
||||
var logingEvent = new LoginEvent
|
||||
{
|
||||
Ip = _appService.RemoteIpAddress,
|
||||
Device = _appService.UserAgent?.Platform,
|
||||
Device = _appService.UserAgent?.Platform ?? "Unknown",
|
||||
Expire = expire,
|
||||
SysUser = sysUser,
|
||||
VerificatId = verificatId
|
||||
@@ -344,7 +344,7 @@ public class AuthService : IAuthService
|
||||
//生成verificat信息
|
||||
var verificatInfo = new VerificatInfo
|
||||
{
|
||||
Device = loginEvent.Device,
|
||||
Device = loginEvent.Device ?? "Unknown",
|
||||
Expire = loginEvent.Expire,
|
||||
VerificatTimeout = tokenTimeout,
|
||||
Id = loginEvent.VerificatId,
|
||||
|
@@ -51,7 +51,7 @@ public static class AdminResourceUtil
|
||||
Target = item.Target.ToString(),
|
||||
Items = BuildMenuTrees(items, item.Id).ToList()
|
||||
};
|
||||
if(menu.Url.IsNullOrEmpty())
|
||||
if (menu.Url.IsNullOrEmpty())
|
||||
{
|
||||
menu.Match = Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix;
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<PluginVersion>10.11.81</PluginVersion>
|
||||
<ProPluginVersion>10.11.81</ProPluginVersion>
|
||||
<DefaultVersion>10.11.81</DefaultVersion>
|
||||
<PluginVersion>10.11.83</PluginVersion>
|
||||
<ProPluginVersion>10.11.83</ProPluginVersion>
|
||||
<DefaultVersion>10.11.83</DefaultVersion>
|
||||
<AuthenticationVersion>10.11.6</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.11.6</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.20</NET8Version>
|
||||
|
@@ -8,8 +8,6 @@
|
||||
// QQ群:605534569
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Buffers;
|
||||
|
||||
using ThingsGateway.Foundation.Extension.String;
|
||||
|
||||
using TouchSocket.SerialPorts;
|
||||
@@ -101,6 +99,22 @@ public static class ChannelOptionsExtensions
|
||||
if (channelOptions.MaxClientCount > 0)
|
||||
config.SetMaxCount(channelOptions.MaxClientCount);
|
||||
|
||||
// config.SetTransportOption(new TransportOption()
|
||||
// {
|
||||
// MaxBufferSize = 1024,
|
||||
// MinBufferSize = 512,
|
||||
// SendPipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
// minimumSegmentSize: 512,
|
||||
// pauseWriterThreshold: 1024,
|
||||
// resumeWriterThreshold: 512,
|
||||
// useSynchronizationContext: false),
|
||||
// ReceivePipeOptions = new System.IO.Pipelines.PipeOptions(
|
||||
//minimumSegmentSize: 512,
|
||||
// pauseWriterThreshold: 1024,
|
||||
// resumeWriterThreshold: 512,
|
||||
// useSynchronizationContext: false),
|
||||
// });
|
||||
|
||||
config.SetTransportOption(a =>
|
||||
{
|
||||
a.MaxBufferSize = 1024;
|
||||
|
@@ -533,8 +533,6 @@ public abstract class DeviceBase : AsyncAndSyncDisposableObject, IDevice
|
||||
int timeout = 3000,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
|
||||
var waitData = clientChannel.WaitHandlePool.GetWaitDataAsync(out var sign);
|
||||
command.Sign = sign;
|
||||
WaitLock? waitLock = null;
|
||||
@@ -554,19 +552,17 @@ public abstract class DeviceBase : AsyncAndSyncDisposableObject, IDevice
|
||||
if (waitData.Status == WaitDataStatus.Success)
|
||||
return waitData.CompletedData;
|
||||
|
||||
bool timeoutStatus = false;
|
||||
|
||||
var reusableTimeout = _reusableTimeouts.Get();
|
||||
try
|
||||
{
|
||||
|
||||
var cts = reusableTimeout.GetTokenSource(timeout, cancellationToken, Channel.ClosedToken);
|
||||
|
||||
await waitData.WaitAsync(cts.Token).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
timeoutStatus = reusableTimeout.TimeoutStatus;
|
||||
return timeoutStatus
|
||||
return reusableTimeout.TimeoutStatus
|
||||
? new MessageBase(new TimeoutException()) { ErrorMessage = $"Timeout, sign: {sign}" }
|
||||
: new MessageBase(new OperationCanceledException());
|
||||
}
|
||||
@@ -577,7 +573,6 @@ public abstract class DeviceBase : AsyncAndSyncDisposableObject, IDevice
|
||||
finally
|
||||
{
|
||||
reusableTimeout.Set();
|
||||
timeoutStatus = reusableTimeout.TimeoutStatus;
|
||||
_reusableTimeouts.Return(reusableTimeout);
|
||||
}
|
||||
|
||||
@@ -587,7 +582,7 @@ public abstract class DeviceBase : AsyncAndSyncDisposableObject, IDevice
|
||||
}
|
||||
else
|
||||
{
|
||||
var operResult = waitData.Check(timeoutStatus);
|
||||
var operResult = waitData.Check(reusableTimeout.TimeoutStatus);
|
||||
return new MessageBase(operResult) { ErrorMessage = $"{operResult.ErrorMessage}, sign: {sign}" };
|
||||
}
|
||||
}
|
||||
|
@@ -259,7 +259,15 @@ public static class GlobalData
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsRedundantEnable(long deviceId)
|
||||
{
|
||||
if (GlobalData.IdDevices.TryGetValue(deviceId, out var deviceRuntime))
|
||||
{
|
||||
if (deviceRuntime.RedundantEnable && deviceRuntime.RedundantDeviceId != null)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static IEnumerable<VariableRuntime> GetEnableVariables()
|
||||
{
|
||||
return IdVariables.Where(a => a.Value.DeviceRuntime?.Enable != false && a.Value.DeviceRuntime?.ChannelRuntime?.Enable != false && a.Value?.Enable == true).Select(a => a.Value);
|
||||
|
@@ -267,7 +267,7 @@ internal sealed class DeviceService : BaseService<Device>, IDeviceService
|
||||
else
|
||||
ManageHelper.CheckDeviceCount(1);
|
||||
|
||||
if (input.RedundantEnable && GlobalData.IsRedundant(input.RedundantDeviceId ?? 0))
|
||||
if (input.RedundantEnable && GlobalData.IsRedundantEnable(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))
|
||||
|
@@ -13,7 +13,6 @@ 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;
|
||||
|
@@ -34,8 +34,8 @@ namespace ThingsGateway.Foundation;
|
||||
public class ModbusBenchmark : IDisposable
|
||||
{
|
||||
public static int ClientCount = 1;
|
||||
public static int TaskNumberOfItems = 4;
|
||||
public static int NumberOfItems = 40;
|
||||
public static int TaskNumberOfItems = 1;
|
||||
public static int NumberOfItems = 1000;
|
||||
|
||||
private readonly List<IModbusClient> _lgbModbusClients = [];
|
||||
private List<ModbusMaster> thingsgatewaymodbuss = new();
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
|
||||
using HslCommunication.Profinet.Siemens;
|
||||
|
||||
|
@@ -837,10 +837,16 @@ public class OpcUaMaster : IAsyncDisposable
|
||||
{
|
||||
foreach (var value in monitoreditem.DequeueValues())
|
||||
{
|
||||
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false, StatusCode.IsGood(value.StatusCode)).GetAwaiter().GetResult();
|
||||
|
||||
var variableNode = ReadNode(monitoreditem.StartNodeId.ToString(), false, StatusCode.IsGood(value.StatusCode)).GetAwaiter().GetResult();
|
||||
if (value.Value != null)
|
||||
{
|
||||
if (value.Value.GetType().IsRichPrimitive())
|
||||
{
|
||||
DataChangedHandler?.Invoke((variableNode, monitoreditem, value, null));
|
||||
continue;
|
||||
}
|
||||
|
||||
var data = JsonUtils.Encode(m_session.MessageContext, TypeInfo.GetBuiltInType(variableNode.DataType, m_session.SystemContext.TypeTable), value.Value);
|
||||
if (data == null && value.Value != null)
|
||||
{
|
||||
|
@@ -12,6 +12,38 @@ namespace ThingsGateway.Foundation.OpcUa;
|
||||
|
||||
internal static class CollectionExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 判断是否是元组类型
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsValueTuple(this Type type)
|
||||
{
|
||||
return type.Namespace == "System" && type.Name.Contains("ValueTuple`");
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断是否是富基元类型
|
||||
/// </summary>
|
||||
/// <param name="type">类型</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsRichPrimitive(this Type? type)
|
||||
{
|
||||
if (type == null) return false;
|
||||
|
||||
// 处理元组类型
|
||||
if (type.IsValueTuple()) return false;
|
||||
|
||||
// 处理数组类型,基元数组类型也可以是基元类型
|
||||
if (type.IsArray) return type.GetElementType()?.IsRichPrimitive() ?? false;
|
||||
|
||||
// 基元类型或值类型或字符串类型
|
||||
if (type.IsPrimitive || type.IsValueType || type == typeof(string)) return true;
|
||||
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) return type.GenericTypeArguments[0].IsRichPrimitive();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<List<T>> ChunkBetter<T>(this IEnumerable<T> source, int chunkSize)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException(nameof(source));
|
||||
|
@@ -206,7 +206,9 @@ public class OpcDaMaster : CollectBase
|
||||
if (TaskSchedulerLoop?.Stoped == true) return;
|
||||
if (DisposedValue)
|
||||
return;
|
||||
LogMessage?.Trace($"{ToString()} Change:{Environment.NewLine} {values?.ToSystemTextJsonString()}");
|
||||
|
||||
if (LogMessage.LogLevel <= LogLevel.Trace)
|
||||
LogMessage?.Trace($"{ToString()} Change:{Environment.NewLine} {values?.ToSystemTextJsonString()}");
|
||||
|
||||
foreach (var data in values)
|
||||
{
|
||||
@@ -215,11 +217,13 @@ public class OpcDaMaster : CollectBase
|
||||
if (TaskSchedulerLoop?.Stoped == true) return;
|
||||
if (DisposedValue)
|
||||
return;
|
||||
var type = data.Value.GetType();
|
||||
if (data.Value is Array)
|
||||
{
|
||||
type = type.GetElementType();
|
||||
}
|
||||
|
||||
//var type = data.Value.GetType();
|
||||
//if (data.Value is Array)
|
||||
//{
|
||||
// type = type.GetElementType();
|
||||
//}
|
||||
|
||||
if (!VariableAddresDicts.TryGetValue(data.Name, out var itemReads)) return;
|
||||
|
||||
foreach (var item in itemReads)
|
||||
|
@@ -164,8 +164,10 @@ public class OpcUaMaster : CollectBase
|
||||
//如果是订阅模式,连接时添加订阅组
|
||||
if (_plc.OpcUaProperty?.ActiveSubscribe == true && CurrentDevice.VariableSourceReads.Count > 0 && _plc.Session.SubscriptionCount < CurrentDevice.VariableSourceReads.Count)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
foreach (var variableSourceRead in CurrentDevice.VariableSourceReads)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
try
|
||||
{
|
||||
if (_plc.Session.Subscriptions.FirstOrDefault(a => a.DisplayName == variableSourceRead.RegisterAddress) == null)
|
||||
@@ -186,8 +188,8 @@ public class OpcUaMaster : CollectBase
|
||||
checkLog = false;
|
||||
}
|
||||
|
||||
LogMessage?.LogInformation("AddSubscriptions done");
|
||||
}
|
||||
LogMessage?.LogInformation("AddSubscriptions done");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,6 +331,7 @@ public class OpcUaMaster : CollectBase
|
||||
|
||||
private void DataChangedHandler((Opc.Ua.VariableNode variableNode, MonitoredItem monitoredItem, DataValue dataValue, JToken jToken) data)
|
||||
{
|
||||
|
||||
DateTime time = DateTime.Now;
|
||||
try
|
||||
{
|
||||
@@ -338,14 +341,15 @@ public class OpcUaMaster : CollectBase
|
||||
return;
|
||||
if (TaskSchedulerLoop?.Stoped == true) return;
|
||||
|
||||
LogMessage?.Trace($"Change: {Environment.NewLine} {data.monitoredItem.StartNodeId} : {data.jToken?.ToString()}");
|
||||
if (LogMessage.LogLevel <= LogLevel.Trace)
|
||||
LogMessage?.Trace($"Change: {Environment.NewLine} {data.monitoredItem.StartNodeId} : {data.jToken?.ToString() ?? data.dataValue?.Value?.ToJsonString()}");
|
||||
|
||||
//尝试固定点位的数据类型
|
||||
var type = TypeInfo.GetSystemType(TypeInfo.GetBuiltInType(data.variableNode.DataType, _plc.Session.SystemContext.TypeTable), data.variableNode.ValueRank);
|
||||
//var type = TypeInfo.GetSystemType(TypeInfo.GetBuiltInType(data.variableNode.DataType, _plc.Session.SystemContext.TypeTable), data.variableNode.ValueRank);
|
||||
|
||||
if (!VariableAddresDicts.TryGetValue(data.monitoredItem.StartNodeId.ToString(), out var itemReads)) return;
|
||||
|
||||
object value = data.jToken.GetObjectFromJToken();
|
||||
object value = data.jToken?.GetObjectFromJToken() ?? data.dataValue?.Value;
|
||||
|
||||
var isGood = StatusCode.IsGood(data.dataValue.StatusCode);
|
||||
if (_driverProperties.SourceTimestampEnable)
|
||||
@@ -382,6 +386,8 @@ public class OpcUaMaster : CollectBase
|
||||
LogMessage?.LogWarning(ex);
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -100,7 +100,7 @@ public partial class OpcUaMaster : IAsyncDisposable
|
||||
LogMessage?.AddLogger(logger);
|
||||
|
||||
_plc.LogEvent = (a, b, c, d) => LogMessage?.Log((LogLevel)a, b, c, d);
|
||||
_plc.DataChangedHandler += (a) => LogMessage?.Trace($"id:{a.monitoredItem?.StartNodeId};stateCode:{a.dataValue?.StatusCode};value:{a.jToken?.ToString()}");
|
||||
_plc.DataChangedHandler += (a) => LogMessage?.Trace($"id:{a.monitoredItem?.StartNodeId};stateCode:{a.dataValue?.StatusCode};value:{a.jToken?.ToString() ?? a.dataValue?.Value?.ToJsonString()}");
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user