Compare commits

..

32 Commits

Author SHA1 Message Date
Kimdiego2098
a6b874d160 2.1.0.6 2023-08-30 17:19:18 +08:00
Kimdiego2098
3e5fb3ddcf add windows service create/delete bat 2023-08-30 17:18:35 +08:00
Kimdiego2098
5e6bcb12d3 update statusPage; 2023-08-30 14:12:50 +08:00
Kimdiego2098
14303f1429 默认检测重连频率为10分钟 2023-08-29 17:56:59 +08:00
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
Kimdiego2098
6a70ef9f31 2.1.0.1 2023-08-27 16:31:03 +08:00
Kimdiego2098
82cc4ca500 dlt645添加数据标识校验 2023-08-27 16:30:32 +08:00
Kimdiego2098
4567fa04ed 更新dlt645,添加地址/控制码的校验规则 2023-08-27 16:15:51 +08:00
Kimdiego2098
8b98b5d818 更新touchsocket 2023-08-27 15:59:57 +08:00
Kimdiego2098
176d0351af 更新 Opc.Ua Version="1.4.372.56" 2023-08-27 14:33:24 +08:00
Kimdiego2098
d63dc3384b opcda/ua浏览地址空间 初始只加载首层节点 2023-08-27 14:14:47 +08:00
Kimdiego2098
1ccd704e30 opcuaclient浏览地址空间 初始只加载首层节点 2023-08-27 13:06:03 +08:00
Diego2098
f5d23dbe79 update MqttNetLogger 2023-08-26 21:38:14 +08:00
Diego2098
75bfe53ac3 update MqttNetLogger 2023-08-26 20:40:23 +08:00
Diego2098
3308f916dd 添加在线/离线方法参数 2023-08-26 17:18:47 +08:00
Diego2098
e7140279ca 更新opcuaclient 2023-08-26 15:38:22 +08:00
Diego2098
1034719f5e 更新opcuaclient,添加checkDomain属性,去除多余代码,更新SelectEndpoint方法 2023-08-26 15:33:03 +08:00
Kimdiego2098
2c00043a7f 更新文档 2023-08-25 19:49:02 +08:00
171 changed files with 2005 additions and 1354 deletions

View File

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

View File

@@ -18,6 +18,7 @@ using System.Reflection;
using System.Text;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using UAParser;

View File

@@ -20,6 +20,7 @@ using System.Globalization;
using System.Reflection;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using Yitter.IdGenerator;

View File

@@ -13,6 +13,8 @@
using System.Text;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -16,6 +16,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

View File

@@ -17,6 +17,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
using Yitter.IdGenerator;

View File

@@ -19,6 +19,7 @@ using Mapster;
using SqlSugar;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

View File

@@ -17,6 +17,7 @@ using Furion.FriendlyException;
using Mapster;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Application;

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

@@ -17,6 +17,7 @@ using Masa.Blazor;
using Microsoft.AspNetCore.Components;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor.Core;
/// <summary>

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

@@ -20,6 +20,7 @@ using Microsoft.AspNetCore.Http;
using ThingsGateway.Admin.Application;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor.Core;

View File

@@ -21,6 +21,7 @@ using Microsoft.Extensions.Hosting;
using ThingsGateway.Admin.Application;
using ThingsGateway.Admin.Blazor.Core;
using ThingsGateway.Admin.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Blazor;

View File

@@ -12,7 +12,7 @@
using Furion.DependencyInjection;
namespace ThingsGateway.Admin.Core;
namespace ThingsGateway.Admin.Core.JsonExtensions;
/// <summary>
/// 对象拓展

View File

@@ -18,6 +18,8 @@ using System.Collections;
using System.Data;
using System.Reflection;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Admin.Core;
/// <summary>

View File

@@ -332,20 +332,51 @@ public static class ObjectExtensions
/// <returns></returns>
public static bool ToBoolean(this object value, bool defaultValue = false) => value?.ToString().ToUpper() switch
{
"0" or "FALSE" => false,
"1" or "TRUE" => true,
_ => defaultValue,
};
/// <summary>
/// ToLong
/// </summary>
/// <returns></returns>
public static long ToLong(this object value, long defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
public static long ToLong(this object value, long defaultValue = 0)
{
if (value == null || value.ToString().IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return Int64.TryParse(value.ToString(), out var n) ? n : defaultValue;
}
}
/// <summary>
/// ToInt
/// </summary>
/// <returns></returns>
public static int ToInt(this object value, int defaultValue = 0) => value == null || value.ToString().IsNullOrEmpty() ? defaultValue : Int32.TryParse(value.ToString(), out var n) ? n : defaultValue;
public static int ToInt(this object value, int defaultValue = 0)
{
if (value == null || value.ToString().IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return int.TryParse(value.ToString(), out int n) ? n : defaultValue;
}
}
/// <summary>
/// ToDecimal
/// </summary>
@@ -357,7 +388,18 @@ public static class ObjectExtensions
return Double.IsNaN(d) ? defaultValue : (Decimal)d;
}
var str = value?.ToString();
return str.IsNullOrEmpty() ? defaultValue : Decimal.TryParse(str, out var n) ? n : defaultValue;
if (str.IsNullOrEmpty())
{
return defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return Decimal.TryParse(str, out var n) ? n : defaultValue;
}
}
/// <summary>
/// ToDecimal
@@ -370,7 +412,18 @@ public static class ObjectExtensions
return Double.IsNaN(d) ? defaultValue : (Double)d;
}
var str = value?.ToString();
return str.IsNullOrEmpty() ? defaultValue : double.TryParse(str, out var n) ? n : defaultValue;
if (str.IsNullOrEmpty())
{
return (double)defaultValue;
}
else
{
if (value is bool boolValue)
{
return boolValue ? 1 : 0;
}
return (double)(double.TryParse(str, out var n) ? n : defaultValue);
}
}
/// <summary>

View File

@@ -850,19 +850,19 @@
<param name="this"></param>
<param name="values"></param>
</member>
<member name="T:ThingsGateway.Admin.Core.JsonExtensions">
<member name="T:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions">
<summary>
对象拓展
</summary>
</member>
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonString(System.Object)">
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonString(System.Object)">
<summary>
转换为Json
</summary>
<param name="item"></param>
<returns></returns>
</member>
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.ToJsonWithT``1(System.String)">
<member name="M:ThingsGateway.Admin.Core.JsonExtensions.JsonExtensions.ToJsonWithT``1(System.String)">
<summary>
从字符串到json
</summary>

View File

