Compare commits

...

15 Commits

Author SHA1 Message Date
Kimdiego2098
96711ba022 2.1.0.5 2023-08-29 17:44:28 +08:00
Kimdiego2098
cbfc0fdbdc 添加报文日志入库选项 2023-08-29 17:42:56 +08:00
Kimdiego2098
6e81886c0e 添加 页脚 编译时间显示 2023-08-29 17:01:46 +08:00
Kimdiego2098
2d976bc132 调整导入excel错误提示 2023-08-29 16:45:54 +08:00
Kimdiego2098
57f6a476af update opcdaclient null error 2023-08-29 15:24:29 +08:00
Kimdiego2098
8491ed296e update GetBoolValue 2023-08-29 12:40:21 +08:00
Kimdiego2098
cd1288afdc 调整种子文件,增加Pro版本种子文件录入 2023-08-29 09:42:54 +08:00
Kimdiego2098
ec6c830cb0 更新2.1.0.4 2023-08-28 19:31:00 +08:00
Kimdiego2098
2f86ccc4bf 修复串口基类 缓存包 失效错误;完善modbusrtu长度校验 2023-08-28 19:25:22 +08:00
Kimdiego2098
8ca445aec0 更新touchsocket版本,更新2.1.0.3 2023-08-28 18:12:18 +08:00
Kimdiego2098
1e1f27c8a5 修复浏览大量节点空间时,BrowseNext方法参数releaseContinuationPoints改为false 2023-08-28 17:44:02 +08:00
Kimdiego2098
2b84bde367 修复调试界面-opcuaclient浏览节点展开逻辑错误 2023-08-28 10:51:35 +08:00
Kimdiego2098
b52e58551d 更新小版本2.1.0.2 2023-08-27 17:17:37 +08:00
Kimdiego2098
9aceed00bf 更新dlt645地址说明 2023-08-27 17:16:59 +08:00
Kimdiego2098
58814f7f74 添加日志查询 时间区间条件 2023-08-27 16:58:45 +08:00
57 changed files with 535 additions and 203 deletions

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.1.0.1</Version>
<Version>2.1.0.5</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -19,7 +19,7 @@
<MSheet>
<MCard Flat Href=@CONFIG_COPYRIGHT_URL Target="_blank">
<MLabel Style="background-color:inherit;" Class="text-subtltie-2">@CONFIG_COPYRIGHT</MLabel>
<MLabel Style="background-color:inherit;" Class="text-subtltie-2 ml-4">@Version</MLabel>
<MLabel Style="background-color:inherit;white-space: pre;" Class="text-subtltie-2 ml-4">@Version</MLabel>
</MCard>
</MSheet>

View File

@@ -14,6 +14,8 @@ using Microsoft.AspNetCore.Components;
using System.Reflection;
using ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>
/// Foter
@@ -40,7 +42,12 @@ public partial class Foter
/// <inheritdoc/>
protected override async Task OnParametersSetAsync()
{
Version = "v" + Assembly.GetExecutingAssembly().GetName().Version.ToString();
var assembly = Assembly.GetEntryAssembly();
if (assembly != null)
{
Version = $"v{assembly.GetName().Version} {new System.IO.FileInfo(assembly.Location).LastWriteTime.ToDefaultDateTimeFormat()}";
}
await base.OnParametersSetAsync();
}

View File

@@ -14,7 +14,7 @@
<ItemGroup>
<PackageReference Include="Masa.Blazor" Version="1.0.2" />
<PackageReference Include="Masa.Blazor" Version="1.0.3" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.10" />
</ItemGroup>

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
@@ -157,7 +159,7 @@ public abstract class CollectBase : DriverBase
{
deviceVariableSourceRead.DeviceVariables.ForEach(it =>
{
var operResult = it.SetValue(null,isOnline:false);
var operResult = it.SetValue(null, isOnline: false);
if (!operResult.IsSuccess)
{
_logger.LogWarning("变量值更新失败:" + operResult.Message);
@@ -220,6 +222,31 @@ public abstract class CollectBase : DriverBase
}
}
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsSaveLog)
{
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
{
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
if ((byte)arg1 < (byte)customLevel)
{
var logRuntime = new BackendLog
{
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
LogMessage = arg3,
LogSource = "采集设备:" + CurDevice.Name,
LogTime = SysDateTimeExtensions.CurrentDateTime,
Exception = null,
};
_logQueues.Enqueue(logRuntime);
}
}
}
base.NewMessage(arg1, arg2, arg3, arg4);
}
/// <summary>
/// 返回全部内容字节数组
/// <br></br>

View File