@@ -80,7 +80,7 @@ public class StringToEncodingConverter : IConverter<string>
{
try
{
source = target.ToJson();
source = target.ToJsonString();
return true;
}
catch (Exception)

View File

@@ -21,7 +21,7 @@ using Newtonsoft.Json.Converters;
using System.Dynamic;
using System.Text;
using TouchSocket.Core;
using ThingsGateway.Admin.Core.JsonExtensions;
namespace ThingsGateway.Application;
/// <summary>
@@ -76,7 +76,7 @@ public class CSharpScriptEngine : ISingleton
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<List<ExpandoObject>>(input, expConverter);
object result = runscript(obj);
var json = result.ToJson();
var json = result.ToJsonString();
return json;
}
@@ -116,7 +116,7 @@ public class CSharpScriptEngine : ISingleton
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(input, expConverter);
object result = runscript(obj);
var json = result.ToJson();
var json = result.ToJsonString();
return json;
}
@@ -136,7 +136,7 @@ public static class CSharpScriptEngineExtension
/// </summary>
public static string GetSciptListValue<T>(this T datas, string script) where T : class
{
var inPut = datas.ToJson();
var inPut = datas.ToJsonString();
if (!string.IsNullOrEmpty(script))
{
//执行脚本,获取新实体
@@ -154,7 +154,7 @@ public static class CSharpScriptEngineExtension
/// </summary>
public static string GetSciptValue<T>(this T datas, string script) where T : class
{
var inPut = datas.ToJson();
var inPut = datas.ToJsonString();
if (!string.IsNullOrEmpty(script))
{
//执行脚本,获取新实体

View File

@@ -82,18 +82,15 @@ public class DeviceVariableRunTime : DeviceVariable
/// </summary>
/// <param name="value"></param>
/// <param name="dateTime"></param>
public OperResult SetValue(object value, DateTime dateTime = default)
/// <param name="isOnline"></param>
public OperResult SetValue(object value, DateTime dateTime = default,bool isOnline=true)
{
try
{
IsOnline = isOnline;
if (value != null)
if (!IsOnline)
{
IsOnline = true;
}
else
{
IsOnline = false;
RawValue = value;
Set(value);
return OperResult.CreateSuccessResult();

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
#endregion
using Furion;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
@@ -102,9 +104,9 @@ public abstract class CollectBase : DriverBase
StopBits = config.StopBits,
};
FoundataionConfig.SetValue(SerialConfigExtension.SerialProperty, data);
var serialClient = new SerialClient();
(serialClient).Setup(FoundataionConfig);
return OperResult.CreateSuccessResult((object)serialClient);
var serialSession = new SerialsSession();
(serialSession).Setup(FoundataionConfig);
return OperResult.CreateSuccessResult((object)serialSession);
case ShareChannelEnum.TcpClientEx:
FoundataionConfig.SetRemoteIPHost(new IPHost($"{config.IP}:{config.Port}"));
var tcpClient = new TcpClientEx();
@@ -157,7 +159,7 @@ public abstract class CollectBase : DriverBase
{
deviceVariableSourceRead.DeviceVariables.ForEach(it =>
{
var operResult = it.SetValue(null);
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

@@ -19,6 +19,7 @@ using Newtonsoft.Json.Linq;
using System.Collections.Concurrent;
using ThingsGateway.Admin.Core.JsonExtensions;
using ThingsGateway.Foundation;
using ThingsGateway.Foundation.Extension.ConcurrentQueue;

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

@@ -1601,12 +1601,13 @@
最近一次值
</summary>
</member>
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime)">
<member name="M:ThingsGateway.Application.DeviceVariableRunTime.SetValue(System.Object,System.DateTime,System.Boolean)">
<summary>
设置变量值与时间设置为null时只更改质量戳状态
</summary>
<param name="value"></param>
<param name="dateTime"></param>
<param name="isOnline"></param>
</member>
<member name="P:ThingsGateway.Application.DeviceVariableRunTime.ChangeTime">
<summary>
@@ -1977,6 +1978,11 @@
是否输出日志
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.IsSaveLog">
<summary>
是否存储报文
</summary>
</member>
<member name="P:ThingsGateway.Application.DriverBase.Messages">
<summary>
报文信息
@@ -1993,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>
设备报文
@@ -2582,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>
日志源
@@ -2612,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

@@ -595,7 +595,7 @@ public class AlarmWorker : BackgroundService
var cacheData = await CacheDb.GetCacheData();
if (cacheData.Count > 0)
{
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryAlarm>>()).ToList();
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryAlarm>>()).ToList();
try
{
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
@@ -633,7 +633,7 @@ public class AlarmWorker : BackgroundService
var cacheDatas = list.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}

View File

@@ -393,7 +393,7 @@ public class CollectDeviceCore
var read = await InvokeMethodAsync(deviceVariableMethodRead, token);
if (read.IsSuccess)
{
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJson());
_logger?.LogTrace(_device.Name + "执行方法[" + deviceVariableMethodRead.MethodInfo.Name + "] 成功" + read.Content.ToJsonString());
deviceMethodsVariableSuccessNum += 1;
}
else
@@ -677,9 +677,9 @@ public class CollectDeviceCore
}
else
{
if (isRead)
if (isRead&& !result.IsSuccess)
{
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null);
var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null,isOnline: false);
if (!operResult.IsSuccess)
{
_logger?.LogWarning(operResult.Message, ToString());

View File

@@ -95,10 +95,13 @@ public class CollectDeviceWorker : BackgroundService
await RemoveAllDeviceThreadAsync();
//创建全部采集线程
await CreatAllDeviceThreadsAsync();
//开始全部采集线程
await StartAllDeviceThreadsAsync();
//开始其他后台服务
await StartOtherHostService();
//开始全部采集线程
await StartAllDeviceThreadsAsync();
}
catch (Exception ex)
{

View File

@@ -224,7 +224,7 @@ public class HistoryValueWorker : BackgroundService
//缓存值
var cacheData = await CacheDb.GetCacheData();
var data = cacheData.SelectMany(a => a.CacheStr.FromJson<List<HistoryValue>>()).ToList();
var data = cacheData.SelectMany(a => a.CacheStr.FromJsonString<List<HistoryValue>>()).ToList();
try
{
var count = await sqlSugarClient.Insertable(data).ExecuteCommandAsync(stoppingToken.Token);
@@ -257,7 +257,7 @@ public class HistoryValueWorker : BackgroundService
var cacheDatas = collecthis.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}
}
@@ -284,7 +284,7 @@ public class HistoryValueWorker : BackgroundService
var cacheDatas = changehis.ChunkTrivialBetter(500);
foreach (var a in cacheDatas)
{
await CacheDb.AddCacheData("", a.ToJson(), 50000);
await CacheDb.AddCacheData("", a.ToJsonString(), 50000);
}
}
}

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

@@ -33,7 +33,7 @@
<TcpClientPage @ref=TcpClientPage></TcpClientPage>
break;
case ChannelEnum.SerialPort:
<SerialClientPage @ref=SerialClientPage></SerialClientPage>
<SerialSessionPage @ref=SerialSessionPage></SerialSessionPage>
break;
case ChannelEnum.UdpSession:
<UdpSessionPage @ref=UdpSessionPage></UdpSessionPage>

View File

@@ -38,9 +38,9 @@ public enum ChannelEnum
public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
/// <summary>
/// SerialClientPage
/// SerialSessionPage
/// </summary>
public SerialClientPage SerialClientPage;
public SerialSessionPage SerialSessionPage;
/// <summary>
/// TcpClientPage
/// </summary>
@@ -79,7 +79,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
Plc?.SafeDispose();
TcpClientPage?.SafeDispose();
SerialClientPage?.SafeDispose();
SerialSessionPage?.SafeDispose();
TcpServerPage?.SafeDispose();
UdpSessionPage?.SafeDispose();
base.Dispose();
@@ -94,8 +94,8 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase
{
if (TcpClientPage != null)
TcpClientPage.LogAction = LogOut;
if (SerialClientPage != null)
SerialClientPage.LogAction = LogOut;
if (SerialSessionPage != null)
SerialSessionPage.LogAction = LogOut;
if (TcpServerPage != null)
TcpServerPage.LogAction = LogOut;
if (UdpSessionPage != null)

View File

@@ -17,7 +17,7 @@ using TouchSocket.Core;
namespace ThingsGateway.Blazor;
/// <inheritdoc/>
public partial class SerialClientPage
public partial class SerialSessionPage
{
/// <summary>
/// 日志输出
@@ -28,18 +28,18 @@ public partial class SerialClientPage
private readonly SerialProperty serialProperty = new();
private SerialClient SerialClient { get; set; } = new();
private SerialsSession SerialsSession { get; set; } = new();
/// <inheritdoc/>
public void Dispose()
{
SerialClient.SafeDispose();
SerialsSession.SafeDispose();
}
/// <summary>
/// 获取对象
/// </summary>
/// <returns></returns>
public SerialClient GetSerialClient()
public SerialsSession GetSerialSession()
{
config?.Dispose();
config = new TouchSocketConfig();
@@ -48,15 +48,15 @@ public partial class SerialClientPage
config.ConfigureContainer(a => a.RegisterSingleton<ILog>(LogMessage));
config.SetSerialProperty(serialProperty);
//载入配置
SerialClient.Setup(config);
return SerialClient;
SerialsSession.Setup(config);
return SerialsSession;
}
private async Task ConnectAsync()
{
try
{
SerialClient.Close();
await GetSerialClient().ConnectAsync();
SerialsSession.Close();
await GetSerialSession().ConnectAsync();
}
catch (Exception ex)
{
@@ -68,7 +68,7 @@ public partial class SerialClientPage
{
try
{
SerialClient.Close();
SerialsSession.Close();
}
catch (Exception ex)
{
@@ -82,8 +82,8 @@ public partial class SerialClientPage
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));
SerialClient = new SerialClient();
SerialClient.Setup(config);
SerialsSession = new SerialsSession();
SerialsSession.Setup(config);
base.OnInitialized();
}

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
@@ -407,6 +424,10 @@
<span>@(item.Device?.KeepRun == true ? "暂停" : "运行")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicerestart")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small Loading=isRestart OnClick=@(()=> UpRestartAsync(item.DeviceId))>
@@ -495,7 +516,22 @@
<span>@((!pauseMessage) ? "暂停日志" : "运行日志")</span>
</ChildContent>
</MTooltip>
<MTooltip Bottom Context="tip">
<ActivatorContent>
<MButton Disabled=@(!UserResoures.IsHasButtonWithRole("gatewaydevicepause")) Class="mx-2" @attributes="@tip.Attrs" Dark Fab Small
OnClick=@(()=>
{
if(uploadDeviceInfoItem.Driver!=null)
uploadDeviceInfoItem.Driver.IsSaveLog=! uploadDeviceInfoItem.Driver.IsSaveLog;
}
)>
<MIcon>@((uploadDeviceInfoItem.Driver?.IsSaveLog == true) ? "mdi-pause" : "mdi-play")</MIcon>
</MButton>
</ActivatorContent>
<ChildContent>
<span>@((uploadDeviceInfoItem.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

@@ -67,9 +67,9 @@
<member name="T:ThingsGateway.Blazor.DefalutDebugDriverPage">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.SerialClientPage">
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.SerialSessionPage">
<summary>
SerialClientPage
SerialSessionPage
</summary>
</member>
<member name="F:ThingsGateway.Blazor.DefalutDebugDriverPage.TcpClientPage">
@@ -116,24 +116,24 @@
</summary>
<param name="firstRender"></param>
</member>
<member name="T:ThingsGateway.Blazor.SerialClientPage">
<member name="T:ThingsGateway.Blazor.SerialSessionPage">
<inheritdoc/>
</member>
<member name="F:ThingsGateway.Blazor.SerialClientPage.LogAction">
<member name="F:ThingsGateway.Blazor.SerialSessionPage.LogAction">
<summary>
日志输出
</summary>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.Dispose">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.Dispose">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.GetSerialClient">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.GetSerialSession">
<summary>
获取对象
</summary>
<returns></returns>
</member>
<member name="M:ThingsGateway.Blazor.SerialClientPage.OnInitialized">
<member name="M:ThingsGateway.Blazor.SerialSessionPage.OnInitialized">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Blazor.TcpClientPage">

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

@@ -22,47 +22,47 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
/// <summary>
/// WaitingClientEx
/// </summary>
public virtual IWaitingClient<SerialClient> WaitingClientEx { get; }
public virtual IWaitingClient<SerialsSession> WaitingClientEx { get; }
/// <summary>
/// <inheritdoc cref="ReadWriteDevicesSerialBase"/>
/// </summary>
/// <param name="serialClient"></param>
public ReadWriteDevicesSerialBase(SerialClient serialClient)
/// <param name="serialSession"></param>
public ReadWriteDevicesSerialBase(SerialsSession serialSession)
{
SerialClient = serialClient;
WaitingClientEx = SerialClient.GetWaitingClientEx(new() { BreakTrigger = true });
SerialsSession = serialSession;
WaitingClientEx = SerialsSession.GetWaitingClientEx(new() { BreakTrigger = true });
SerialClient.Connecting -= Connecting;
SerialClient.Connected -= Connected;
SerialClient.Disconnecting -= Disconnecting;
SerialClient.Disconnected -= Disconnected;
SerialClient.Connecting += Connecting;
SerialClient.Connected += Connected;
SerialClient.Disconnecting += Disconnecting;
SerialClient.Disconnected += Disconnected;
Logger = SerialClient.Logger;
SerialsSession.Connecting -= Connecting;
SerialsSession.Connected -= Connected;
SerialsSession.Disconnecting -= Disconnecting;
SerialsSession.Disconnected -= Disconnected;
SerialsSession.Connecting += Connecting;
SerialsSession.Connected += Connected;
SerialsSession.Disconnecting += Disconnecting;
SerialsSession.Disconnected += Disconnected;
Logger = SerialsSession.Logger;
}
/// <summary>
/// 串口管理对象
/// </summary>
public SerialClient SerialClient { get; }
public SerialsSession SerialsSession { get; }
/// <inheritdoc/>
public override void Connect(CancellationToken token)
{
SerialClient.Connect();
SerialsSession.Connect();
}
/// <inheritdoc/>
public override Task ConnectAsync(CancellationToken token)
{
return SerialClient.ConnectAsync();
return SerialsSession.ConnectAsync();
}
/// <inheritdoc/>
public override void Disconnect()
{
SerialClient.Close();
SerialsSession.Close();
}
/// <inheritdoc/>
@@ -71,7 +71,7 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = SerialClient.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, token);
ResponsedData result = SerialsSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, token);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -86,7 +86,7 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
try
{
waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll };
ResponsedData result = await SerialClient.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, token);
ResponsedData result = await SerialsSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, token);
return OperResult.CreateSuccessResult(result.Data);
}
catch (Exception ex)
@@ -98,37 +98,37 @@ public abstract class ReadWriteDevicesSerialBase : ReadWriteDevicesClientBase
/// <inheritdoc/>
public override string ToString()
{
return SerialClient.SerialProperty.ToString();
return SerialsSession.SerialProperty.ToString();
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
SerialClient.Connecting -= Connecting;
SerialClient.Connected -= Connected;
SerialClient.Disconnecting -= Disconnecting;
SerialClient.Disconnected -= Disconnected;
SerialClient.Close();
SerialClient.SafeDispose();
SerialsSession.Connecting -= Connecting;
SerialsSession.Connected -= Connected;
SerialsSession.Disconnecting -= Disconnecting;
SerialsSession.Disconnected -= Disconnected;
SerialsSession.Close();
SerialsSession.SafeDispose();
base.Dispose(disposing);
}
private void Connected(ISerialClient client, ConnectedEventArgs e)
private void Connected(ISerialSession client, ConnectedEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "连接成功");
}
private void Connecting(ISerialClient client, SerialConnectingEventArgs e)
private void Connecting(ISerialSession client, SerialConnectingEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在连接");
SetDataAdapter();
}
private void Disconnected(ISerialClientBase client, DisconnectEventArgs e)
private void Disconnected(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message);
}
private void Disconnecting(ISerialClientBase client, DisconnectEventArgs e)
private void Disconnecting(ISerialSessionBase client, DisconnectEventArgs e)
{
Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message);
}

View File