@@ -12,7 +12,10 @@
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Extension.ConcurrentQueue;
using TouchSocket.Core;
@@ -40,6 +43,7 @@ public abstract class DriverBase : DisposableObject
LogMessage = new LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(Log_Out) { LogLevel = TouchSocket.Core.LogLevel.Trace });
FoundataionConfig.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
Task.Factory.StartNew(LogInsertAsync);
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
@@ -67,6 +71,12 @@ public abstract class DriverBase : DisposableObject
/// </summary>
public bool IsLogOut { get; set; }
/// <summary>
/// 是否存储报文
/// </summary>
public bool IsSaveLog { get; set; }
/// <summary>
/// 报文信息
/// </summary>
@@ -82,11 +92,14 @@ public abstract class DriverBase : DisposableObject
/// </summary>
/// <returns></returns>
public abstract bool IsConnected();
/// <summary>
/// 存储日志队列
/// </summary>
protected ConcurrentQueue<BackendLog> _logQueues = new();
/// <summary>
/// 设备报文
/// </summary>
internal void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
internal virtual void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsLogOut)
{
@@ -102,6 +115,27 @@ public abstract class DriverBase : DisposableObject
}
}
private async Task LogInsertAsync()
{
var db = DbContext.Db.CopyNew();
while (!DisposedValue)
{
if (_logQueues.Count > 0)
{
try
{
var data = _logQueues.ToListWithDequeue();
await db.InsertableWithAttr(data).ExecuteCommandAsync();//入库
}
catch
{
}
}
await Task.Delay(5000);
}
}
/// <summary>
/// 底层日志输出

View File

@@ -14,6 +14,8 @@ using Furion;
using Microsoft.Extensions.Logging;
using ThingsGateway.Foundation;
using TouchSocket.Core;
namespace ThingsGateway.Application;
@@ -153,6 +155,32 @@ public abstract class UpLoadBase : DriverBase
_logger.Log_Out(arg1, arg2, arg3, arg4);
}
}
internal override void NewMessage(TouchSocket.Core.LogLevel arg1, object arg2, string arg3, Exception arg4)
{
if (IsSaveLog)
{
if (arg3.StartsWith(FoundationConst.LogMessageHeader))
{
var customLevel = App.GetConfig<Microsoft.Extensions.Logging.LogLevel?>("Logging:LogLevel:BackendLog") ?? Microsoft.Extensions.Logging.LogLevel.Trace;
if ((byte)arg1 < (byte)customLevel)
{
var logRuntime = new BackendLog
{
LogLevel = (Microsoft.Extensions.Logging.LogLevel)arg1,
LogMessage = arg3,
LogSource = "上传设备:" + CurDevice.Name,
LogTime = SysDateTimeExtensions.CurrentDateTime,
Exception = null,
};
_logQueues.Enqueue(logRuntime);
}
}
}
base.NewMessage(arg1, arg2, arg3, arg4);
}
}

View File

@@ -22,6 +22,9 @@ public class DriverPluginSeedData : ISqlSugarEntitySeedData<DriverPlugin>
/// <inheritdoc/>
public IEnumerable<DriverPlugin> SeedData()
{
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json");
return SeedDataUtil.GetSeedData<DriverPlugin>("driver_plugin.json")
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("pro_driver_plugin.json"))
.Concat(SeedDataUtil.GetSeedData<DriverPlugin>("custom_driver_plugin.json"))
;
}
}

View File

@@ -22,6 +22,6 @@ public class OpenApiUserSeedData : ISqlSugarEntitySeedData<OpenApiUser>
/// <inheritdoc/>
public IEnumerable<OpenApiUser> SeedData()
{
return SeedDataUtil.GetSeedData<OpenApiUser>("gatewayopenapi_user.json");
return SeedDataUtil.GetSeedData<OpenApiUser>("gateway_openapi_user.json");
}
}

View File