@@ -26,8 +26,6 @@ using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using ThingsGateway.Foundation;
using TouchSocket.Resources;
namespace ThingsGateway.Foundation;
@@ -65,18 +63,26 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
/// </summary>
public TcpClientBaseEx()
{
this.Protocol = Protocol.TCP;
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 bool m_useDelaySender;
private Stream m_workStream;
private int m_bufferRate = 1;
private long m_bufferRate = 1;
private volatile bool m_online;
private Socket m_mainSocket;
ValueCounter m_receiveCounter;
ValueCounter m_sendCounter;
#endregion
#region
@@ -121,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());
@@ -212,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; }
@@ -233,13 +237,13 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public TcpDataHandlingAdapter DataHandlingAdapter { get; private set; }
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <inheritdoc/>
public string IP { get; private set; }
/// <inheritdoc/>
public Socket MainSocket { get => this.m_mainSocket; }
public Socket MainSocket { get; private set; }
/// <inheritdoc/>
public bool Online { get => this.m_online; }
@@ -269,7 +273,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
public bool IsClient => true;
#endregion
private EasyLock EasyLock { get; set; } = new();
#region
/// <inheritdoc/>
@@ -277,7 +281,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
this.PrivateOnDisconnecting(new DisconnectEventArgs(true, msg));
@@ -294,7 +298,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
@@ -302,7 +306,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
this.m_online = false;
@@ -315,7 +319,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
@@ -330,7 +334,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
this.m_online = false;
@@ -347,10 +351,10 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
privateEasyLock.SafeDispose();
EasyLock.SafeDispose();
base.Dispose(disposing);
}
@@ -358,7 +362,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
#endregion
#region Connect
private EasyLock privateEasyLock { get; set; } = new();
/// <summary>
/// 建立Tcp的连接。
/// </summary>
@@ -371,7 +374,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
try
{
privateEasyLock.Wait();
EasyLock.Wait();
if (this.m_online)
{
return;
@@ -382,13 +385,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
if (this.Config == null)
{
throw new ArgumentNullException("配置文件不能为空。");
throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。");
}
var iPHost = this.Config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty) ?? throw new ArgumentNullException("iPHost不能为空。");
var iPHost = this.Config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty) ?? throw new ArgumentNullException(nameof(IPHost), "iPHost不能为空。");
this.MainSocket.SafeDispose();
var socket = this.CreateSocket(iPHost);
var args = new ConnectingEventArgs(this.MainSocket);
this.PrivateOnConnecting(args);
this.PrivateOnConnecting(new ConnectingEventArgs(socket));
if (timeout == 5000)
{
socket.Connect(iPHost.Host, iPHost.Port);
@@ -406,15 +408,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
throw new TimeoutException();
}
}
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
this.m_useDelaySender = true;
this.m_delaySender.SafeDispose();
this.m_delaySender = new DelaySender(this.MainSocket, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.m_online = true;
this.SetSocket(socket);
this.BeginReceive();
@@ -422,24 +415,24 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
}
/// <summary>
/// 建立Tcp的连接。
/// </summary>
/// <param name="timeOut"></param>
/// <param name="timeout"></param>
/// <param name="token"></param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
/// <exception cref="TimeoutException"></exception>
public async Task TcpConnectAsync(int timeOut, CancellationToken token = default)
public async Task TcpConnectAsync(int timeout, CancellationToken token = default)
{
try
{
await privateEasyLock.WaitAsync();
await EasyLock.WaitAsync();
if (this.m_online)
{
return;
@@ -459,7 +452,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.PrivateOnConnecting(args);
#if (NET6_0_OR_GREATER)
using CancellationTokenSource cancellationTokenSource = new(timeOut);
using CancellationTokenSource cancellationTokenSource = new(timeout);
using CancellationTokenSource stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, token);
try
{
@@ -477,7 +470,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
using CancellationTokenSource cancellationTokenSource = new();
using CancellationTokenSource stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationTokenSource.Token, token);
var task = Task.Factory.FromAsync(socket.BeginConnect(iPHost.EndPoint, null, null), socket.EndConnect);
var result = await Task.WhenAny(task, Task.Delay(timeOut, stoppingToken.Token));
var result = await Task.WhenAny(task, Task.Delay(timeout, stoppingToken.Token));
if (result == task)
{
cancellationTokenSource.Cancel();
@@ -502,20 +495,11 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
finally
{
privateEasyLock.Release();
EasyLock.Release();
}
void success(Socket socket)
{
if (this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
this.m_useDelaySender = true;
this.m_delaySender.SafeDispose();
this.m_delaySender = new DelaySender(this.MainSocket, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.m_online = true;
this.SetSocket(socket);
this.BeginReceive();
@@ -523,20 +507,19 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
}
/// <inheritdoc/>
public virtual ITcpClient Connect(int timeout = 5000)
{
this.TcpConnect(timeout);
return this;
}
/// <inheritdoc/>
public virtual async Task<ITcpClient> ConnectAsync(int timeOut = 5000)
public async Task<ITcpClient> ConnectAsync(int timeout = 5000)
{
await TcpConnectAsync(timeOut);
await TcpConnectAsync(timeout);
return this;
}
#endregion
/// <inheritdoc/>
@@ -547,8 +530,46 @@ 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 virtual void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter)
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)
{
if (!this.CanSetDataHandlingAdapter)
{
@@ -682,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);
}
@@ -703,7 +720,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(TcpDataHandlingAdapter adapter)
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
@@ -749,12 +766,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
else
{
if (this.ReceiveType == ReceiveType.Auto)
if (this.ReceiveType == ReceiveType.Iocp)
{
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))
@@ -762,12 +779,45 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.ProcessReceived(eventArgs);
}
}
else if (this.ReceiveType == ReceiveType.Bio)
{
new Thread(BeginBio)
{
IsBackground = true
}
.Start();
}
}
}
private void BeginBio()
{
while (true)
{
var byteBlock = new ByteBlock(this.ReceiveBufferSize);
try
{
var r = this.MainSocket.Receive(byteBlock.Buffer);
if (r == 0)
{
this.BreakOut("远程终端主动关闭");
return;
}
byteBlock.SetLength(r);
this.HandleBuffer(byteBlock);
}
catch (Exception ex)
{
this.BreakOut(ex.Message);
return;
}
}
}
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);
@@ -802,32 +852,42 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
private Socket CreateSocket(IPHost iPHost)
{
var socket = new Socket(iPHost.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
Socket socket;
if (iPHost.HostNameType == UriHostNameType.Dns)
{
ReceiveBufferSize = this.BufferLength,
SendBufferSize = this.BufferLength,
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
#if NET45_OR_GREATER
var keepAliveValue = this.Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty);
if (keepAliveValue.Enable)
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
{
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
else
{
var keepAliveValue = Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty);
if (keepAliveValue.Enable)
socket = new Socket(iPHost.EndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
{
SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty)
};
}
if (this.Config.GetValue(TouchSocketConfigExtension.KeepAliveValueProperty) is KeepAliveValue keepAliveValue)
{
#if NET45_OR_GREATER
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
#else
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
socket.IOControl(IOControlCode.KeepAliveValues, keepAliveValue.KeepAliveTime, null);
}
}
#endif
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, this.Config.GetValue<bool>(TouchSocketConfigExtension.NoDelayProperty));
}
var noDelay = this.Config.GetValue(TouchSocketConfigExtension.NoDelayProperty);
if (noDelay != null)
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, noDelay);
}
if (this.Config.GetValue(TouchSocketConfigExtension.BindIPHostProperty) != null)
{
if (this.Config.GetValue(TouchSocketConfigExtension.ReuseAddressProperty))
@@ -860,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;
@@ -961,14 +1021,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
{
length += item.Count;
}
using (var byteBlock = new ByteBlock(length))
using var byteBlock = new ByteBlock(length);
foreach (var item in transferBytes)
{
foreach (var item in transferBytes)
{
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
byteBlock.Write(item.Array, item.Offset, item.Count);
}
this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len);
}
}
@@ -1048,17 +1106,16 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
}
else
{
if (this.m_useDelaySender && length < TouchSocketUtility.BigDataBoundary)
if (this.m_delaySender != null && length < m_delaySender.DelayLength)
{
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
this.m_delaySender.Send(QueueDataBytes.CreateNew(buffer, offset, length));
}
else
{
this.MainSocket.AbsoluteSend(buffer, offset, length);
}
}
this.LastSendTime = DateTime.Now;
this.m_sendCounter.Increment(length);
}
}
@@ -1092,7 +1149,12 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient
this.IP = socket.RemoteEndPoint.GetIP();
this.Port = socket.RemoteEndPoint.GetPort();
this.m_mainSocket = socket;
this.MainSocket = socket;
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new DelaySender(socket, delaySenderOption, this.OnDelaySenderError);
}
}
private void ProcessReceived(SocketAsyncEventArgs e)
@@ -1115,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

@@ -70,7 +70,7 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
this.m_breaked = true;
this.Cancel();
}
private void OnSerialClientDisconnected(ISerialClientBase client, DisconnectEventArgs e)
private void OnSerialSessionDisconnected(ISerialSessionBase client, DisconnectEventArgs e)
{
this.m_breaked = true;
this.Cancel();
@@ -129,9 +129,9 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
tcpClient.Disconnected += this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected += this.OnSerialClientDisconnected;
serialSession.Disconnected += this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -190,9 +190,9 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
tcpClient.Disconnected -= this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected -= this.OnSerialClientDisconnected;
serialSession.Disconnected -= this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -232,9 +232,9 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
tcpClient.Disconnected += this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected += this.OnSerialClientDisconnected;
serialSession.Disconnected += this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{
@@ -293,9 +293,9 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie
{
tcpClient.Disconnected -= this.OnDisconnected;
}
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialClientBase serialClient)
if (this.WaitingOptions.BreakTrigger && this.Client is ISerialSessionBase serialSession)
{
serialClient.Disconnected -= this.OnSerialClientDisconnected;
serialSession.Disconnected -= this.OnSerialSessionDisconnected;
}
if (this.WaitingOptions.AdapterFilter == AdapterFilter.AllAdapter || this.WaitingOptions.AdapterFilter == AdapterFilter.WaitAdapter)
{

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

@@ -82,7 +82,7 @@ public class ByteTransformUtil
/// </summary>
public static IThingsGatewayBitConverter GetTransByAddress(ref string address, IThingsGatewayBitConverter defaultTransform)
{
var hasCache = _cache.TryGetValue(address + defaultTransform.ToJson(), out IThingsGatewayBitConverter thingsGatewayBitConverter);
var hasCache = _cache.TryGetValue(address + defaultTransform.ToJsonString(), out IThingsGatewayBitConverter thingsGatewayBitConverter);
if (hasCache)
{
return thingsGatewayBitConverter;
@@ -187,7 +187,7 @@ public class ByteTransformUtil
{
converter.StringLength = length.Value;
}
_cache.SetCache(address + defaultTransform.ToJson(), converter);
_cache.SetCache(address + defaultTransform.ToJsonString(), converter);
return converter;
}

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

@@ -13,32 +13,31 @@
namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// <inheritdoc cref="ISerialClientBase"/>
/// <inheritdoc cref="ISerialSessionBase"/>
/// </summary>
public interface ISerialClient : ISerialClientBase, IClientSender, IPluginObject
public interface ISerialSession : ISerialSessionBase, IClientSender, IPluginObject
{
/// <summary>
/// 成功连接到服务器
/// 成功打开串口
/// </summary>
ConnectedEventHandler<ISerialClient> Connected { get; set; }
ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <summary>
/// 准备连接的时候
/// 准备连接串口的时候
/// </summary>
SerialConnectingEventHandler<ISerialClient> Connecting { get; set; }
SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <summary>
/// 连接串口
/// </summary>
/// <exception cref="TimeoutException"></exception>
/// <exception cref="Exception"></exception>
ISerialClient Connect(int timeout = 5000);
ISerialSession Connect();
/// <summary>
/// 配置服务器
/// </summary>
/// <param name="config"></param>
/// <exception cref="Exception"></exception>
ISerialClient Setup(TouchSocketConfig config);
ISerialSession Setup(TouchSocketConfig config);
}

View File

@@ -17,7 +17,7 @@ namespace ThingsGateway.Foundation.Serial;
/// <summary>
/// 串口连接接口。
/// </summary>
public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender
public interface ISerialSessionBase : IClient, ISender, IDefaultSender, IPluginObject, IRequsetInfoSender
{
/// <summary>
/// 是否允许自由调用<see cref="SetDataHandlingAdapter"/>进行赋值。
@@ -32,24 +32,19 @@ public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginOb
/// <summary>
/// 数据处理适配器
/// </summary>
TcpDataHandlingAdapter DataHandlingAdapter { get; }
SingleStreamDataHandlingAdapter DataHandlingAdapter { get; }
/// <summary>
/// 断开连接
/// </summary>
DisconnectEventHandler<ISerialClientBase> Disconnected { get; set; }
DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// <para>
/// </para>
/// </summary>
DisconnectEventHandler<ISerialClientBase> Disconnecting { get; set; }
/// <summary>
/// 表示是否为客户端。
/// </summary>
bool IsClient { get; }
DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
/// <summary>
/// 主通信器
@@ -77,5 +72,5 @@ public interface ISerialClientBase : IClient, ISender, IDefaultSender, IPluginOb
/// 设置数据处理适配器
/// </summary>
/// <param name="adapter"></param>
void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter);
void SetDataHandlingAdapter(SingleStreamDataHandlingAdapter adapter);
}

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

@@ -9,7 +9,18 @@
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO.Ports;
namespace ThingsGateway.Foundation.Serial;
@@ -28,18 +39,22 @@ public sealed class SerialDelaySender : DisposableObject
/// <summary>
/// 延迟发送器
/// </summary>
public SerialDelaySender(SerialPort serialPort, int queueLength, Action<Exception> onError)
/// <param name="serialPort"></param>
/// <param name="onError"></param>
/// <param name="delaySenderOption"></param>
public SerialDelaySender(SerialPort serialPort, DelaySenderOption delaySenderOption, Action<Exception> onError)
{
this.DelayLength = delaySenderOption.DelayLength;
this.m_serial = serialPort;
this.m_onError = onError;
this.m_queueDatas = new IntelligentDataQueue<QueueDataBytes>(queueLength);
this.m_queueDatas = new IntelligentDataQueue<QueueDataBytes>(delaySenderOption.QueueLength);
this.m_lockSlim = new ReaderWriterLockSlim();
}
/// <summary>
/// 延迟包最大尺寸默认1024*512字节
/// 延迟包最大尺寸。
/// </summary>
public int DelayLength { get; set; } = 1024 * 512;
public int DelayLength { get; private set; }
/// <summary>
/// 是否处于发送状态

View File

@@ -10,19 +10,31 @@
//------------------------------------------------------------------------------
#endregion
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在XREF结尾的命名空间的代码归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// API首页http://rrqm_home.gitee.io/touchsocket/
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.IO.Ports;
using TouchSocket.Resources;
namespace ThingsGateway.Foundation.Serial;
/// <inheritdoc cref="SerialClientBase"/>
public class SerialClient : SerialClientBase
/// <inheritdoc cref="SerialSessionBase"/>
public class SerialsSession : SerialSessionBase
{
/// <summary>
/// 接收到数据
/// </summary>
public ReceivedEventHandler<SerialClient> Received { get; set; }
public ReceivedEventHandler<SerialsSession> Received { get; set; }
/// <summary>
/// 接收数据
@@ -39,38 +51,61 @@ public class SerialClient : SerialClientBase
/// <summary>
/// 串口管理
/// </summary>
public class SerialClientBase : BaseSerial, ISerialClient
public class SerialSessionBase : BaseSerial, ISerialSession
{
static readonly Protocol SerialPort = new("SerialPort");
static readonly Protocol SerialPort = new("SerialSession");
/// <summary>
/// 构造函数
/// </summary>
public SerialClientBase()
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 int m_bufferRate = 1;
private SerialDelaySender m_delaySender;
private SerialPort m_mainSerialPort;
private long m_bufferRate = 1;
private volatile bool m_online;
private bool m_useDelaySender;
ValueCounter m_receiveCounter;
ValueCounter m_sendCounter;
#endregion
#region
/// <inheritdoc/>
public ConnectedEventHandler<ISerialClient> Connected { get; set; }
public ConnectedEventHandler<ISerialSession> Connected { get; set; }
/// <inheritdoc/>
public SerialConnectingEventHandler<ISerialClient> Connecting { get; set; }
public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialClientBase> Disconnected { get; set; }
public DisconnectEventHandler<ISerialSessionBase> Disconnected { get; set; }
/// <inheritdoc/>
public DisconnectEventHandler<ISerialClientBase> Disconnecting { get; set; }
public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; }
private void PrivateOnConnected(object o)
{
var e = (ConnectedEventArgs)o;
this.OnConnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
}
/// <summary>
/// 已经建立Tcp连接
@@ -88,6 +123,21 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnConnecting(SerialConnectingEventArgs e)
{
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
}
this.OnConnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
}
/// <summary>
/// 准备连接的时候此时已初始化Socket但是并未建立Tcp连接
/// </summary>
@@ -104,6 +154,16 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnDisconnected(DisconnectEventArgs e)
{
this.OnDisconnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
}
/// <summary>
/// 断开连接。在客户端未设置连接状态时,不会触发
/// </summary>
@@ -120,6 +180,16 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnDisconnecting(DisconnectEventArgs e)
{
this.OnDisconnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e);
}
/// <summary>
/// 即将断开连接(仅主动断开时有效)。
/// <para>
@@ -139,56 +209,24 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateOnConnected(object o)
{
var e = (ConnectedEventArgs)o;
this.OnConnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e);
}
private void PrivateOnConnecting(SerialConnectingEventArgs e)
{
this.LastReceivedTime = DateTime.Now;
this.LastSendTime = DateTime.Now;
if (this.CanSetDataHandlingAdapter)
{
this.SetDataHandlingAdapter(this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty).Invoke());
}
this.OnConnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e);
}
private void PrivateOnDisconnected(DisconnectEventArgs e)
{
this.OnDisconnected(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e);
}
private void PrivateOnDisconnecting(DisconnectEventArgs e)
{
this.OnDisconnecting(e);
if (e.Handled)
{
return;
}
this.PluginsManager.Raise(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e);
}
#endregion
#region
/// <inheritdoc/>
public bool CanSend => this.m_online;
public DateTime LastReceivedTime => this.m_receiveCounter.LastIncrement;
/// <inheritdoc/>
public DateTime LastSendTime => this.m_sendCounter.LastIncrement;
/// <inheritdoc/>
public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
/// <inheritdoc/>
public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; }
/// <inheritdoc/>
public IContainer Container { get; private set; }
/// <inheritdoc/>
public virtual bool CanSetDataHandlingAdapter => true;
@@ -197,39 +235,35 @@ public class SerialClientBase : BaseSerial, ISerialClient
public TouchSocketConfig Config { get; private set; }
/// <inheritdoc/>
public IContainer Container { get; private set; }
public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <inheritdoc/>
public TcpDataHandlingAdapter DataHandlingAdapter { get; private set; }
/// <summary>
/// <inheritdoc/>
public bool IsClient => true;
/// </summary>
public SerialProperty SerialProperty { get; private set; }
/// <inheritdoc/>
public SerialPort MainSerialPort { get; private set; }
/// <inheritdoc/>
public DateTime LastReceivedTime { get; private set; }
/// <inheritdoc/>
public DateTime LastSendTime { get; private set; }
/// <inheritdoc/>
public SerialPort MainSerialPort { get => this.m_mainSerialPort; }
/// <inheritdoc/>
public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
/// <inheritdoc/>
public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; }
/// <inheritdoc/>
/// <inheritdoc/>
public bool Online { get => this.m_online; }
/// <inheritdoc/>
public bool CanSend => this.m_online;
/// <inheritdoc/>
public IPluginsManager PluginsManager { get; private set; }
/// <inheritdoc/>
public ReceiveType ReceiveType { get; private set; }
/// <inheritdoc/>
public Protocol Protocol { get; set; }
/// <inheritdoc/>
public ReceiveType ReceiveType { get; private set; }
#endregion
#region
@@ -254,6 +288,21 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void BreakOut(string msg)
{
lock (this.SyncRoot)
{
if (this.m_online)
{
this.m_online = false;
this.MainSerialPort.SafeDispose();
this.m_delaySender.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(false, msg));
}
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
@@ -278,48 +327,13 @@ public class SerialClientBase : BaseSerial, ISerialClient
base.Dispose(disposing);
}
private void BreakOut(string msg)
{
lock (this.SyncRoot)
{
if (this.m_online)
{
this.m_online = false;
this.MainSerialPort.SafeDispose();
this.m_delaySender.SafeDispose();
this.DataHandlingAdapter.SafeDispose();
this.PrivateOnDisconnected(new DisconnectEventArgs(false, msg));
}
}
}
#endregion
#region Connect
/// <inheritdoc/>
public virtual ISerialClient Connect(int timeout = 5000)
{
this.TcpConnect(timeout);
return this;
}
/// <inheritdoc/>
public Task<ISerialClient> ConnectAsync(int timeout = 5000)
{
return Task.Run(() =>
{
return this.Connect(timeout);
});
}
/// <summary>
/// 建立Tcp的连接。
/// 打开串口
/// </summary>
/// <param name="timeout"></param>
/// <exception cref="ObjectDisposedException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
/// <exception cref="TimeoutException"></exception>
protected void TcpConnect(int timeout)
protected void Open()
{
lock (this.SyncRoot)
{
@@ -337,42 +351,78 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。");
this.m_mainSerialPort.SafeDispose();
m_mainSerialPort = this.CreateSerial(serialProperty);
this.MainSerialPort.SafeDispose();
var serialPort = this.CreateSerial(serialProperty);
var args = new SerialConnectingEventArgs(this.MainSerialPort);
this.PrivateOnConnecting(args);
m_mainSerialPort.Open();
serialPort.Open();
this.m_online = true;
this.SetSerialPort(m_mainSerialPort);
if (Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty) is DelaySenderOption senderOption)
{
m_useDelaySender = true;
m_delaySender.SafeDispose();
m_delaySender = new SerialDelaySender(MainSerialPort, senderOption.QueueLength, this.OnDelaySenderError)
{
DelayLength = senderOption.DelayLength
};
}
this.SetSerialPort(serialPort);
this.BeginReceive();
this.PrivateOnConnected(new ConnectedEventArgs());
}
}
/// <inheritdoc/>
public virtual ISerialSession Connect()
{
this.Open();
return this;
}
/// <inheritdoc/>
public Task<ISerialSession> ConnectAsync()
{
return Task.Run(() =>
{
return this.Connect();
});
}
#endregion
private void OnReceivePeriod(long value)
{
this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value);
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public SerialProperty SerialProperty { get; private set; }
private void OnSendPeriod(long value)
{
this.SendBufferSize = TouchSocketUtility.HitBufferLength(value);
}
/// <inheritdoc/>
public virtual void SetDataHandlingAdapter(TcpDataHandlingAdapter adapter)
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)
{
if (!this.CanSetDataHandlingAdapter)
{
@@ -383,7 +433,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
/// <inheritdoc/>
public ISerialClient Setup(TouchSocketConfig config)
public ISerialSession Setup(TouchSocketConfig config)
{
if (config == null)
{
@@ -401,99 +451,6 @@ public class SerialClientBase : BaseSerial, ISerialClient
return this;
}
/// <summary>
/// 处理已接收到的数据。
/// </summary>
/// <param name="byteBlock">以二进制流形式传递</param>
/// <param name="requestInfo">以解析的数据对象传递</param>
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
protected virtual bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
return false;
}
/// <summary>
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <returns>返回值表示是否允许发送</returns>
protected virtual bool HandleSendingData(byte[] buffer, int offset, int length)
{
if (this.PluginsManager.Enable)
{
var args = new SendingEventArgs(buffer, offset, length);
this.PluginsManager.Raise(nameof(ITcpSendingPlugin.OnTcpSending), this, args);
return args.IsPermitOperation;
}
return true;
}
/// <summary>
/// 加载配置
/// </summary>
/// <param name="config"></param>
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);
}
/// <summary>
/// 在延迟发生错误
/// </summary>
/// <param name="ex"></param>
protected virtual void OnDelaySenderError(Exception ex)
{
this.Logger.Log(LogLevel.Error, this, "发送错误", ex);
}
/// <summary>
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(TcpDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
{
throw new ArgumentNullException(nameof(adapter));
}
if (this.Config != null)
{
adapter.Config(this.Config);
}
adapter.Logger = this.Logger;
adapter.OnLoaded(this);
adapter.ReceivedCallBack = this.PrivateHandleReceivedData;
adapter.SendCallBack = this.DefaultSend;
this.DataHandlingAdapter = adapter;
}
private void BeginReceive()
{
if (this.ReceiveType == ReceiveType.Auto)
{
SerialReceivedEventArgs eventArgs = new();
var byteBlock = BytePool.Default.GetByteBlock(this.BufferLength);
byteBlock.SetLength(0);
eventArgs.UserToken = byteBlock;
if (this.MainSerialPort.BytesToRead > 0)
{
this.ProcessReceived(eventArgs);
}
MainSerialPort.DataReceived += this.EventArgs_Completed;
}
}
private void BuildConfig(TouchSocketConfig config)
{
this.Config = config;
@@ -536,6 +493,122 @@ public class SerialClientBase : BaseSerial, ISerialClient
this.PluginsManager = pluginsManager;
}
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false)
{
return;
}
if (this.HandleReceivedData(byteBlock, requestInfo))
{
return;
}
if (this.PluginsManager.Enable)
{
var args = new ReceivedDataEventArgs(byteBlock, requestInfo);
this.PluginsManager.Raise(nameof(ITcpReceivedPlugin.OnTcpReceived), this, args);
}
}
/// <summary>
/// 处理已接收到的数据。
/// </summary>
/// <param name="byteBlock">以二进制流形式传递</param>
/// <param name="requestInfo">以解析的数据对象传递</param>
/// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
protected virtual bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
return false;
}
/// <summary>
/// 当即将发送时,如果覆盖父类方法,则不会触发插件。
/// </summary>
/// <param name="buffer">数据缓存区</param>
/// <param name="offset">偏移</param>
/// <param name="length">长度</param>
/// <returns>返回值表示是否允许发送</returns>
protected virtual bool HandleSendingData(byte[] buffer, int offset, int length)
{
if (this.PluginsManager.Enable)
{
var args = new SendingEventArgs(buffer, offset, length);
this.PluginsManager.Raise(nameof(ITcpSendingPlugin.OnTcpSending), this, args);
return args.IsPermitOperation;
}
return true;
}
/// <summary>
/// 加载配置
/// </summary>
/// <param name="config"></param>
protected virtual void LoadConfig(TouchSocketConfig config)
{
this.SerialProperty = config.GetValue(SerialConfigExtension.SerialProperty);
this.Logger ??= this.Container.Resolve<ILog>();
this.ReceiveType = config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty);
}
/// <summary>
/// 在延迟发生错误
/// </summary>
/// <param name="ex"></param>
protected virtual void OnDelaySenderError(Exception ex)
{
this.Logger.Log(LogLevel.Error, this, "发送错误", ex);
}
/// <summary>
/// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
/// </summary>
/// <param name="adapter"></param>
protected void SetAdapter(SingleStreamDataHandlingAdapter adapter)
{
this.ThrowIfDisposed();
if (adapter is null)
{
throw new ArgumentNullException(nameof(adapter));
}
if (this.Config != null)
{
adapter.Config(this.Config);
}
adapter.Logger = this.Logger;
adapter.OnLoaded(this);
adapter.ReceivedCallBack = this.PrivateHandleReceivedData;
adapter.SendCallBack = this.DefaultSend;
this.DataHandlingAdapter = adapter;
}
private void BeginReceive()
{
if (this.ReceiveType == ReceiveType.Iocp)
{
SerialReceivedEventArgs eventArgs = new();
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
byteBlock.SetLength(0);
eventArgs.UserToken = byteBlock;
if (this.MainSerialPort.BytesToRead > 0)
{
this.ProcessReceived(eventArgs);
}
MainSerialPort.DataReceived += this.EventArgs_Completed;
}
else if (this.ReceiveType == ReceiveType.Bio)
{
new Thread(BeginBio)
{
IsBackground = true
}
.Start();
}
}
private SerialPort CreateSerial(SerialProperty serialProperty)
{
SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits)
@@ -552,7 +625,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
{
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)
@@ -565,7 +638,84 @@ public class SerialClientBase : BaseSerial, ISerialClient
this.BreakOut(ex.Message);
}
}
private void BeginBio()
{
while (true)
{
var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize);
try
{
int r = MainSerialPort.Read(byteBlock.Buffer, 0, MainSerialPort.BytesToRead);
if (r == 0)
{
this.BreakOut("远程终端主动关闭");
return;
}
byteBlock.SetLength(r);
this.HandleBuffer(byteBlock);
}
catch (Exception ex)
{
this.BreakOut(ex.Message);
return;
}
}
}
private void ProcessReceived(SerialReceivedEventArgs e)
{
if (!this.m_online)
{
e.UserToken.SafeDispose();
return;
}
if (MainSerialPort.BytesToRead > 0)
{
byte[] buffer = new byte[2048];
var byteBlock = (ByteBlock)e.UserToken;
int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead);
byteBlock.Write(buffer, 0, num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength));
newByteBlock.SetLength(num);
e.UserToken = newByteBlock;
if (MainSerialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived(e);
}
}
catch (Exception ex)
{
e.UserToken.SafeDispose();
this.BreakOut(ex.Message);
}
}
else
{
e.UserToken.SafeDispose();
this.BreakOut("远程终端主动关闭");
}
}
private void SetSerialPort(SerialPort serialPort)
{
if (serialPort == null)
{
return;
}
this.MainSerialPort = serialPort;
var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty);
if (delaySenderOption != null)
{
this.m_delaySender = new SerialDelaySender(MainSerialPort, delaySenderOption, this.OnDelaySenderError);
}
}
/// <summary>
/// 处理数据
/// </summary>
@@ -573,7 +723,7 @@ public class SerialClientBase : BaseSerial, ISerialClient
{
try
{
this.LastReceivedTime = DateTime.Now;
this.m_receiveCounter.Increment(byteBlock.Length);
if (this.OnHandleRawBuffer?.Invoke(byteBlock) == false)
{
return;
@@ -603,24 +753,6 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
}
private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo)
{
if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false)
{
return;
}
if (this.HandleReceivedData(byteBlock, requestInfo))
{
return;
}
if (this.PluginsManager.Enable)
{
var args = new ReceivedDataEventArgs(byteBlock, requestInfo);
this.PluginsManager.Raise(nameof(ITcpReceivedPlugin.OnTcpReceived), this, args);
}
}
#region
#region
@@ -771,16 +903,16 @@ public class SerialClientBase : BaseSerial, ISerialClient
}
if (this.HandleSendingData(buffer, offset, length))
{
if (this.m_useDelaySender && length < TouchSocketUtility.BigDataBoundary)
if (this.m_delaySender != null && length < m_delaySender.DelayLength)
{
this.m_delaySender.Send(new QueueDataBytes(buffer, offset, length));
this.m_delaySender.Send(QueueDataBytes.CreateNew(buffer, offset, length));
}
else
{
this.MainSerialPort.AbsoluteSend(buffer, offset, length);
}
this.LastSendTime = DateTime.Now;
this.m_sendCounter.Increment(length);
}
}
@@ -803,52 +935,5 @@ public class SerialClientBase : BaseSerial, ISerialClient
#endregion
private void ProcessReceived(SerialReceivedEventArgs e)
{
if (!this.m_online)
{
e.UserToken.SafeDispose();
return;
}
if (MainSerialPort.BytesToRead > 0)
{
byte[] buffer = new byte[2048];
var byteBlock = (ByteBlock)e.UserToken;
int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead);
byteBlock.Write(buffer, byteBlock.Len, num);
this.HandleBuffer(byteBlock);
try
{
var newByteBlock = BytePool.Default.GetByteBlock(Math.Min(this.BufferLength * this.m_bufferRate, 1024 * 1024));
newByteBlock.SetLength(num);
e.UserToken = newByteBlock;
if (MainSerialPort.BytesToRead > 0)
{
this.m_bufferRate += 2;
this.ProcessReceived(e);
}
}
catch (Exception ex)
{
e.UserToken.SafeDispose();
this.BreakOut(ex.Message);
}
}
else
{
e.UserToken.SafeDispose();
this.BreakOut("远程终端主动关闭");
}
}
private void SetSerialPort(SerialPort serialPort)
{
if (serialPort == null)
{
return;
}
this.m_mainSerialPort = serialPort;
}
}