@@ -86,6 +86,8 @@ public class BackendLogService : DbRepository<BackendLog>, IBackendLogService
private ISugarQueryable<BackendLog> GetPage(BackendLogPageInput input)
{
var query = Context.Queryable<BackendLog>()
.WhereIF(input.StartTime != null, a => a.LogTime >= input.StartTime.Value.ToLocalTime())
.WhereIF(input.EndTime != null, a => a.LogTime <= input.EndTime.Value.ToLocalTime())
.WhereIF(!string.IsNullOrEmpty(input.Source), it => it.LogSource.Contains(input.Source))
.WhereIF(!string.IsNullOrEmpty(input.Level), it => it.LogLevel.ToString().Contains(input.Level));
for (int i = 0; i < input.SortField.Count; i++)

View File

@@ -19,6 +19,15 @@ namespace ThingsGateway.Application;
/// </summary>
public class BackendLogPageInput : BasePageInput
{
/// <summary>
/// 开始时间
/// </summary>
public DateTime? StartTime { get; set; } = DateTime.UtcNow.AddDays(-1);
/// <summary>
/// 结束时间
/// </summary>
public DateTime? EndTime { get; set; } = DateTime.UtcNow.AddDays(1);
/// <summary>
/// 日志源
/// </summary>
@@ -55,6 +64,14 @@ public class BackendLogInput
/// </summary>
public class RpcLogPageInput : BasePageInput
{
/// <summary>
/// 开始时间
/// </summary>
public DateTime? StartTime { get; set; } = DateTime.UtcNow.AddDays(-1);
/// <summary>
/// 结束时间
/// </summary>
public DateTime? EndTime { get; set; } = DateTime.UtcNow.AddDays(1);
/// <summary>
/// 操作源
/// </summary>

View File

@@ -44,6 +44,8 @@ public class RpcLogService : DbRepository<RpcLog>, IRpcLogService
private ISugarQueryable<RpcLog> GetPage(RpcLogPageInput input)
{
var query = Context.Queryable<RpcLog>()
.WhereIF(input.StartTime != null, a => a.LogTime >= input.StartTime.Value.ToLocalTime())
.WhereIF(input.EndTime != null, a => a.LogTime <= input.EndTime.Value.ToLocalTime())
.WhereIF(!string.IsNullOrEmpty(input.Source), it => it.OperateSource.Contains(input.Source))
.WhereIF(!string.IsNullOrEmpty(input.Object), it => it.OperateObject.Contains(input.Object))
.WhereIF(!string.IsNullOrEmpty(input.Method), it => it.OperateMethod.Contains(input.Method));

View File

@@ -6,7 +6,7 @@
<ItemGroup>
<None Remove="SeedData\Json\driver_plugin.json" />
<None Remove="SeedData\Json\gatewayopenapi_user.json" />
<None Remove="SeedData\Json\gateway_openapi_user.json" />
<None Remove="SeedData\Json\gateway_relation.json" />
</ItemGroup>
@@ -24,7 +24,7 @@
<Content Include="SeedData\Json\gateway_resource.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="SeedData\Json\gatewayopenapi_user.json">
<Content Include="SeedData\Json\gateway_openapi_user.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="SeedData\Json\gateway_relation.json">

View File

@@ -1978,6 +1978,11 @@
是否输出日志
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.IsSaveLog">
<summary>
是否存储报文
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.Messages">
<summary>
报文信息
@@ -1994,6 +1999,11 @@
</summary>
<returns></returns>
</member>
<member name="F:ThingsGateway.Application.DriverBase._logQueues">
<summary>
存储日志队列
</summary>
</member>
<member name="M:ThingsGateway.Application.DriverBase.NewMessage(TouchSocket.Core.LogLevel,System.Object,System.String,System.Exception)">
<summary>
设备报文
@@ -2583,6 +2593,16 @@
运行日志分页DTO
</summary>
</member>
<member name="P:ThingsGateway.Application.BackendLogPageInput.StartTime">
<summary>
开始时间
</summary>
</member>
<member name="P:ThingsGateway.Application.BackendLogPageInput.EndTime">
<summary>
结束时间
</summary>
</member>
<member name="P:ThingsGateway.Application.BackendLogPageInput.Source">
<summary>
日志源
@@ -2613,6 +2633,16 @@
RPC日志分页DTO
</summary>
</member>
<member name="P:ThingsGateway.Application.RpcLogPageInput.StartTime">
<summary>
开始时间
</summary>
</member>
<member name="P:ThingsGateway.Application.RpcLogPageInput.EndTime">
<summary>
结束时间
</summary>
</member>
<member name="P:ThingsGateway.Application.RpcLogPageInput.Source">
<summary>
操作源

View File

@@ -75,30 +75,33 @@
(item.Value.HasError ? "出现错误" : "验证成功")
)
</MSubheader>
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results">
<ItemContent>
<MListItem>
<MListItemAction>
<MChip Class="ma-2">
@(
if (item.Value.HasError)
{
<MVirtualScroll Context="item1" Height=300 OverscanCount=2 ItemSize="60" Items="item.Value.Results.Where(a=>!a.isSuccess).ToList()">
<ItemContent>
<MListItem>
<MListItemAction>
<MChip Class="ma-2">
@(
$"第{item1.row}行"
)
</MChip>
</MListItemAction>
</MChip>
</MListItemAction>
<MListItemContent>
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
<strong>@item1.resultString</strong>
</MListItemTitle>
</MListItemContent>
<MListItemContent>
<MListItemTitle Class=@((item1.isSuccess?"green--text":"red--text"))>
<strong>@item1.resultString</strong>
</MListItemTitle>
</MListItemContent>
</MListItem>
</MListItem>
<MDivider></MDivider>
<MDivider></MDivider>
</ItemContent>
</MVirtualScroll>
</ItemContent>
</MVirtualScroll>
}
}

View File

@@ -82,7 +82,7 @@ public partial class TcpClientPage
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(IP + ":" + Port)).SetBufferLength(300);
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
//载入配置
TcpClientEx.Setup(config);
return TcpClientEx;
@@ -96,7 +96,7 @@ public partial class TcpClientPage
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(IP + ":" + Port)).SetBufferLength(300);
config.SetRemoteIPHost(new IPHost(IP + ":" + Port));
TcpClientEx = new TcpClientEx();
TcpClientEx.Setup(config);
base.OnInitialized();

View File

@@ -72,7 +72,6 @@ public partial class TcpServerPage
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
config.SetBufferLength(300);
//载入配置
TcpServer.Setup(config);
return TcpServer;
@@ -88,7 +87,6 @@ public partial class TcpServerPage
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetListenIPHosts(new IPHost[] { new IPHost(ip + ":" + port) });
config.SetBufferLength(300);
TcpServer = new TcpService();
TcpServer.Setup(config);
base.OnInitialized();

View File

@@ -71,7 +71,7 @@ public partial class UdpSessionPage : IDisposable
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(ip + ":" + port)).SetBufferLength(300);
config.SetRemoteIPHost(new IPHost(ip + ":" + port));
config.SetBindIPHost(new IPHost(0));
//载入配置
UdpSession.Setup(config);
@@ -88,7 +88,7 @@ public partial class UdpSessionPage : IDisposable
var LogMessage = new TouchSocket.Core.LoggerGroup() { LogLevel = TouchSocket.Core.LogLevel.Trace };
LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace });
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetRemoteIPHost(new IPHost(ip + ":" + port)).SetBufferLength(300);
config.SetRemoteIPHost(new IPHost(ip + ":" + port));
config.SetBindIPHost(new IPHost(0));
UdpSession = new UdpSession();
UdpSession.Setup(config);