View File

@@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="TouchSocket" Version="2.0.0-beta.138" />
<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

@@ -237,13 +237,13 @@
WaitingClientEx
</summary>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.#ctor(ThingsGateway.Foundation.Serial.SerialClient)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.#ctor(ThingsGateway.Foundation.Serial.SerialsSession)">
<summary>
<inheritdoc cref="T:ThingsGateway.Foundation.ReadWriteDevicesSerialBase"/>
</summary>
<param name="serialClient"></param>
<param name="serialSession"></param>
</member>
<member name="P:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.SerialClient">
<member name="P:ThingsGateway.Foundation.ReadWriteDevicesSerialBase.SerialsSession">
<summary>
串口管理对象
</summary>
@@ -351,7 +351,7 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpServerBase.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Core.IRequestInfo)">
<summary>
接收解析
</summary>
@@ -685,7 +685,7 @@
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
接收数据
</summary>
@@ -821,7 +821,7 @@
<summary>
建立Tcp的连接。
</summary>
<param name="timeOut"></param>
<param name="timeout"></param>
<param name="token"></param>
<exception cref="T:System.ObjectDisposedException"></exception>
<exception cref="T:System.ArgumentNullException"></exception>
@@ -837,7 +837,13 @@
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.GetStream">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<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>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Setup(System.String)">
@@ -846,7 +852,7 @@
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
@@ -875,7 +881,7 @@
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SetAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.TcpClientBaseEx.CanSetDataHandlingAdapter"/>的值。
</summary>
@@ -886,13 +892,13 @@
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(System.Byte[],System.Int32,System.Int32)">
@@ -903,7 +909,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
@@ -912,7 +918,7 @@
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(System.Byte[],System.Int32,System.Int32)">
@@ -923,16 +929,16 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
@@ -941,7 +947,7 @@
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.DefaultSend(System.Byte[],System.Int32,System.Int32)">
@@ -952,7 +958,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.TcpClientBaseEx.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
@@ -963,7 +969,7 @@
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.WaitingClientExExtension">
@@ -1037,9 +1043,9 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpDataHandleAdapter`1.GetResponse(TouchSocket.Core.ByteBlock,`0,System.Byte[],System.Byte[])">
<summary>
解包获取实际数据包
<para>当不满足解析条件时,请返回<see cref="F:TouchSocket.Sockets.FilterResult.Cache"/>,此时会保存<see cref="P:TouchSocket.Core.ByteBlock.CanReadLen"/>的数据</para>
<para>当数据部分异常时,请移动<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>到指定位置,然后返回<see cref="F:TouchSocket.Sockets.FilterResult.GoOn"/></para>
<para>当完全满足解析条件时,请返回<see cref="F:TouchSocket.Sockets.FilterResult.Success"/>最后将<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>移至指定位置。</para>
<para>当不满足解析条件时,请返回<see cref="F:TouchSocket.Core.FilterResult.Cache"/>,此时会保存<see cref="P:TouchSocket.Core.ByteBlock.CanReadLen"/>的数据</para>
<para>当数据部分异常时,请移动<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>到指定位置,然后返回<see cref="F:TouchSocket.Core.FilterResult.GoOn"/></para>
<para>当完全满足解析条件时,请返回<see cref="F:TouchSocket.Core.FilterResult.Success"/>最后将<see cref="P:TouchSocket.Core.ByteBlock.Pos"/>移至指定位置。</para>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesTcpDataHandleAdapter`1.GoSend(System.Byte[])">
@@ -1105,7 +1111,7 @@
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(System.Net.EndPoint,System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.PreviewSend(TouchSocket.Core.IRequestInfo)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.ReadWriteDevicesUdpDataHandleAdapter`1.Reset">
@@ -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,103 +1841,89 @@
日志记录器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerial.SetBufferLength(System.Int32)">
<member name="T:ThingsGateway.Foundation.Serial.ISerialSession">
<summary>
设置数据交互缓存池尺寸min=1024 byte。
一般情况下该值用于三个方面,包括:发送、接收缓存,及内存池的默认申请。
</summary>
<param name="value"></param>
<returns></returns>
</member>
<member name="T:ThingsGateway.Foundation.Serial.ISerialClient">
<summary>
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.ISerialClientBase"/>
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.ISerialSessionBase"/>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClient.Connected">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSession.Connected">
<summary>
成功连接到服务器
成功打开串口
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClient.Connecting">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSession.Connecting">
<summary>
准备连接的时候
准备连接串口的时候
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClient.Connect(System.Int32)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSession.Connect">
<summary>
连接串口
</summary>
<exception cref="T:System.TimeoutException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClient.Setup(TouchSocket.Core.TouchSocketConfig)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSession.Setup(TouchSocket.Core.TouchSocketConfig)">
<summary>
配置服务器
</summary>
<param name="config"></param>
<exception cref="T:System.Exception"></exception>
</member>
<member name="T:ThingsGateway.Foundation.Serial.ISerialClientBase">
<member name="T:ThingsGateway.Foundation.Serial.ISerialSessionBase">
<summary>
串口连接接口。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.CanSetDataHandlingAdapter">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.CanSetDataHandlingAdapter">
<summary>
是否允许自由调用<see cref="M:ThingsGateway.Foundation.Serial.ISerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)"/>进行赋值。
是否允许自由调用<see cref="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)"/>进行赋值。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Config">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Config">
<summary>
客户端配置
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.DataHandlingAdapter">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.DataHandlingAdapter">
<summary>
数据处理适配器
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Disconnected">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Disconnected">
<summary>
断开连接
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.Disconnecting">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.Disconnecting">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
</para>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.IsClient">
<summary>
表示是否为客户端。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.MainSerialPort">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.MainSerialPort">
<summary>
主通信器
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.ReceiveType">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.ReceiveType">
<summary>
接收模式
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.ISerialClientBase.SerialProperty">
<member name="P:ThingsGateway.Foundation.Serial.ISerialSessionBase.SerialProperty">
<summary>
串口描述
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClientBase.Close(System.String)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.Close(System.String)">
<summary>
关闭客户端。
</summary>
<param name="msg"></param>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.ISerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<member name="M:ThingsGateway.Foundation.Serial.ISerialSessionBase.SetDataHandlingAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置数据处理适配器
</summary>
@@ -1942,308 +1939,31 @@
同步根。
</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>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialClient">
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.SerialClientBase"/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClient.Received">
<summary>
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClient.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<summary>
接收数据
</summary>
<param name="byteBlock"></param>
<param name="requestInfo"></param>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialClientBase">
<summary>
串口管理
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.#ctor">
<summary>
构造函数
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Connected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Connecting">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Disconnected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Disconnecting">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnConnected(TouchSocket.Sockets.ConnectedEventArgs)">
<summary>
已经建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnConnecting(ThingsGateway.Foundation.Serial.SerialConnectingEventArgs)">
<summary>
准备连接的时候此时已初始化Socket但是并未建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDisconnected(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
断开连接。在客户端未设置连接状态时,不会触发
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDisconnecting(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
当主动调用Close断开时。
</para>
</summary>
<param name="e"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSend">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSetDataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Config">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Container">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.DataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.IsClient">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.LastReceivedTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.LastSendTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.MainSerialPort">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.OnHandleRawBuffer">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.OnHandleReceivedData">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Online">
<inheritdoc/>
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.PluginsManager">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.Protocol">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.ReceiveType">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Close(System.String)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Dispose(System.Boolean)">
<summary>
<inheritdoc/>
</summary>
<param name="disposing"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Connect(System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.ConnectAsync(System.Int32)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.TcpConnect(System.Int32)">
<summary>
建立Tcp的连接。
</summary>
<param name="timeout"></param>
<exception cref="T:System.ObjectDisposedException"></exception>
<exception cref="T:System.ArgumentNullException"></exception>
<exception cref="T:System.Exception"></exception>
<exception cref="T:System.TimeoutException"></exception>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialClientBase.SerialProperty">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SetDataHandlingAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Sockets.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
<param name="byteBlock">以二进制流形式传递</param>
<param name="requestInfo">以解析的数据对象传递</param>
<returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleSendingData(System.Byte[],System.Int32,System.Int32)">
<summary>
当即将发送时,如果覆盖父类方法,则不会触发插件。
</summary>
<param name="buffer">数据缓存区</param>
<param name="offset">偏移</param>
<param name="length">长度</param>
<returns>返回值表示是否允许发送</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.LoadConfig(TouchSocket.Core.TouchSocketConfig)">
<summary>
加载配置
</summary>
<param name="config"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.OnDelaySenderError(System.Exception)">
<summary>
在延迟发生错误
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SetAdapter(TouchSocket.Sockets.TcpDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.Serial.SerialClientBase.CanSetDataHandlingAdapter"/>的值。
</summary>
<param name="adapter"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.HandleBuffer(TouchSocket.Core.ByteBlock)">
<summary>
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(TouchSocket.Sockets.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(TouchSocket.Sockets.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.DefaultSend(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialClientBase.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Sockets.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialDelaySender">
<summary>
延迟发送器
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.#ctor(System.IO.Ports.SerialPort,System.Int32,System.Action{System.Exception})">
<member name="M:ThingsGateway.Foundation.Serial.SerialDelaySender.#ctor(System.IO.Ports.SerialPort,TouchSocket.Sockets.DelaySenderOption,System.Action{System.Exception})">
<summary>
延迟发送器
</summary>
<param name="serialPort"></param>
<param name="onError"></param>
<param name="delaySenderOption"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.DelayLength">
<summary>
延迟包最大尺寸默认1024*512字节
延迟包最大尺寸。
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialDelaySender.Sending">
@@ -2295,6 +2015,269 @@
<member name="M:ThingsGateway.Foundation.Serial.SerialProperty.ToString">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialsSession">
<inheritdoc cref="T:ThingsGateway.Foundation.Serial.SerialSessionBase"/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialsSession.Received">
<summary>
接收到数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialsSession.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
接收数据
</summary>
<param name="byteBlock"></param>
<param name="requestInfo"></param>
</member>
<member name="T:ThingsGateway.Foundation.Serial.SerialSessionBase">
<summary>
串口管理
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.#ctor">
<summary>
构造函数
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Connected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Connecting">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Disconnected">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Disconnecting">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnConnected(TouchSocket.Sockets.ConnectedEventArgs)">
<summary>
已经建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnConnecting(ThingsGateway.Foundation.Serial.SerialConnectingEventArgs)">
<summary>
准备连接的时候此时已初始化Socket但是并未建立Tcp连接
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDisconnected(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
断开连接。在客户端未设置连接状态时,不会触发
</summary>
<param name="e"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDisconnecting(TouchSocket.Sockets.DisconnectEventArgs)">
<summary>
即将断开连接(仅主动断开时有效)。
<para>
当主动调用Close断开时。
</para>
</summary>
<param name="e"></param>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.LastReceivedTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.LastSendTime">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.OnHandleRawBuffer">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.OnHandleReceivedData">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Container">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSetDataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Config">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.DataHandlingAdapter">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.SerialProperty">
<summary>
<inheritdoc/>
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.MainSerialPort">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Online">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSend">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.PluginsManager">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.ReceiveType">
<inheritdoc/>
</member>
<member name="P:ThingsGateway.Foundation.Serial.SerialSessionBase.Protocol">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Close(System.String)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Dispose(System.Boolean)">
<summary>
<inheritdoc/>
</summary>
<param name="disposing"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Open">
<summary>
打开串口
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Connect">
<inheritdoc/>
</member>
<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>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Setup(TouchSocket.Core.TouchSocketConfig)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleReceivedData(TouchSocket.Core.ByteBlock,TouchSocket.Core.IRequestInfo)">
<summary>
处理已接收到的数据。
</summary>
<param name="byteBlock">以二进制流形式传递</param>
<param name="requestInfo">以解析的数据对象传递</param>
<returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleSendingData(System.Byte[],System.Int32,System.Int32)">
<summary>
当即将发送时,如果覆盖父类方法,则不会触发插件。
</summary>
<param name="buffer">数据缓存区</param>
<param name="offset">偏移</param>
<param name="length">长度</param>
<returns>返回值表示是否允许发送</returns>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.LoadConfig(TouchSocket.Core.TouchSocketConfig)">
<summary>
加载配置
</summary>
<param name="config"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.OnDelaySenderError(System.Exception)">
<summary>
在延迟发生错误
</summary>
<param name="ex"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SetAdapter(TouchSocket.Core.SingleStreamDataHandlingAdapter)">
<summary>
设置适配器,该方法不会检验<see cref="P:ThingsGateway.Foundation.Serial.SerialSessionBase.CanSetDataHandlingAdapter"/>的值。
</summary>
<param name="adapter"></param>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.HandleBuffer(TouchSocket.Core.ByteBlock)">
<summary>
处理数据
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.Send(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(TouchSocket.Core.IRequestInfo)">
<summary>
<inheritdoc/>
</summary>
<param name="requestInfo"></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"></exception>
<exception cref="T:System.Exception"></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.SendAsync(System.Collections.Generic.IList{System.ArraySegment{System.Byte}})">
<summary>
<inheritdoc/>
</summary>
<param name="transferBytes"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.DefaultSend(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="M:ThingsGateway.Foundation.Serial.SerialSessionBase.DefaultSendAsync(System.Byte[],System.Int32,System.Int32)">
<summary>
<inheritdoc/>
</summary>
<param name="buffer"><inheritdoc/></param>
<param name="offset"><inheritdoc/></param>
<param name="length"><inheritdoc/></param>
<exception cref="T:TouchSocket.Sockets.NotConnectedException"><inheritdoc/></exception>
<exception cref="T:TouchSocket.Core.OverlengthException"><inheritdoc/></exception>
<exception cref="T:System.Exception"><inheritdoc/></exception>
</member>
<member name="T:ThingsGateway.Foundation.SerialPortExtensions">
<summary>
SocketExtension

View File

@@ -27,14 +27,14 @@ namespace DLT645Test
.SetSerialProperty(new SerialProperty() //串口链路才需要
{
PortName = "COM1"
}).SetBufferLength(1024);
});
var serialClient = new SerialClient();//链路对象
serialClient.Setup(config);
var serialSession = new SerialsSession();//链路对象
serialSession.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
DLT645_2007 dlt6452007 = new(serialClient)//传入链路
DLT645_2007 dlt6452007 = new(serialSession)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -47,7 +47,7 @@ namespace DLT645Test
#region
//测试读取写入
Console.WriteLine("dlt6452007" + dlt6452007.SerialClient.SerialProperty.ToJson());
Console.WriteLine("dlt6452007" + dlt6452007.SerialsSession.SerialProperty.ToJsonString());
await TestAsync(dlt6452007);
#endregion

View File

@@ -61,18 +61,18 @@ namespace ModbusDemo
.SetSerialProperty(new SerialProperty() //串口链路才需要
{
PortName = "COM1"
}).SetBufferLength(1024);
});
var tcpClient1 = new TcpClientEx();//链路对象
var tcpClient2 = new TcpClientEx();//链路对象
var udpSession1 = new UdpSession();//链路对象
var udpSession2 = new UdpSession();//链路对象
var serialClient = new SerialClient();//链路对象
var serialSession = new SerialsSession();//链路对象
tcpClient1.Setup(config);
tcpClient2.Setup(config);
udpSession1.Setup(config);
udpSession2.Setup(config);
serialClient.Setup(config);
serialSession.Setup(config);
//创建协议对象,构造函数需要传入对应链路对象
@@ -108,7 +108,7 @@ namespace ModbusDemo
TimeOut = 3000,
IsCheckMessageId = true
};
ModbusRtu modbusRtu = new(serialClient)//传入链路
ModbusRtu modbusRtu = new(serialSession)//传入链路
{
//协议配置
DataFormat = DataFormat.ABCD,
@@ -134,7 +134,7 @@ namespace ModbusDemo
//测试读取写入
Console.WriteLine("modbusTcp" + modbusTcp.TcpClientEx.RemoteIPHost);
await TestAsync(modbusTcp);
Console.WriteLine("modbusRtu" + modbusRtu.SerialClient.SerialProperty.ToJson());
Console.WriteLine("modbusRtu" + modbusRtu.SerialsSession.SerialProperty.ToJsonString());
await TestAsync(modbusRtu);
Console.WriteLine("modbusRtuOvrTcp" + modbusRtuOvrTcp.TcpClientEx.RemoteIPHost);
await TestAsync(modbusRtuOvrTcp);

View File

@@ -12,7 +12,7 @@ namespace ModbusDemo
{
OPCNode = new()
{
OPCUrl = "opc.tcp://desktop-p5gb4iq:50001/StandardServer",
OPCUrl = "opc.tcp://127.0.0.1:49320",
IsUseSecurity = true,
}
};

View File

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

View File

@@ -26,8 +26,8 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
/// <summary>
/// DLT645_2007
/// </summary>
/// <param name="serialClient"></param>
public DLT645_2007(SerialClient serialClient) : base(serialClient)
/// <param name="serialSession"></param>
public DLT645_2007(SerialsSession serialSession) : base(serialSession)
{
ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big);
RegisterByteLength = 2;
@@ -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)
{
@@ -102,7 +119,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
{
EnableFEHead = EnableFEHead
};
SerialClient.SetDataHandlingAdapter(dataHandleAdapter);
SerialsSession.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>
public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default)
@@ -182,7 +199,7 @@ public class DLT645_2007 : ReadWriteDevicesSerialBase
var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes());
if (commandResult.IsSuccess)
{
SerialClient.Send(commandResult.Content);
SerialsSession.Send(commandResult.Content);
return OperResult.CreateSuccessResult();
}
else

View File

@@ -62,6 +62,18 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
}
}
}
int sendHeadCodeIndex = 0;
if (send != null)
{
for (int index = 0; index < send.Length; index++)
{
if (send[index] == 0x68)
{
sendHeadCodeIndex = index;
break;
}
}
}
//帧起始符 地址域 帧起始符 控制码 数据域长度共10个字节
if (headCodeIndex < 0 || headCodeIndex + 10 > response.Length)
@@ -88,6 +100,49 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
if (
(response[headCodeIndex + 1] != send[sendHeadCodeIndex + 1]) ||
(response[headCodeIndex + 2] != send[sendHeadCodeIndex + 2]) ||
(response[headCodeIndex + 3] != send[sendHeadCodeIndex + 3]) ||
(response[headCodeIndex + 4] != send[sendHeadCodeIndex + 4]) ||
(response[headCodeIndex + 5] != send[sendHeadCodeIndex + 5]) ||
(response[headCodeIndex + 6] != send[sendHeadCodeIndex + 6])
)//设备地址不符合时,返回错误
{
if (
(response[headCodeIndex + 1] == 0xAA) &&
(response[headCodeIndex + 2] == 0xAA) &&
(response[headCodeIndex + 3] == 0xAA) &&
(response[headCodeIndex + 4] == 0xAA) &&
(response[headCodeIndex + 5] == 0xAA) &&
(response[headCodeIndex + 6] == 0xAA)
)//读写通讯地址例外
{
}
else
{
request.Message = "返回地址不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
}
if ((response[headCodeIndex + 8] != send[sendHeadCodeIndex + 8] + 0x80))//控制码不符合时,返回错误
{
request.Message = "返回控制码:" + $"0x{response[headCodeIndex + 8]:X2},请求控制码:" + $"0x{send[sendHeadCodeIndex + 8]:X2},不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
if ((response[headCodeIndex + 8] & 0x40) == 0x40)//控制码bit6为1时返回错误
{
byte byte1 = (byte)(response[headCodeIndex + 10] - 0x33);
@@ -96,13 +151,35 @@ public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
else
if (send[sendHeadCodeIndex + 8] == (byte)ControlCode.Read ||
send[sendHeadCodeIndex + 8] == (byte)ControlCode.Write
)
{
request.Content = response.RemoveBegin(headCodeIndex + 10).RemoveLast(response.Length + 2 - len - headCodeIndex);
request.ResultCode = ResultCode.Success;
return FilterResult.Success;
//数据标识不符合时,返回错误
if (
(response[headCodeIndex + 10] == send[sendHeadCodeIndex + 10]) &&
(response[headCodeIndex + 11] == send[sendHeadCodeIndex + 11]) &&
(response[headCodeIndex + 12] == send[sendHeadCodeIndex + 12]) &&
(response[headCodeIndex + 13] == send[sendHeadCodeIndex + 13])
)
{
}
else
{
request.Message = "返回数据标识不符合规则";
request.ResultCode = ResultCode.Fail;
return FilterResult.Success;
}
}
request.Content = response.RemoveBegin(headCodeIndex + 10).RemoveLast(response.Length + 2 - len - headCodeIndex);
request.ResultCode = ResultCode.Success;
return FilterResult.Success;
}
else
{

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

@@ -41,11 +41,11 @@
DLT645_2007
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialClient)">
<member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialsSession)">
<summary>
DLT645_2007
</summary>
<param name="serialClient"></param>
<param name="serialSession"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.CacheTimeout">
<summary>

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

@@ -24,8 +24,8 @@ public class ModbusRtu : ReadWriteDevicesSerialBase
/// <summary>
/// ModbusRtu
/// </summary>
/// <param name="serialClient"></param>
public ModbusRtu(SerialClient serialClient) : base(serialClient)
/// <param name="serialSession"></param>
public ModbusRtu(SerialsSession serialSession) : base(serialSession)
{
ThingsGatewayBitConverter = new ThingsGatewayBitConverter(EndianType.Big);
RegisterByteLength = 2;
@@ -87,7 +87,7 @@ public class ModbusRtu : ReadWriteDevicesSerialBase
Crc16CheckEnable = Crc16CheckEnable,
CacheTimeout = TimeSpan.FromMilliseconds(CacheTimeout)
};
SerialClient.SetDataHandlingAdapter(dataHandleAdapter);
SerialsSession.SetDataHandlingAdapter(dataHandleAdapter);
}
/// <inheritdoc/>

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

@@ -239,11 +239,11 @@
ModbusRtu
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialClient)">
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.#ctor(ThingsGateway.Foundation.Serial.SerialsSession)">
<summary>
ModbusRtu
</summary>
<param name="serialClient"></param>
<param name="serialSession"></param>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu.CacheTimeout">
<summary>
@@ -378,7 +378,7 @@
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Sockets.IRequestInfo)">
<member name="M:ThingsGateway.Foundation.Adapter.Modbus.ModbusServer.Received(TouchSocket.Sockets.SocketClient,TouchSocket.Core.IRequestInfo)">
<inheritdoc/>
</member>
<member name="T:ThingsGateway.Foundation.Adapter.Modbus.ModbusServerDataHandleAdapter">

View File

@@ -75,7 +75,7 @@ public class OpcDiscovery
{
return new OperResult<ServerInfo>($"无法创建OPCServer连接请检查OPC名称是否一致以下为Host{host}中的OPC列表:"
+ Environment.NewLine +
JToken.Parse(serverInfos.ToJson()).ToString()
JToken.Parse(serverInfos.ToJsonString()).ToString()
);
}
return OperResult.CreateSuccessResult(result);

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

@@ -70,7 +70,7 @@ public static class JsonUtils
TypeId = new { Id = dataTypeId.Identifier, Namespace = dataTypeId.NamespaceIndex },
Body = json
}
}.ToJson();
}.ToJsonString();
break;
case BuiltInType.Variant:
var type = TypeInfo.GetDataTypeId(GetSystemType(json.Type));
@@ -82,13 +82,13 @@ public static class JsonUtils
Body = json
}
}.ToJson();
}.ToJsonString();
break;
default:
newData = new
{
Value = json
}.ToJson();
}.ToJsonString();
break;
}

View File

@@ -34,7 +34,12 @@ public class OPCNode
/// </summary>
[Description("登录密码")]
public string Password { get; set; }
/// <summary>
/// 检查域
/// </summary>
[Description("检查域")]
public bool CheckDomain { get; set; }
/// <summary>
/// 更新间隔
/// </summary>