View File

@@ -32,6 +32,30 @@
IsShowDetailButton
IsShowQueryButton>
<SearchTemplate>
<MMenu CloseOnContentClick="false" OffsetY Context="menu">
<ActivatorContent>
<MTextField Dense Readonly Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 "
Value="context.StartTime.Value.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)"
@attributes="menu.Attrs" Outlined Label=@context.Description(x => x.StartTime) />
</ActivatorContent>
<ChildContent>
<AppDateTimePicker @bind-Value="context.StartTime"></AppDateTimePicker>
</ChildContent>
</MMenu>
<MMenu CloseOnContentClick="false" OffsetY Context="menu">
<ActivatorContent>
<MTextField Dense Readonly Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 "
Value="context.EndTime.Value.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)" Clearable
@attributes="menu.Attrs" Outlined Label=@context.Description(x => x.EndTime) />
</ActivatorContent>
<ChildContent>
<AppDateTimePicker @bind-Value="context.EndTime"></AppDateTimePicker>
</ChildContent>
</MMenu>
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 " @bind-Value="context.Source"
Outlined Label=@context.Description(x => x.Source) />
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 " @bind-Value="context.Level"

View File

@@ -30,6 +30,8 @@ public partial class BackendLogPage
[Inject]
AjaxService AjaxService { get; set; }
[Inject]
InitTimezone InitTimezone { get; set; }
private async Task ClearClickAsync()
{
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");

View File

@@ -253,6 +253,23 @@
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
OnClick=@(()=>
{
if(collectDeviceInfoItem.Driver!=null)
collectDeviceInfoItem.Driver.IsSaveLog=! collectDeviceInfoItem.Driver.IsSaveLog;
}
)>
<MIcon>@((collectDeviceInfoItem.Driver?.IsSaveLog==true) ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<span>@((collectDeviceInfoItem.Driver?.IsSaveLog != true) ? "存入数据库,注意若交互频繁,可能导致数据库太大" : "不存入数据库")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Loading=isDownExport Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small

View File

@@ -30,6 +30,31 @@
QueryCallAsync="QueryCallAsync"
IsShowDetailButton IsShowQueryButton>
<SearchTemplate>
<MMenu CloseOnContentClick="false" OffsetY Context="menu">
<ActivatorContent>
<MTextField Dense Readonly Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 "
Value="context.StartTime.Value.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)"
@attributes="menu.Attrs" Outlined Label=@context.Description(x => x.StartTime) />
</ActivatorContent>
<ChildContent>
<AppDateTimePicker @bind-Value="context.StartTime"></AppDateTimePicker>
</ChildContent>
</MMenu>
<MMenu CloseOnContentClick="false" OffsetY Context="menu">
<ActivatorContent>
<MTextField Dense Readonly Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 "
Value="context.EndTime.Value.ToDefaultDateTimeFormat(InitTimezone.TimezoneOffset)" Clearable
@attributes="menu.Attrs" Outlined Label=@context.Description(x => x.EndTime) />
</ActivatorContent>
<ChildContent>
<AppDateTimePicker @bind-Value="context.EndTime"></AppDateTimePicker>
</ChildContent>
</MMenu>
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 " @bind-Value="context.Source"
Outlined Label=@context.Description(x => x.Source) />
<MTextField Dense Style="max-width:200px;" HideDetails=@("auto") Class="my-1 mx-2 " @bind-Value="context.Object"

View File

@@ -29,7 +29,8 @@ public partial class RpcLogPage
[Inject]
AjaxService AjaxService { get; set; }
[Inject]
InitTimezone InitTimezone { get; set; }
private async Task ClearClickAsync()
{
var confirm = await PopupService.OpenConfirmDialogAsync("删除", "确定 ?");

View File

@@ -24,6 +24,8 @@ public static class ReadWriteDevicesExHelpers
/// <returns></returns>
public static bool GetBoolValue(this string value)
{
if (value == null)
return false;
if (value == "1")
return true;
if (value == "0")

View File

@@ -64,13 +64,25 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
public TcpClientBaseEx()
{
this.Protocol = Protocol.Tcp;
this.m_receiveCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnReceivePeriod
};
this.m_sendCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnSendPeriod
};
}
#region
private DelaySender m_delaySender;
private Stream m_workStream;
private int m_bufferRate = 1;
private long m_bufferRate = 1;
private volatile bool m_online;
ValueCounter m_receiveCounter;
ValueCounter m_sendCounter;
#endregion
#region
@@ -115,8 +127,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
private void PrivateOnConnecting(ConnectingEventArgs e)
{
this.LastReceivedTime = DateTime.Now;
this.LastSendTime = DateTime.Now;
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
@@ -206,10 +216,10 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
#region
/// <inheritdoc/>
public DateTime LastReceivedTime { get; private set; }
public DateTime LastReceivedTime => this.m_receiveCounter.LastIncrement;
/// <inheritdoc/>
public DateTime LastSendTime { get; private set; }
public DateTime LastSendTime => this.m_sendCounter.LastIncrement;
/// <inheritdoc/>
public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
@@ -520,6 +530,44 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
return this.m_workStream;
}
private void OnReceivePeriod(long value)
{
this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value);
}
private void OnSendPeriod(long value)
{
this.SendBufferSize = TouchSocketUtility.HitBufferLength(value);
}
/// <inheritdoc/>
public override int ReceiveBufferSize
{
get => base.ReceiveBufferSize;
set
{
base.ReceiveBufferSize = value;
if (this.MainSocket != null)
{
this.MainSocket.ReceiveBufferSize = base.ReceiveBufferSize;
}
}
}
/// <inheritdoc/>
public override int SendBufferSize
{
get => base.SendBufferSize;
set
{
base.SendBufferSize = value;
if (this.MainSocket != null)
{
this.MainSocket.SendBufferSize = base.SendBufferSize;
}
}
}
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
{
@@ -655,10 +703,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
protected virtual void LoadConfig(TouchSocketConfig config)
{
this.RemoteIPHost = config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty);
if (config.GetValue(TouchSocketConfigExtension.BufferLengthProperty) is int value)
{
this.SetBufferLength(value);
}
this.Logger ??= this.Container.Resolve<ILog>();
this.ReceiveType = config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty);
}
@@ -727,7 +771,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
var eventArgs = new SocketAsyncEventArgs();
eventArgs.Completed += this.EventArgs_Completed;
var byteBlock = BytePool.Default.GetByteBlock(this.BufferLength);
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
eventArgs.UserToken = byteBlock;
eventArgs.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity);
if (!this.MainSocket.ReceiveAsync(eventArgs))
@@ -750,7 +794,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
while (true)
{
var byteBlock = new ByteBlock(this.BufferLength);
var byteBlock = new ByteBlock(this.ReceiveBufferSize);
try
{
var r = this.MainSocket.Receive(byteBlock.Buffer);
@@ -773,7 +817,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
private void BeginSsl()
{
var byteBlock = new ByteBlock(this.BufferLength);
var byteBlock = new ByteBlock(this.ReceiveBufferSize);
try
{
this.m_workStream.BeginRead(byteBlock.Buffer, 0, byteBlock.Capacity, this.EndSsl, byteBlock);
@@ -813,8 +857,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
@@ -822,8 +864,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
socket = new Socket(iPHost.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
@@ -831,8 +871,8 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
#if NET45_OR_GREATER
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
@@ -880,7 +920,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
this.LastReceivedTime = DateTime.Now;
this.m_receiveCounter.Increment(byteBlock.Length);
if (this.OnHandleRawBuffer?.Invoke(byteBlock) == false)
{
return;
@@ -1075,8 +1115,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.MainSocket.AbsoluteSend(buffer, offset, length);
}
}
this.LastSendTime = DateTime.Now;
this.m_sendCounter.Increment(length);
}
}
@@ -1138,7 +1177,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength));
e.UserToken = newByteBlock;
e.SetBuffer(newByteBlock.Buffer, 0, newByteBlock.Capacity);