View File

@@ -83,14 +83,6 @@ public class OPCUAClient : DisposableObject
Log = log;
var certificateValidator = new CertificateValidator();
certificateValidator.CertificateValidation += CertificateValidation;
SecurityConfiguration securityConfigurationcv = new()
{
UseValidatedCertificates = true,
AutoAcceptUntrustedCertificates = true,//自动接受证书
RejectSHA1SignedCertificates = false,
MinimumCertificateKeySize = 1024,
};
certificateValidator.Update(securityConfigurationcv);
// 构建应用程序配置
m_configuration = new ApplicationConfiguration
@@ -112,7 +104,8 @@ public class OPCUAClient : DisposableObject
SecurityConfiguration = new SecurityConfiguration
{
AutoAcceptUntrustedCertificates = true,
UseValidatedCertificates = true,
AutoAcceptUntrustedCertificates = true,//自动接受证书
RejectSHA1SignedCertificates = false,
MinimumCertificateKeySize = 1024,
SuppressNonceValidationErrors = true,
@@ -172,6 +165,8 @@ public class OPCUAClient : DisposableObject
DisableHiResClock = true
};
certificateValidator.Update(m_configuration);
m_configuration.Validate(ApplicationType.Client);
m_application.ApplicationConfiguration = m_configuration;
@@ -227,7 +222,7 @@ public class OPCUAClient : DisposableObject
{
try
{
var variableNode = (VariableNode)ReadNode(items[i], false);
var variableNode = await ReadNodeAsync(items[i], false);
var item = new MonitoredItem
{
StartNodeId = variableNode.NodeId,
@@ -236,8 +231,6 @@ public class OPCUAClient : DisposableObject
Filter = OPCNode.DeadBand == 0 ? null : new DataChangeFilter() { DeadbandValue = OPCNode.DeadBand, DeadbandType = (int)DeadbandType.Absolute, Trigger = DataChangeTrigger.StatusValue },
SamplingInterval = OPCNode?.UpdateRate ?? 1000,
};
await typeSystem.LoadType(variableNode.DataType, true, true);
item.Notification += Callback;
monitoredItems.Add(item);
}
@@ -259,7 +252,7 @@ public class OPCUAClient : DisposableObject
var iserror = m_subscription.MonitoredItems.Any(a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode));
if (iserror)
{
Log.Error("创建以下变量订阅失败" + m_subscription.MonitoredItems.Where(a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode)).Select(a => a.StartNodeId.ToString() + "" + a.Status.Error.ToString()).ToJson());
Log.Error("创建以下变量订阅失败" + m_subscription.MonitoredItems.Where(a => a.Status.Error != null && StatusCode.IsBad(a.Status.Error.StatusCode)).Select(a => a.StartNodeId.ToString() + "" + a.Status.Error.ToString()).ToJsonString());
}
lock (dic_subscriptions)
@@ -316,11 +309,11 @@ public class OPCUAClient : DisposableObject
}
private void Callback(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs monitoredItemNotificationEventArgs)
private async void Callback(MonitoredItem monitoreditem, MonitoredItemNotificationEventArgs monitoredItemNotificationEventArgs)
{
try
{
VariableNode variableNode = (VariableNode)ReadNode(monitoreditem.StartNodeId.ToString(), false);
var variableNode = await ReadNodeAsync(monitoreditem.StartNodeId.ToString(), false);
foreach (var value in monitoreditem.DequeueValues())
{
if (value.Value != null)
@@ -493,6 +486,55 @@ public class OPCUAClient : DisposableObject
m_session = null;
}
}
private ComplexTypeSystem typeSystem;
/// <summary>
/// Creates a new session.
/// </summary>
/// <returns>The new session object.</returns>
private async Task<ISession> ConnectAsync(string serverUrl)
{
PrivateDisconnect();
if (m_configuration == null)
{
throw new ArgumentNullException("未初始化配置");
}
var useSecurity = OPCNode?.IsUseSecurity ?? true;
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, serverUrl, useSecurity, 10000);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
UserIdentity userIdentity;
if (!OPCNode.UserName.IsNullOrEmpty())
{
userIdentity = new UserIdentity(OPCNode.UserName, OPCNode.Password);
}
else
{
userIdentity = new UserIdentity(new AnonymousIdentityToken());
}
//创建本地证书
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
m_session = await Opc.Ua.Client.Session.Create(
m_configuration,
endpoint,
false,
OPCNode.CheckDomain,
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
60000,
userIdentity,
Array.Empty<string>());
typeSystem = new ComplexTypeSystem(m_session);
Log.Debug("连接成功");
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
//如果是订阅模式,连接时添加订阅组
if (OPCNode.ActiveSubscribe)
await AddSubscriptionAsync(Guid.NewGuid().ToString(), Variables.ToArray());
return m_session;
}
private void PrivateDisconnect()
{
@@ -502,7 +544,11 @@ public class OPCUAClient : DisposableObject
m_reConnectHandler.SafeDispose();
m_reConnectHandler = null;
}
m_session?.Close(10000);
if (m_session != null)
{
m_session.KeepAlive -= Session_KeepAlive;
m_session.Close(10000);
}
}
@@ -537,8 +583,7 @@ public class OPCUAClient : DisposableObject
NodeId = new NodeId(item.Key),
AttributeId = Attributes.Value,
};
var variableNode = (VariableNode)ReadNode(item.Key, false);
await typeSystem.LoadType(variableNode.DataType, true, true);
var variableNode = await ReadNodeAsync(item.Key, false, token);
var dataValue = JsonUtils.Decode(
m_session.MessageContext,
variableNode.DataType,
@@ -597,8 +642,6 @@ public class OPCUAClient : DisposableObject
ReadValueIdCollection nodesToRead = new();
for (int i = 0; i < nodeIds.Length; i++)
{
var variableNode = (VariableNode)ReadNode(nodeIds[i].ToString(), false);
await typeSystem.LoadType(variableNode.DataType, true, true);
nodesToRead.Add(new ReadValueId()
{
NodeId = nodeIds[i],
@@ -620,7 +663,7 @@ public class OPCUAClient : DisposableObject
List<(string, DataValue, JToken)> jTokens = new();
for (int i = 0; i < results.Count; i++)
{
var variableNode = (VariableNode)ReadNode(nodeIds[i].ToString(), false);
var variableNode = await ReadNodeAsync(nodeIds[i].ToString(), false, token);
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));
@@ -631,7 +674,7 @@ public class OPCUAClient : DisposableObject
/// <summary>
/// 从服务器或缓存读取节点
/// </summary>
private Node ReadNode(string nodeIdStr, bool isOnlyServer = true)
private async Task<VariableNode> ReadNodeAsync(string nodeIdStr, bool isOnlyServer = true, CancellationToken token = default)
{
if (!isOnlyServer)
{
@@ -642,8 +685,9 @@ public class OPCUAClient : DisposableObject
}
NodeId nodeToRead = new(nodeIdStr);
var node = m_session.ReadNode(nodeToRead);
_variableDicts.AddOrUpdate(nodeIdStr, (VariableNode)node);
var node = (VariableNode)await m_session.ReadNodeAsync(nodeToRead, token);
await typeSystem.LoadType(node.DataType, true, true);
_variableDicts.AddOrUpdate(nodeIdStr, node);
return node;
}
#endregion
@@ -900,55 +944,6 @@ public class OPCUAClient : DisposableObject
else
throw new Exception(string.Format("验证证书失败,错误代码:{0}: {1}", eventArgs.Error.Code, eventArgs.Error.AdditionalInfo));
}
private ComplexTypeSystem typeSystem;
/// <summary>
/// Creates a new session.
/// </summary>
/// <returns>The new session object.</returns>
private async Task<ISession> ConnectAsync(string serverUrl)
{
PrivateDisconnect();
if (m_configuration == null)
{
throw new ArgumentNullException("未初始化配置");
}
var useSecurity = OPCNode?.IsUseSecurity ?? true;
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(serverUrl, useSecurity);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
UserIdentity userIdentity;
ConfiguredEndpoint endpoint = new(null, endpointDescription, endpointConfiguration);
if (!OPCNode.UserName.IsNullOrEmpty())
{
userIdentity = new UserIdentity(OPCNode.UserName, OPCNode.Password);
}
else
{
userIdentity = new UserIdentity(new AnonymousIdentityToken());
}
//创建本地证书
await m_application.CheckApplicationInstanceCertificate(true, 0, 1200);
m_session = await Opc.Ua.Client.Session.Create(
m_configuration,
endpoint,
false,
false,
(string.IsNullOrEmpty(OPCUAName)) ? m_configuration.ApplicationName : OPCUAName,
60000,
userIdentity,
Array.Empty<string>());
typeSystem = new ComplexTypeSystem(m_session);
Log.Debug("连接成功");
m_session.KeepAliveInterval = OPCNode.KeepAliveInterval == 0 ? 60000 : OPCNode.KeepAliveInterval;
m_session.KeepAlive += new KeepAliveEventHandler(Session_KeepAlive);
//如果是订阅模式,连接时添加订阅组
if (OPCNode.ActiveSubscribe)
await AddSubscriptionAsync(Guid.NewGuid().ToString(), Variables.ToArray());
return m_session;
}
private async Task<OperResult<Dictionary<string, List<OPCNodeAttribute>>>> ReadNoteAttributeAsync(BrowseDescriptionCollection nodesToBrowse, ReadValueIdCollection nodesToRead, CancellationToken token)

View File

@@ -2,14 +2,14 @@
<PropertyGroup>
<!--<GenerateDocumentationFile>True</GenerateDocumentationFile>-->
<TargetFrameworks>net462;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.371.96" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.371.96" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Server" Version="1.4.371.96" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.4.372.56" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client.ComplexTypes" Version="1.4.372.56" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Server" Version="1.4.372.56" />
</ItemGroup>

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>
浏览地址空间
@@ -217,6 +225,11 @@
登录密码
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.CheckDomain">
<summary>
检查域
</summary>
</member>
<member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UpdateRate">
<summary>
更新间隔
@@ -375,6 +388,12 @@
断开连接。
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync(System.String)">
<summary>
Creates a new session.
</summary>
<returns>The new session object.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(System.String[],System.Threading.CancellationToken)">
<summary>
从服务器读取值
@@ -390,7 +409,7 @@
从服务器读取值
</summary>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNode(System.String,System.Boolean)">
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNodeAsync(System.String,System.Boolean,System.Threading.CancellationToken)">
<summary>
从服务器或缓存读取节点
</summary>
@@ -415,12 +434,6 @@
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Dispose(System.Boolean)">
<inheritdoc/>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync(System.String)">
<summary>
Creates a new session.
</summary>
<returns>The new session object.</returns>
</member>
<member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Server_ReconnectComplete(System.Object,System.EventArgs)">
<summary>
连接处理器连接事件处理完成。

View File

@@ -73,7 +73,7 @@ public class DLT645_2007 : CollectBase
/// <inheritdoc/>
public override bool IsConnected()
{
return _plc?.SerialClient?.CanSend == true;
return _plc?.SerialsSession?.CanSend == true;
}
/// <inheritdoc/>
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
@@ -94,12 +94,12 @@ public class DLT645_2007 : CollectBase
Parity = driverPropertys.Parity,
StopBits = driverPropertys.StopBits,
})
.SetBufferLength(1024);
client = new SerialClient();
((SerialClient)client).Setup(FoundataionConfig);
;
client = new SerialsSession();
((SerialsSession)client).Setup(FoundataionConfig);
}
//载入配置
_plc = new((SerialClient)client)
_plc = new((SerialsSession)client)
{
FrameTime = driverPropertys.FrameTime,
CacheTimeout = driverPropertys.CacheTimeout,

View File

@@ -55,7 +55,7 @@
if (firstRender)
{
//载入配置
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007((SerialClient)defalutDebugDriverPage.SerialClientPage.GetSerialClient());
_plc = new ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007((SerialsSession)defalutDebugDriverPage.SerialSessionPage.GetSerialSession());
defalutDebugDriverPage.Plc = _plc;
}
base.OnAfterRender(firstRender);

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

@@ -92,7 +92,7 @@ public class KafkaProducer : UpLoadBase
{
if (!token.IsCancellationRequested)
{
await KafKaUp(driverPropertys.VariableTopic, item.ToJson(), token);
await KafKaUp(driverPropertys.VariableTopic, item.ToJsonString(), token);
}
else
{
@@ -128,7 +128,7 @@ public class KafkaProducer : UpLoadBase
{
if (!token.IsCancellationRequested)
{
await KafKaUp(driverPropertys.DeviceTopic, item.ToJson(), token);
await KafKaUp(driverPropertys.DeviceTopic, item.ToJsonString(), token);
}
else
{

View File

@@ -66,7 +66,7 @@ public class ModbusRtu : CollectBase
/// <inheritdoc/>
public override bool IsConnected()
{
return _plc?.SerialClient?.CanSend == true;
return _plc?.SerialsSession?.CanSend == true;
}
/// <inheritdoc/>
public override List<DeviceVariableSourceRead> LoadSourceRead(List<DeviceVariableRunTime> deviceVariables)
@@ -87,12 +87,12 @@ public class ModbusRtu : CollectBase
Parity = driverPropertys.Parity,
StopBits = driverPropertys.StopBits,
})
.SetBufferLength(1024);
client = new SerialClient();
((SerialClient)client).Setup(FoundataionConfig);
;
client = new SerialsSession();
((SerialsSession)client).Setup(FoundataionConfig);
}
//载入配置
_plc = new((SerialClient)client)
_plc = new((SerialsSession)client)
{
Crc16CheckEnable = driverPropertys.Crc16CheckEnable,
FrameTime = driverPropertys.FrameTime,

View File

@@ -53,7 +53,7 @@
if (firstRender)
{
//载入配置
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu((SerialClient)defalutDebugDriverPage.SerialClientPage.GetSerialClient());
_plc = new ThingsGateway.Foundation.Adapter.Modbus.ModbusRtu((SerialsSession)defalutDebugDriverPage.SerialSessionPage.GetSerialSession());
defalutDebugDriverPage.Plc = _plc;
}
base.OnAfterRender(firstRender);

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

@@ -118,7 +118,7 @@ public class IotSharpClient : UpLoadBase
}
if (!token.IsCancellationRequested)
{
await MqttUp($"devices/{item.Key}/telemetry", nameValueDict.ToJson(), token);
await MqttUp($"devices/{item.Key}/telemetry", nameValueDict.ToJsonString(), token);
}
else
{
@@ -326,7 +326,7 @@ public class IotSharpClient : UpLoadBase
else
{
RpcResponse rpcResponse = new();
var nameValue = e.ApplicationMessage.ConvertPayloadToString().FromJson<List<KeyValuePair<string, string>>>();
var nameValue = e.ApplicationMessage.ConvertPayloadToString().FromJsonString<List<KeyValuePair<string, string>>>();
Dictionary<string, OperResult> results = new();
if (nameValue?.Count > 0)
{
@@ -345,13 +345,13 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
}
else
{
results.Add(item.Key, new("权限不足,变量不支持写入"));
results.Add(item.Key, new OperResult("权限不足,变量不支持写入"));
}
}
else
{
results.Add(item.Key, new("不存在该变量"));
results.Add(item.Key, new OperResult("不存在该变量"));
}
}
@@ -366,7 +366,7 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
ResponseId = rpcrequestid,
Method = rpcmethodname,
Success = !results.Any(a => !a.Value.IsSuccess),
Data = results.ToJson()
Data = results.ToJsonString()
};
}
else
@@ -396,7 +396,7 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
var variableMessage = new MqttApplicationMessageBuilder()
.WithTopic($"{topic}")
.WithPayload(rpcResponse.ToJson()).Build();
.WithPayload(rpcResponse.ToJsonString()).Build();
var isConnect = await TryMqttClientAsync(CancellationToken.None);
if (isConnect.IsSuccess)
await _mqttClient.PublishAsync(variableMessage);
@@ -416,7 +416,7 @@ GetPropertyValue(tag, nameof(variablePropertys.VariableRpcEnable)).ToBoolean()
{
LogMessage?.LogWarning(subResult.Items
.Where(a => a.ResultCode > (MqttClientSubscribeResultCode)10)
.Select(a => a.ToString()).ToJson());
.Select(a => a.ToString()).ToJsonString());
}
}
/// <summary>

View File

@@ -406,7 +406,7 @@ public class MqttClient : UpLoadBase
return;
if (arg.ApplicationMessage.Topic != driverPropertys.RpcWriteTopic)
return;
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJsonString<MqttRpcNameVaueWithId>();
if (rpcDatas == null)
return;
@@ -453,7 +453,7 @@ public class MqttClient : UpLoadBase
{
var variableMessage = new MqttApplicationMessageBuilder()
.WithTopic($"{driverPropertys.RpcSubTopic}")
.WithPayload(mqttRpcResult.ToJson()).Build();
.WithPayload(mqttRpcResult.ToJsonString()).Build();
var isConnect = await TryMqttClientAsync(CancellationToken.None);
if (isConnect.IsSuccess)
await _mqttClient.PublishAsync(variableMessage);
@@ -470,7 +470,7 @@ public class MqttClient : UpLoadBase
{
LogMessage?.Warning("订阅失败-" + subResult.Items
.Where(a => a.ResultCode > (MqttClientSubscribeResultCode)10)
.ToJson());
.ToJsonString());
}
}
/// <summary>

View File

@@ -260,7 +260,7 @@ public class MqttServer : UpLoadBase
return;
if (arg.ApplicationMessage.Topic != driverPropertys.RpcWriteTopic)
return;
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJson<MqttRpcNameVaueWithId>();
var rpcDatas = Encoding.UTF8.GetString(arg.ApplicationMessage.PayloadSegment).FromJsonString<MqttRpcNameVaueWithId>();
if (rpcDatas == null)
return;
MqttRpcResult mqttRpcResult = new() { RpcId = rpcDatas.RpcId, Success = true };
@@ -280,13 +280,13 @@ public class MqttServer : UpLoadBase
else
{
mqttRpcResult.Success = false;
mqttRpcResult.Message.Add(rpcData.Key, new("权限不足,变量不支持写入"));
mqttRpcResult.Message.Add(rpcData.Key, new OperResult("权限不足,变量不支持写入"));
}
}
else
{
mqttRpcResult.Success = false;
mqttRpcResult.Message.Add(rpcData.Key, new("不存在该变量"));
mqttRpcResult.Message.Add(rpcData.Key, new OperResult("不存在该变量"));
}
}
@@ -305,7 +305,7 @@ public class MqttServer : UpLoadBase
{
var variableMessage = new MqttApplicationMessageBuilder()
.WithTopic($"{driverPropertys.RpcSubTopic}")
.WithPayload(mqttRpcResult.ToJson()).Build();
.WithPayload(mqttRpcResult.ToJsonString()).Build();
await _mqttServer.InjectApplicationMessage(
new InjectedMqttApplicationMessage(variableMessage));
}

View File

@@ -32,19 +32,19 @@ namespace ThingsGateway.Mqtt
switch (logLevel)
{
case MqttNetLogLevel.Verbose:
LogMessage?.Log(LogLevel.Trace, source, message, exception);
LogMessage?.Log(LogLevel.Trace, source, message != null ? (parameters != null ? message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Info:
LogMessage?.Log(LogLevel.Info, source, message, exception);
LogMessage?.Log(LogLevel.Info, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Warning:
LogMessage?.Log(LogLevel.Warning, source, message, exception);
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
case MqttNetLogLevel.Error:
LogMessage?.Log(LogLevel.Warning, source, message, exception);
LogMessage?.Log(LogLevel.Warning, source, message != null ? (parameters != null ? string.Format(message, parameters) : message) : string.Empty, exception);
break;
}
}

Some files were not shown because too many files have changed in this diff Show More