View File

@@ -84,7 +84,13 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat
byteBlock.Read(out byte[] body, request.BodyLength);
var bytes = request.HeadBytes.SpliceArray(body);
return GetResponse(byteBlock, request, body, bytes);
var result = GetResponse(byteBlock, request, body, bytes);
if (result == FilterResult.Cache)
{
byteBlock.Pos = pos;//回退游标
}
return result;
}
else
{

View File

@@ -18,21 +18,18 @@ namespace ThingsGateway.Foundation.Serial;
public interface ISerial : IDisposable
{
/// <summary>
/// 数据交互缓存池限制
/// 发送缓存区大小。最小值=1024。
/// </summary>
int BufferLength { get; }
int SendBufferSize { get; set; }
/// <summary>
/// 接收缓存区大小。最小值=1024。
/// </summary>
int ReceiveBufferSize { get; set; }
/// <summary>
/// 日志记录器
/// </summary>
ILog Logger { get; }
/// <summary>
/// 设置数据交互缓存池尺寸min=1024 byte。
/// 一般情况下该值用于三个方面,包括:发送、接收缓存,及内存池的默认申请。
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
int SetBufferLength(int value);
ILog Logger { get; set; }
}

View File

@@ -20,39 +20,22 @@ public abstract class BaseSerial : DependencyObject, ISerial
/// <summary>
/// 同步根。
/// </summary>
protected readonly object SyncRoot;
protected readonly object SyncRoot = new object();
private int m_receiveBufferSize = 1024 * 64;
private int m_sendBufferSize = 1024 * 64;
/// <summary>
/// 通讯基类
/// </summary>
public BaseSerial()
/// <inheritdoc/>
public virtual int SendBufferSize
{
this.SyncRoot = new object();
get => m_sendBufferSize;
set => m_sendBufferSize = value < 1024 ? 1024 : value;
}
/// <summary>
/// 数据交互缓存池限制min=1024 byte
/// </summary>
public int BufferLength { get; private set; } = 64 * 1024;
/// <summary>
/// 日志记录器
/// </summary>
/// <inheritdoc/>
public virtual int ReceiveBufferSize
{
get => m_receiveBufferSize;
set => m_receiveBufferSize = value < 1024 ? 1024 : value;
}
/// <inheritdoc/>
public ILog Logger { get; set; }
/// <summary>
/// 设置数据交互缓存池尺寸min=1024 byte。
/// 一般情况下该值用于三个方面包括socket的发送、接收缓存及内存池的默认申请。
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public virtual int SetBufferLength(int value)
{
if (value < 1024)
{
value = 1024;
}
this.BufferLength = value;
return this.BufferLength;
}
}

View File

@@ -60,12 +60,27 @@ public class SerialSessionBase : BaseSerial, ISerialSession
public SerialSessionBase()
{
this.Protocol = SerialPort;
this.m_receiveCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnReceivePeriod
};
this.m_sendCounter = new ValueCounter
{
Period = TimeSpan.FromSeconds(1),
OnPeriod = this.OnSendPeriod
};
}
#region
private SerialDelaySender m_delaySender;
private int m_bufferRate = 1;
private long m_bufferRate = 1;
private volatile bool m_online;
ValueCounter m_receiveCounter;
ValueCounter m_sendCounter;
#endregion
#region
@@ -110,8 +125,6 @@ public class SerialSessionBase : BaseSerial, ISerialSession
private void PrivateOnConnecting(SerialConnectingEventArgs e)
{
this.LastReceivedTime = DateTime.Now;
this.LastSendTime = DateTime.Now;
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
@@ -201,10 +214,10 @@ public class SerialSessionBase : BaseSerial, ISerialSession
#region
/// <inheritdoc/>
public DateTime LastReceivedTime { get; private set; }
public DateTime LastReceivedTime => this.m_receiveCounter.LastIncrement;
/// <inheritdoc/>
public DateTime LastSendTime { get; private set; }
public DateTime LastSendTime => this.m_sendCounter.LastIncrement;
/// <inheritdoc/>
public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
@@ -370,7 +383,43 @@ public class SerialSessionBase : BaseSerial, ISerialSession
}
#endregion
private void OnReceivePeriod(long value)
{
this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value);
}
private void OnSendPeriod(long value)
{
this.SendBufferSize = TouchSocketUtility.HitBufferLength(value);
}
/// <inheritdoc/>
public override int ReceiveBufferSize
{
get => base.ReceiveBufferSize;
set
{
base.ReceiveBufferSize = value;
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
{
this.MainSerialPort.ReadBufferSize = base.ReceiveBufferSize;
}
}
}
/// <inheritdoc/>
public override int SendBufferSize
{
get => base.SendBufferSize;
set
{
base.SendBufferSize = value;
if (this.MainSerialPort != null && !MainSerialPort.IsOpen)
{
this.MainSerialPort.WriteBufferSize = base.SendBufferSize;
}
}
}
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter)
@@ -499,10 +548,6 @@ public class SerialSessionBase : BaseSerial, ISerialSession
protected virtual void LoadConfig(TouchSocketConfig config)
{
this.SerialProperty = config.GetValue(SerialConfigExtension.SerialProperty);
if (config.GetValue(TouchSocketConfigExtension.BufferLengthProperty) is int value)
{
this.SetBufferLength(value);
}
this.Logger ??= this.Container.Resolve<ILog>();
this.ReceiveType = config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty);
}
@@ -546,7 +591,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
if (this.ReceiveType == ReceiveType.Iocp)
{
SerialReceivedEventArgs eventArgs = new();
var byteBlock = BytePool.Default.GetByteBlock(this.BufferLength);
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
byteBlock.SetLength(0);
eventArgs.UserToken = byteBlock;
if (this.MainSerialPort.BytesToRead > 0)
@@ -580,7 +625,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
{
this.m_bufferRate = 1;
SerialReceivedEventArgs eventArgs = new();
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength));
newByteBlock.SetLength(0);
eventArgs.UserToken = newByteBlock;
if (MainSerialPort.BytesToRead > 0)
@@ -597,7 +642,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
{
while (true)
{
var byteBlock = new ByteBlock(this.BufferLength);
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
try
{
int r = MainSerialPort.Read(byteBlock.Buffer, 0, MainSerialPort.BytesToRead);
@@ -630,11 +675,11 @@ public class SerialSessionBase : BaseSerial, ISerialSession
byte[] buffer = new byte[2048];
var byteBlock = (ByteBlock)e.UserToken;
int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead);
byteBlock.Write(buffer, byteBlock.Len, num);
byteBlock.Write(buffer, 0, num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength));
newByteBlock.SetLength(num);
e.UserToken = newByteBlock;
@@ -678,7 +723,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
{
try
{
this.LastReceivedTime = DateTime.Now;
this.m_receiveCounter.Increment(byteBlock.Length);
if (this.OnHandleRawBuffer?.Invoke(byteBlock) == false)
{
return;
@@ -867,7 +912,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession
this.MainSerialPort.AbsoluteSend(buffer, offset, length);
}
this.LastSendTime = DateTime.Now;
this.m_sendCounter.Increment(length);
}
}

View File

@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.154" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.156" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'!='net45'">
<PackageReference Include="System.IO.Ports" Version="7.0.0" />

View File

@@ -837,6 +837,12 @@
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.GetStream">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.TcpClientBaseEx.ReceiveBufferSize">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.TcpClientBaseEx.SendBufferSize">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<inheritdoc/>
</member>
@@ -1820,9 +1826,14 @@
串口基接口
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerial.BufferLength">
<member name="P:ThingsGateway.Foundation.Serial.ISerial.SendBufferSize">
<summary>
数据交互缓存池限制
发送缓存区大小。最小值=1024。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerial.ReceiveBufferSize">
<summary>
接收缓存区大小。最小值=1024。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerial.Logger">
@@ -1830,14 +1841,6 @@
日志记录器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerial.SetBufferLength(System.Int32)">
<summary>
设置数据交互缓存池尺寸min=1024 byte。
一般情况下该值用于三个方面,包括:发送、接收缓存,及内存池的默认申请。
</summary>
<param name="value"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Serial.ISerialSession">
<summary>
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.ISerialSessionBase"/>
@@ -1936,28 +1939,14 @@
同步根。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.BaseSerial.#ctor">
<summary>
通讯基类
</summary>
<member name="P:ThingsGateway.Foundation.Serial.BaseSerial.SendBufferSize">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.BaseSerial.BufferLength">
<summary>
数据交互缓存池限制min=1024 byte
</summary>
<member name="P:ThingsGateway.Foundation.Serial.BaseSerial.ReceiveBufferSize">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.BaseSerial.Logger">
<summary>
日志记录器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.BaseSerial.SetBufferLength(System.Int32)">
<summary>
设置数据交互缓存池尺寸min=1024 byte。
一般情况下该值用于三个方面包括socket的发送、接收缓存及内存池的默认申请。
</summary>
<param name="value"></param>
<returns></returns>
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialDelaySender">
<summary>
@@ -2157,6 +2146,12 @@
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.ConnectAsync">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.ReceiveBufferSize">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.SendBufferSize">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<inheritdoc/>
</member>

View File

@@ -27,7 +27,7 @@ namespace DLT645Test
.SetSerialProperty(new SerialProperty() //串口链路才需要
{
PortName = "COM1"
}).SetBufferLength(1024);
});
var serialSession = new SerialsSession();//链路对象
serialSession.Setup(config);

View File

@@ -61,7 +61,7 @@ namespace ModbusDemo
.SetSerialProperty(new SerialProperty() //串口链路才需要
{
PortName = "COM1"
}).SetBufferLength(1024);
});
var tcpClient1 = new TcpClientEx();//链路对象
var tcpClient2 = new TcpClientEx();//链路对象

View File

@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Version>2.1.0.1</Version>
<Version>2.1.0.5</Version>
<Authors>Diego</Authors>
<Product>ThingsGateway</Product>
<Copyright>© 2023-present Diego</Copyright>

View File

@@ -70,7 +70,24 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
[Description("通讯地址")]
public string Station { get; set; }
/// <inheritdoc/>
public override string GetAddressDescription() => base.GetAddressDescription() + Environment.NewLine;
public override string GetAddressDescription()
{
var str = """
-----------------------------------------
02010100 A相电压
02020100 A相电流
02030000
00000000 ()
00010000 ()
""";
return base.GetAddressDescription() + Environment.NewLine + str;
}
/// <inheritdoc/>
public override async Task<OperResult<byte[]>> ReadAsync(string address, int length, CancellationToken token = default)
{

View File

@@ -22,13 +22,13 @@ public class DLT645_2007Message : MessageBase, IMessage
/// <inheritdoc/>
public override bool CheckHeadBytes(byte[] head)
{
BodyLength = -1;
return true;
}
/// <inheritdoc/>
protected override void SendBytesThen()
{
BodyLength = -1;
}
}

View File

@@ -124,6 +124,13 @@ internal class ModbusHelper
{
if (response.Length < 3)
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
if (response[1] >= 0x80)//错误码
return new OperResult<byte[], FilterResult>(GetDescriptionByErrorCode(response[2])) { Content2 = FilterResult.Success };
if ((response.Length < response[2] + 5))
return new OperResult<byte[], FilterResult>("数据长度不足" + response.ToHexString()) { Content2 = FilterResult.Cache };
var data = response.SelectMiddle(0, response[2] + 5);
if (crcCheck && !EasyCRC16.CheckCRC16(data))
return new OperResult<byte[], FilterResult>("Crc校验失败" + DataTransUtil.ByteToHexString(data, ' ')) { Content2 = FilterResult.Success };

View File

@@ -22,13 +22,13 @@ public class ModbusRtuMessage : MessageBase, IMessage
/// <inheritdoc/>
public override bool CheckHeadBytes(byte[] head)
{
BodyLength = -1;
return true;
}
/// <inheritdoc/>
protected override void SendBytesThen()
{
BodyLength = -1;
}
}

View File

@@ -519,8 +519,12 @@ public class OPCDAClient : DisposableObject
{
if (IsConnected)
_logger?.Trace($"{m_server.Host + " - " + m_server.Name} - 断开连接");
checkTimer.Enabled = false;
checkTimer.Stop();
if (checkTimer != null)
{
checkTimer.Enabled = false;
checkTimer.Stop();
}
try
{
m_server?.SafeDispose();

View File

@@ -14,6 +14,7 @@ using Opc.Ua;
using Opc.Ua.Client;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -150,6 +151,26 @@ public class FormUtils
return null;
}
}
/// <summary>
/// Create the continuation point collection from the browse result
/// collection for the BrowseNext service.
/// </summary>
/// <param name="browseResultCollection">The browse result collection to use.</param>
/// <returns>The collection of continuation points for the BrowseNext service.</returns>
private static ByteStringCollection PrepareBrowseNext(BrowseResultCollection browseResultCollection)
{
var continuationPoints = new ByteStringCollection();
foreach (var browseResult in browseResultCollection)
{
if (browseResult.ContinuationPoint != null)
{
continuationPoints.Add(browseResult.ContinuationPoint);
}
}
return continuationPoints;
}
/// <summary>
/// 浏览地址空间
/// </summary>
@@ -180,10 +201,17 @@ public class FormUtils
ClientBase.ValidateResponse(results, nodesToBrowse);
ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToBrowse);
ByteStringCollection continuationPoints = new();
var continuationPoints = PrepareBrowseNext(result.Results);
for (int ii = 0; ii < nodesToBrowse.Count; ii++)
{
// check if all references have been fetched.
if (results[ii].References.Count == 0)
{
continue;
}
// check for error.
if (StatusCode.IsBad(results[ii].StatusCode))
{
@@ -198,31 +226,20 @@ public class FormUtils
continue;
}
// check if all references have been fetched.
if (results[ii].References.Count == 0)
{
continue;
}
// save results.
references.AddRange(results[ii].References);
// check for continuation point.
if (results[ii].ContinuationPoint != null)
{
continuationPoints.Add(results[ii].ContinuationPoint);
}
}
// process continuation points.
ByteStringCollection revisedContiuationPoints = new();
while (continuationPoints.Count > 0)
while (continuationPoints.Any())
{
// continue browse operation.
var nextResult = await session.BrowseNextAsync(
null,
true,
false,
continuationPoints
, token);
results = nextResult.Results;
@@ -232,6 +249,11 @@ public class FormUtils
for (int ii = 0; ii < continuationPoints.Count; ii++)
{
// check if all references have been fetched.
if (results[ii].References.Count == 0)
{
continue;
}
// check for error.
if (StatusCode.IsBad(results[ii].StatusCode))
@@ -239,24 +261,16 @@ public class FormUtils
continue;
}
// check if all references have been fetched.
if (results[ii].References.Count == 0)
{
continue;
}
// save results.
references.AddRange(results[ii].References);
// check for continuation point.
if (results[ii].ContinuationPoint != null)
{
revisedContiuationPoints.Add(results[ii].ContinuationPoint);
}
}
// check if browsing must continue;
revisedContiuationPoints = continuationPoints;
continuationPoints = PrepareBrowseNext(nextResult.Results);
}
// check if unprocessed results exist.

View File

@@ -38,6 +38,14 @@
The references found. Null if an error occurred.
</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.PrepareBrowseNext(Opc.Ua.BrowseResultCollection)">
<summary>
Create the continuation point collection from the browse result
collection for the BrowseNext service.
</summary>
<param name="browseResultCollection">The browse result collection to use.</param>
<returns>The collection of continuation points for the BrowseNext service.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean,System.Threading.CancellationToken)">
<summary>
浏览地址空间

View File

@@ -94,7 +94,7 @@ public class DLT645_2007 : CollectBase
Parity = driverPropertys.Parity,
StopBits = driverPropertys.StopBits,
})
.SetBufferLength(1024);
;
client = new SerialsSession();
((SerialsSession)client).Setup(FoundataionConfig);
}

View File

@@ -81,7 +81,7 @@ public class DLT645_2007OverTcp : CollectBase
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -87,7 +87,7 @@ public class ModbusRtu : CollectBase
Parity = driverPropertys.Parity,
StopBits = driverPropertys.StopBits,
})
.SetBufferLength(1024);
;
client = new SerialsSession();
((SerialsSession)client).Setup(FoundataionConfig);
}

View File

@@ -75,7 +75,7 @@ public class ModbusRtuOverTcp : CollectBase
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -80,7 +80,7 @@ public class ModbusRtuOverUdp : CollectBase
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBindIPHost(new IPHost(0))
.SetBufferLength(1024);
;
client = new UdpSession();
((UdpSession)client).Setup(FoundataionConfig);

View File

@@ -122,7 +122,7 @@ public class ModbusServer : UpLoadBase
{
iPHost = new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}");
}
FoundataionConfig.SetListenIPHosts(new IPHost[] { iPHost }).SetBufferLength(1024);
FoundataionConfig.SetListenIPHosts(new IPHost[] { iPHost });
var service = new TcpService();
service.Setup(FoundataionConfig);
//载入配置

View File

@@ -81,7 +81,7 @@ public class ModbusTcp : CollectBase
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -81,7 +81,7 @@ public class ModbusUdp : CollectBase
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBindIPHost(new IPHost(0))
.SetBufferLength(1024);
;
client = new UdpSession();
((UdpSession)client).Setup(FoundataionConfig);
}

View File

@@ -236,14 +236,9 @@ public partial class ImportVariable
if (data != null && data.Count > 0)
{
if (isAll)
{
child.Nodes = new();
}
else
{
child.Nodes = await PopulateBranchAsync((NodeId)target.NodeId);
}
child.Nodes = await PopulateBranchAsync((NodeId)target.NodeId);
else
child.Nodes = new();
}
else
{

View File

@@ -33,7 +33,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -32,7 +32,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -32,7 +32,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -32,7 +32,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -32,7 +32,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}

View File

@@ -32,7 +32,7 @@ namespace ThingsGateway.Siemens
if (client == null)
{
FoundataionConfig.SetRemoteIPHost(new IPHost($"{driverPropertys.IP}:{driverPropertys.Port}"))
.SetBufferLength(1024);
;
client = new TcpClientEx();
((TcpClientEx)client).Setup(FoundataionConfig);
}