Compare commits
	
		
			48 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | ec6c830cb0 | ||
|   | 2f86ccc4bf | ||
|   | 8ca445aec0 | ||
|   | 1e1f27c8a5 | ||
|   | 2b84bde367 | ||
|   | b52e58551d | ||
|   | 9aceed00bf | ||
|   | 58814f7f74 | ||
|   | 6a70ef9f31 | ||
|   | 82cc4ca500 | ||
|   | 4567fa04ed | ||
|   | 8b98b5d818 | ||
|   | 176d0351af | ||
|   | d63dc3384b | ||
|   | 1ccd704e30 | ||
|   | f5d23dbe79 | ||
|   | 75bfe53ac3 | ||
|   | 3308f916dd | ||
|   | e7140279ca | ||
|   | 1034719f5e | ||
|   | 2c00043a7f | ||
|   | 65c695d9ce | ||
|   | 57253fe46a | ||
|   | 4e5c443440 | ||
|   | 0b3b73d8ec | ||
|   | 921eabc134 | ||
|   | 0faa428751 | ||
|   | f71a2fdd63 | ||
|   | 4eb9ed8aba | ||
|   | d7b549abb8 | ||
|   | 95d723c578 | ||
|   | 2fcd853e86 | ||
|   | 07eef7c812 | ||
|   | b01e0757fa | ||
|   | 32844a20c6 | ||
|   | 5b6532c601 | ||
|   | 2c5b4b4027 | ||
|   | 72d7ecf195 | ||
|   | 2cfa6b4306 | ||
|   | 6f6ffde0ab | ||
|   | 1694739a16 | ||
|   | 95d1e8bfca | ||
|   | 60dec08e3c | ||
|   | a99d71be93 | ||
|   | f1331b6a0c | ||
|   | 10d66b642b | ||
|   | cd2310e4a8 | ||
|   | 1b399cf6b0 | 
| @@ -22,7 +22,9 @@ | ||||
|  | ||||
| [ThingsGateway演示地址](http://120.24.62.140:5000/) | ||||
|  | ||||
| 账户	:  **superAdmin**	密码 : **111111** | ||||
| 账户	:  **superAdmin**	 | ||||
|  | ||||
| 密码 : **111111** | ||||
|  | ||||
| ## 赞助 | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Version>2.0.7.0</Version> | ||||
| 		<Version>2.1.0.4</Version> | ||||
| 		<Authors>Diego</Authors> | ||||
| 		<Product>ThingsGateway</Product> | ||||
| 		<Copyright>© 2023-present Diego</Copyright> | ||||
|   | ||||
| @@ -18,6 +18,7 @@ using System.Reflection; | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| using UAParser; | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,7 @@ using System.Globalization; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| using Yitter.IdGenerator; | ||||
|  | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Application; | ||||
|  | ||||
| /// <summary> | ||||
|   | ||||
| @@ -16,6 +16,7 @@ using Furion.FriendlyException; | ||||
| using Mapster; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Application; | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ using Furion.FriendlyException; | ||||
| using Mapster; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| using Yitter.IdGenerator; | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ using Mapster; | ||||
| using SqlSugar; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Application; | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ using Furion.FriendlyException; | ||||
| using Mapster; | ||||
|  | ||||
| using ThingsGateway.Admin.Core; | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Application; | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -20,19 +20,19 @@ namespace ThingsGateway.Admin.Blazor.Core; | ||||
| public partial class AppBarItems | ||||
| { | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 链接 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT_URL { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>Ȩ | ||||
|     /// 版权 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 标题 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_TITLE { get; set; } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Components; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Blazor.Core; | ||||
| /// <summary> | ||||
| /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>/ͣ<><CDA3> <20>ı<EFBFBD><C4B1><EFBFBD>ʾ | ||||
| /// 启用/停用 文本提示 | ||||
| /// </summary> | ||||
| public partial class EnableChip | ||||
| { | ||||
| @@ -46,5 +46,5 @@ public partial class EnableChip | ||||
|  | ||||
|     private string TextColor => Value ? "green" : "error"; | ||||
|     private string Color => Value ? "green-lighten" : "warning-lighten"; | ||||
|     private string Label => Value ? EnabledLabel ?? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : DisabledLabel ?? "ͣ<EFBFBD><EFBFBD>"; | ||||
|     private string Label => Value ? EnabledLabel ?? "启用" : DisabledLabel ?? "停用"; | ||||
| } | ||||
| @@ -1,18 +1,18 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| namespace ThingsGateway.Admin.Blazor.Core; | ||||
| /// <summary> | ||||
| /// <EFBFBD>ղ<EFBFBD>/<2F><><EFBFBD>ݷ<EFBFBD>ʽ | ||||
| /// 收藏/快捷方式 | ||||
| /// </summary> | ||||
| public partial class Favorite | ||||
| { | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -22,17 +22,17 @@ public partial class Foter | ||||
| { | ||||
|     private string Version = ""; | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 链接 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT_URL { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>Ȩ | ||||
|     /// 版权 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 标题 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_TITLE { get; set; } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -20,23 +20,23 @@ namespace ThingsGateway.Admin.Blazor.Core; | ||||
| public partial class Logo | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Logo<EFBFBD>߶<EFBFBD> | ||||
|     /// Logo高度 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public int HeightInt { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 链接 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT_URL { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>Ȩ | ||||
|     /// 版权 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_COPYRIGHT { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 标题 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public string CONFIG_TITLE { get; set; } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -34,7 +34,7 @@ public partial class PageTabs | ||||
|         return op; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// Tabsʵ<EFBFBD><EFBFBD> | ||||
|     /// Tabs实例 | ||||
|     /// </summary> | ||||
|     public PPageTabs PPageTabs { get; private set; } | ||||
|  | ||||
| @@ -46,7 +46,7 @@ public partial class PageTabs | ||||
|     [Parameter] | ||||
|     public IEnumerable<string> SelfPatterns { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 子组件 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment ChildContent { get; set; } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -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> | ||||
| @@ -49,11 +50,11 @@ public partial class UserMenu | ||||
|         var ret = str?.ToJsonWithT<UnifyResult<string>>(); | ||||
|         if (ret?.Code != 200) | ||||
|         { | ||||
|             await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>", AlertTypes.Error); | ||||
|             await PopupService.EnqueueSnackbarAsync("注销失败", AlertTypes.Error); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             await PopupService.EnqueueSnackbarAsync("ע<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>", AlertTypes.Success); | ||||
|             await PopupService.EnqueueSnackbarAsync("注销成功", AlertTypes.Success); | ||||
|             await Task.Delay(500); | ||||
|             NavigationManager.NavigateTo(NavigationManager.Uri); | ||||
|         } | ||||
|   | ||||
| @@ -0,0 +1,68 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using Furion.DependencyInjection; | ||||
|  | ||||
| namespace BlazorComponent.I18n; | ||||
| /// <summary> | ||||
| /// CookieStorage | ||||
| /// </summary> | ||||
| public class CookieStorage : IScoped | ||||
| { | ||||
|     private readonly IJSRuntime _jsRuntime; | ||||
|     /// <summary> | ||||
|     /// CookieStorage | ||||
|     /// </summary> | ||||
|     /// <param name="jsRuntime"></param> | ||||
|     public CookieStorage(IJSRuntime jsRuntime) | ||||
|     { | ||||
|         _jsRuntime = jsRuntime; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// GetCookieAsync | ||||
|     /// </summary> | ||||
|     /// <param name="key"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<string> GetCookieAsync(string key) | ||||
|     { | ||||
|         return await _jsRuntime.InvokeAsync<string>(JsInteropConstants.GetCookie, key); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// GetCookie | ||||
|     /// </summary> | ||||
|     /// <param name="key"></param> | ||||
|     /// <returns></returns> | ||||
|     public string GetCookie(string key) | ||||
|     { | ||||
|         if (_jsRuntime is IJSInProcessRuntime jsInProcess) | ||||
|         { | ||||
|             return jsInProcess.Invoke<string>(JsInteropConstants.GetCookie, key); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// SetItemAsync | ||||
|     /// </summary> | ||||
|     /// <typeparam name="T"></typeparam> | ||||
|     /// <param name="key"></param> | ||||
|     /// <param name="value"></param> | ||||
|     public async void SetItemAsync<T>(string key, T value) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await _jsRuntime.InvokeVoidAsync(JsInteropConstants.SetCookie, key, value?.ToString()); | ||||
|         } | ||||
|         catch | ||||
|         { | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -10,6 +10,8 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using BlazorComponent; | ||||
|  | ||||
| using Furion; | ||||
|  | ||||
| using Masa.Blazor; | ||||
| @@ -61,6 +63,8 @@ public class Startup : AppStartup | ||||
|  | ||||
|  | ||||
|             }); | ||||
|             options.Locale = new Locale("zh-CN", "en-US"); | ||||
|  | ||||
|         }); | ||||
|  | ||||
|         services.AddScoped<InitTimezone>(); | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
|  | ||||
| 		<PackageReference Include="Masa.Blazor" Version="1.0.1" /> | ||||
| 		<PackageReference Include="Masa.Blazor" Version="1.0.3" /> | ||||
| 		<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.10" /> | ||||
|  | ||||
| 	</ItemGroup> | ||||
|   | ||||
| @@ -857,5 +857,38 @@ | ||||
|             设置深浅主题统一由这个方法为入口 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:BlazorComponent.I18n.CookieStorage"> | ||||
|             <summary> | ||||
|             CookieStorage | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:BlazorComponent.I18n.CookieStorage.#ctor(Microsoft.JSInterop.IJSRuntime)"> | ||||
|             <summary> | ||||
|             CookieStorage | ||||
|             </summary> | ||||
|             <param name="jsRuntime"></param> | ||||
|         </member> | ||||
|         <member name="M:BlazorComponent.I18n.CookieStorage.GetCookieAsync(System.String)"> | ||||
|             <summary> | ||||
|             GetCookieAsync | ||||
|             </summary> | ||||
|             <param name="key"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:BlazorComponent.I18n.CookieStorage.GetCookie(System.String)"> | ||||
|             <summary> | ||||
|             GetCookie | ||||
|             </summary> | ||||
|             <param name="key"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:BlazorComponent.I18n.CookieStorage.SetItemAsync``1(System.String,``0)"> | ||||
|             <summary> | ||||
|             SetItemAsync | ||||
|             </summary> | ||||
|             <typeparam name="T"></typeparam> | ||||
|             <param name="key"></param> | ||||
|             <param name="value"></param> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
| @@ -153,7 +154,7 @@ public class UserResoures : IDisposable | ||||
|     { | ||||
|         if (MasaBlazor.Theme.Dark != isDark || isDark == null) | ||||
|             MasaBlazor.ToggleTheme(); | ||||
|         _cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, isDark.ToJsonString()); | ||||
|         _cookieStorage?.SetItemAsync(BlazorResourceConst.ThemeCookieKey, MasaBlazor.Theme.Dark.ToJsonString()); | ||||
|     } | ||||
|  | ||||
|     private void InitCookie(IRequestCookieCollection cookies) | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Blazor; | ||||
| /// <summary> | ||||
| /// <EFBFBD><EFBFBD>ҳ | ||||
| /// 首页 | ||||
| /// </summary> | ||||
| public partial class Index | ||||
| { | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -18,7 +18,7 @@ using ThingsGateway.Admin.Core; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Blazor; | ||||
| /// <summary> | ||||
| /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| /// 个人设置 | ||||
| /// </summary> | ||||
| public partial class UserCenter | ||||
| { | ||||
| @@ -50,25 +50,25 @@ public partial class UserCenter | ||||
|     { | ||||
|         await UserCenterService.UpdateUserDefaultRazorAsync(UserManager.UserId, DefaultMenuId); | ||||
|         await MainLayout.StateHasChangedAsync(); | ||||
|         await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success); | ||||
|         await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success); | ||||
|     } | ||||
|  | ||||
|     async Task OnShortcutSaveAsync() | ||||
|     { | ||||
|         await UserCenterService.UpdateWorkbenchAsync(_menusChoice); | ||||
|         await MainLayout.StateHasChangedAsync(); | ||||
|         await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success); | ||||
|         await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success); | ||||
|     } | ||||
|     async Task OnUpdatePasswordInfoAsync(FormContext context) | ||||
|     { | ||||
|         var success = context.Validate(); | ||||
|         if (success) | ||||
|         { | ||||
|             //<EFBFBD><EFBFBD>֤<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD> | ||||
|             //验证成功,操作业务 | ||||
|             _passwordInfoInput.Id = UserResoures.CurrentUser.Id; | ||||
|             await UserCenterService.EditPasswordAsync(_passwordInfoInput); | ||||
|             await MainLayout.StateHasChangedAsync(); | ||||
|             await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>¼", AlertTypes.Success); | ||||
|             await PopupService.EnqueueSnackbarAsync("成功,将重新登录", AlertTypes.Success); | ||||
|             await Task.Delay(2000); | ||||
|             NavigationManager.NavigateTo(NavigationManager.Uri); | ||||
|         } | ||||
| @@ -78,6 +78,6 @@ public partial class UserCenter | ||||
|     { | ||||
|         await UserCenterService.UpdateUserInfoAsync(_updateInfoInput); | ||||
|         await MainLayout.StateHasChangedAsync(); | ||||
|         await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success); | ||||
|         await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success); | ||||
|     } | ||||
| } | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|  | ||||
| using Furion.DependencyInjection; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Core; | ||||
| namespace ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| /// <summary> | ||||
| /// 对象拓展 | ||||
|   | ||||
| @@ -18,6 +18,8 @@ using System.Collections; | ||||
| using System.Data; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Admin.Core.JsonExtensions; | ||||
|  | ||||
| namespace ThingsGateway.Admin.Core; | ||||
|  | ||||
| /// <summary> | ||||
|   | ||||
| @@ -9,10 +9,10 @@ | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.40" /> | ||||
| 		<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.40" /> | ||||
| 		<PackageReference Include="Furion.Pure" Version="4.8.8.40" /> | ||||
| 		<PackageReference Include="SqlSugarCore" Version="5.1.4.96" /> | ||||
| 		<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.8.8.41" /> | ||||
| 		<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.8.8.41" /> | ||||
| 		<PackageReference Include="Furion.Pure" Version="4.8.8.41" /> | ||||
| 		<PackageReference Include="SqlSugarCore" Version="5.1.4.102" /> | ||||
| 		<PackageReference Include="UAParser" Version="3.1.47" /> | ||||
| 		<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> | ||||
| 		<PackageReference Include="MiniExcel" Version="1.31.2" /> | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -89,13 +89,8 @@ public class RpcControler : IDynamicApiController | ||||
|     [Description("写入变量")] | ||||
|     public async Task<Dictionary<string, OperResult>> WriteDeviceMethods(Dictionary<string, string> objs) | ||||
|     { | ||||
|         Dictionary<string, OperResult> operResultDict = new(); | ||||
|         foreach (KeyValuePair<string, string> obj in objs) | ||||
|         { | ||||
|             var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", obj); | ||||
|             operResultDict.Add(obj.Key, result); | ||||
|         } | ||||
|         return operResultDict; | ||||
|         var result = await RpcCore.InvokeDeviceMethodAsync($"WebApi-{UserManager.UserAccount}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", objs); | ||||
|         return result; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -80,7 +80,7 @@ public class StringToEncodingConverter : IConverter<string> | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             source = target.ToJson(); | ||||
|             source = target.ToJsonString(); | ||||
|             return true; | ||||
|         } | ||||
|         catch (Exception) | ||||
|   | ||||
| @@ -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)) | ||||
|         { | ||||
|             //执行脚本,获取新实体 | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -36,6 +36,10 @@ public abstract class CollectBase : DriverBase | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public abstract bool IsSupportRequest { get; } | ||||
|     /// <summary> | ||||
|     /// 一般底层驱动,也有可能为null | ||||
|     /// </summary> | ||||
|     protected abstract IReadWriteDevice PLC { get; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 数据转换器 | ||||
| @@ -98,9 +102,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(); | ||||
| @@ -153,7 +157,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); | ||||
| @@ -177,10 +181,22 @@ public abstract class CollectBase : DriverBase | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入变量值 | ||||
|     /// 批量写入变量值,需返回变量名称/结果 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public abstract Task<OperResult> WriteValueAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token); | ||||
|     public virtual async Task<Dictionary<string, OperResult>> WriteValuesAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token) | ||||
|     { | ||||
|         if (PLC == null) | ||||
|             throw new("未初始化成功"); | ||||
|         Dictionary<string, OperResult> operResults = new(); | ||||
|         foreach (var writeInfo in writeInfoLists) | ||||
|         { | ||||
|             var result = await PLC.WriteAsync(writeInfo.Key.VariableAddress, writeInfo.Key.DataType, writeInfo.Value.ToString(), token); | ||||
|             await Task.Delay(10, token); //防止密集写入 | ||||
|             operResults.Add(writeInfo.Key.Name, result); | ||||
|         } | ||||
|         return operResults; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 初始化 | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
| @@ -48,92 +49,172 @@ public class RpcSingletonService : ISingleton | ||||
|     /// 反向RPC入口方法 | ||||
|     /// </summary> | ||||
|     /// <param name="sourceDes">触发该方法的源说明</param> | ||||
|     /// <param name="item">指定键为变量名称,值为附带方法参数或写入值</param> | ||||
|     /// <param name="items">指定键为变量名称,值为附带方法参数或写入值</param> | ||||
|     /// <param name="isBlazor">如果是true,不检查<see cref="MemoryVariable.RpcWriteEnable"/>字段</param> | ||||
|     /// <param name="token"><see cref="CancellationToken"/> 取消源</param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> InvokeDeviceMethodAsync(string sourceDes, KeyValuePair<string, string> item, bool isBlazor = false, CancellationToken token = default) | ||||
|     public async Task<Dictionary<string, OperResult>> InvokeDeviceMethodAsync(string sourceDes, Dictionary<string, string> items, bool isBlazor = false, CancellationToken token = default) | ||||
|     { | ||||
|         //避免并发过高,这里延时10ms | ||||
|         await Task.Delay(10, token); | ||||
|         OperResult data = new(); | ||||
|         var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key); | ||||
|         if (tag == null) return new OperResult("不存在变量:" + item.Key); | ||||
|         if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly) return new OperResult("只读变量"); | ||||
|         if (!tag.RpcWriteEnable && !isBlazor) return new OperResult("不允许远程写入"); | ||||
|  | ||||
|         if (tag.IsMemoryVariable == true) | ||||
|         Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, JToken>> WriteVariables = new(); | ||||
|         Dictionary<CollectDeviceCore, Dictionary<DeviceVariableRunTime, string>> WriteMethods = new(); | ||||
|         Dictionary<string, OperResult> results = new(); | ||||
|         foreach (var item in items) | ||||
|         { | ||||
|             return tag.SetValue(item.Value); | ||||
|         } | ||||
|         var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId); | ||||
|         if (dev == null) return new OperResult("系统错误,不存在对应采集设备,请稍候重试"); | ||||
|         if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine) return new OperResult("设备已离线"); | ||||
|         if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause) return new OperResult("设备已暂停"); | ||||
|         if (string.IsNullOrEmpty(tag.OtherMethod)) | ||||
|         { | ||||
|             //写入变量 | ||||
|             JToken tagValue; | ||||
|             try | ||||
|             { | ||||
|                 tagValue = JToken.Parse(item.Value); | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 tagValue = JToken.Parse("\"" + item.Value + "\""); | ||||
|             } | ||||
|  | ||||
|             data = await dev.InVokeWriteAsync(tag, tagValue, token); | ||||
|             _logQueues.Enqueue( | ||||
|                 new RpcLog() | ||||
|             OperResult data = new(); | ||||
|             var tag = _globalDeviceData.AllVariables.FirstOrDefault(it => it.Name == item.Key); | ||||
|             if (tag == null) | ||||
|                 results.Add(item.Key, new("不存在变量:" + item.Key)); | ||||
|             if (tag.ProtectTypeEnum == ProtectTypeEnum.ReadOnly) | ||||
|                 results.Add(item.Key, new("只读变量:" + item.Key)); | ||||
|             if (!tag.RpcWriteEnable && !isBlazor) | ||||
|                 results.Add(item.Key, new("不允许远程写入:" + item.Key)); | ||||
|  | ||||
|             if (tag.IsMemoryVariable == true) | ||||
|             { | ||||
|                 results.Add(item.Key, tag.SetValue(item.Value)); | ||||
|             } | ||||
|             var dev = _collectDeviceHostService.CollectDeviceCores.FirstOrDefault(it => it.Device.Id == tag.DeviceId); | ||||
|             if (dev == null) | ||||
|                 results.Add(item.Key, new OperResult("系统错误,不存在对应采集设备,请稍候重试")); | ||||
|             if (dev.Device.DeviceStatus == DeviceStatusEnum.OffLine) | ||||
|                 results.Add(item.Key, new OperResult("设备已离线")); | ||||
|             if (dev.Device.DeviceStatus == DeviceStatusEnum.Pause) | ||||
|                 results.Add(item.Key, new OperResult("设备已暂停")); | ||||
|  | ||||
|             if (!results.ContainsKey(item.Key)) | ||||
|             { | ||||
|                 if (string.IsNullOrEmpty(tag.OtherMethod)) | ||||
|                 { | ||||
|                     LogTime = SysDateTimeExtensions.CurrentDateTime, | ||||
|                     OperateMessage = data.Exception, | ||||
|                     IsSuccess = data.IsSuccess, | ||||
|                     OperateMethod = WriteVariable, | ||||
|                     OperateObject = tag.Name, | ||||
|                     OperateSource = sourceDes, | ||||
|                     ParamJson = item.Value, | ||||
|                     ResultJson = data.Message | ||||
|                     //写入变量 | ||||
|                     JToken tagValue; | ||||
|                     try | ||||
|                     { | ||||
|                         tagValue = JToken.Parse(item.Value); | ||||
|                     } | ||||
|                     catch (Exception) | ||||
|                     { | ||||
|                         tagValue = JToken.Parse("\"" + item.Value + "\""); | ||||
|                     } | ||||
|                     if (WriteVariables.ContainsKey(dev)) | ||||
|                     { | ||||
|  | ||||
|                         WriteVariables[dev].Add(tag, tagValue); | ||||
|  | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         WriteVariables.Add(dev, new()); | ||||
|                         WriteVariables[dev].Add(tag, tagValue); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if (WriteMethods.ContainsKey(dev)) | ||||
|                     { | ||||
|  | ||||
|                         WriteMethods[dev].Add(tag, item.Value); | ||||
|  | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         WriteVariables.Add(dev, new()); | ||||
|                         WriteVariables[dev].Add(tag, item.Value); | ||||
|                     } | ||||
|                 } | ||||
|                 ); | ||||
|             if (!data.IsSuccess) | ||||
|             { | ||||
|                 _logger.LogWarning($"写入变量[{tag.Name}]失败:{data.Message}"); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|  | ||||
|         foreach (var item in WriteVariables) | ||||
|         { | ||||
|             //执行变量附带的方法 | ||||
|             var method = dev.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == tag); | ||||
|             try | ||||
|             { | ||||
|                 data = await dev.InvokeMethodAsync(method, false, item.Value, token); | ||||
|                 var result = await item.Key.InVokeWriteAsync(item.Value, token); | ||||
|                 foreach (var resultItem in result) | ||||
|                 { | ||||
|                     string operObj; | ||||
|                     string parJson; | ||||
|                     if (resultItem.Key.IsNullOrEmpty()) | ||||
|                     { | ||||
|                         operObj = items.Select(x => x.Key).ToJsonString(); | ||||
|                         parJson = items.Select(x => x.Value).ToJsonString(); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         operObj = resultItem.Key; | ||||
|                         parJson = items[resultItem.Key]; | ||||
|  | ||||
|                     } | ||||
|                     _logQueues.Enqueue( | ||||
|           new RpcLog() | ||||
|           { | ||||
|               LogTime = SysDateTimeExtensions.CurrentDateTime, | ||||
|               OperateMessage = resultItem.Value.Exception, | ||||
|               IsSuccess = resultItem.Value.IsSuccess, | ||||
|               OperateMethod = WriteVariable, | ||||
|               OperateObject = operObj, | ||||
|               OperateSource = sourceDes, | ||||
|               ParamJson = parJson, | ||||
|               ResultJson = resultItem.Value.Message | ||||
|           } | ||||
|           ); | ||||
|                     if (!resultItem.Value.IsSuccess) | ||||
|                     { | ||||
|                         _logger.LogWarning($"写入变量[{resultItem.Key}]失败:{resultItem.Value.Message}"); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 results.AddRange(result); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 data = new OperResult<string>(ex); | ||||
|             } | ||||
|             _logQueues.Enqueue( | ||||
| new RpcLog() | ||||
| { | ||||
|     LogTime = SysDateTimeExtensions.CurrentDateTime, | ||||
|     OperateMessage = data.Exception, | ||||
|     IsSuccess = data.IsSuccess, | ||||
|     OperateMethod = tag.OtherMethod, | ||||
|     OperateObject = tag.Name, | ||||
|     OperateSource = sourceDes, | ||||
|     ParamJson = item.Value?.ToString(), | ||||
|     ResultJson = data.Message | ||||
| } | ||||
| ); | ||||
|             if (!data.IsSuccess) | ||||
|             { | ||||
|                 _logger.LogWarning($"执行变量[{tag.Name}]方法[{tag.OtherMethod}]失败:{data.Message}"); | ||||
|                 _logger.LogWarning($"写入变量异常:{ex.Message + Environment.NewLine + ex.StackTrace}"); | ||||
|             } | ||||
|         } | ||||
|         return data; | ||||
|         foreach (var item in WriteMethods) | ||||
|         { | ||||
|             foreach (var writeMethod in item.Value) | ||||
|             { | ||||
|  | ||||
|                 //执行变量附带的方法 | ||||
|                 var method = item.Key.DeviceVariableMethodSources.FirstOrDefault(it => it.DeviceVariable == writeMethod.Key); | ||||
|                 OperResult<string> result; | ||||
|                 try | ||||
|                 { | ||||
|                     result = await item.Key.InvokeMethodAsync(method, false, writeMethod.Value, token); | ||||
|                     results.Add(writeMethod.Key.Name, result); | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     result = new OperResult<string>(ex); | ||||
|                     results.Add(writeMethod.Key.Name, result); | ||||
|                 } | ||||
|                 _logQueues.Enqueue( | ||||
|     new RpcLog() | ||||
|     { | ||||
|         LogTime = SysDateTimeExtensions.CurrentDateTime, | ||||
|         OperateMessage = result.Exception, | ||||
|         IsSuccess = result.IsSuccess, | ||||
|         OperateMethod = writeMethod.Key.OtherMethod, | ||||
|         OperateObject = writeMethod.Key.Name, | ||||
|         OperateSource = sourceDes, | ||||
|         ParamJson = writeMethod.Value?.ToString(), | ||||
|         ResultJson = result.Message | ||||
|     } | ||||
|     ); | ||||
|                 if (!result.IsSuccess) | ||||
|                 { | ||||
|                     _logger.LogWarning($"执行变量[{writeMethod.Key.Name}]方法[{writeMethod.Key.OtherMethod}]失败:{result.Message}"); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     private async Task RpcLogInsertAsync() | ||||
|     { | ||||
|   | ||||
| @@ -319,6 +319,39 @@ | ||||
|       "UpdateUserId": null, | ||||
|       "SortCode": 0, | ||||
|       "ExtJson": null | ||||
|     }, | ||||
|  | ||||
|     { | ||||
|       "Id": 442505, | ||||
|       "FileName": "ThingsGateway.DLT645", | ||||
|       "AssembleName": "DLT645_2007", | ||||
|       "DriverTypeEnum": "Collect", | ||||
|       "FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll", | ||||
|       "CreateTime": "2023/8/6 18:22:33", | ||||
|       "CreateUser": "superAdmin", | ||||
|       "CreateUserId": 212725263002001, | ||||
|       "IsDelete": 0, | ||||
|       "UpdateTime": null, | ||||
|       "UpdateUser": null, | ||||
|       "UpdateUserId": null, | ||||
|       "SortCode": 0, | ||||
|       "ExtJson": null | ||||
|     }, | ||||
|     { | ||||
|       "Id": 442506, | ||||
|       "FileName": "ThingsGateway.DLT645", | ||||
|       "AssembleName": "DLT645_2007OverTcp", | ||||
|       "DriverTypeEnum": "Collect", | ||||
|       "FilePath": "Plugins/ThingsGateway.DLT645/ThingsGateway.DLT645.dll", | ||||
|       "CreateTime": "2023/8/6 18:22:33", | ||||
|       "CreateUser": "superAdmin", | ||||
|       "CreateUserId": 212725263002001, | ||||
|       "IsDelete": 0, | ||||
|       "UpdateTime": null, | ||||
|       "UpdateUser": null, | ||||
|       "UpdateUserId": null, | ||||
|       "SortCode": 0, | ||||
|       "ExtJson": null | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| @@ -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++) | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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)); | ||||
|   | ||||
| @@ -37,7 +37,7 @@ | ||||
| 		<PackageReference Include="Hardware.Info" Version="11.1.1.1" /> | ||||
| 		<PackageReference Include="CS-Script" Version="4.8.1" /> | ||||
| 		<!--CS-Script与Furion冲突,直接安装覆盖版本--> | ||||
| 		<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" /> | ||||
| 		<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.7.0" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
|   | ||||
| @@ -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> | ||||
| @@ -1855,6 +1856,11 @@ | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Application.CollectBase.PLC"> | ||||
|             <summary> | ||||
|             一般底层驱动,也有可能为null | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Application.CollectBase.ThingsGatewayBitConverter"> | ||||
|             <summary> | ||||
|             数据转换器 | ||||
| @@ -1906,9 +1912,9 @@ | ||||
|             采集驱动读取 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Application.CollectBase.WriteValueAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)"> | ||||
|         <member name="M:ThingsGateway.Application.CollectBase.WriteValuesAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             写入变量值 | ||||
|             批量写入变量值,需返回变量名称/结果 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
| @@ -2242,12 +2248,12 @@ | ||||
|         <member name="M:ThingsGateway.Application.RpcSingletonService.#ctor(Microsoft.Extensions.Logging.ILogger{ThingsGateway.Application.RpcSingletonService})"> | ||||
|             <inheritdoc cref="T:ThingsGateway.Application.RpcSingletonService"/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.KeyValuePair{System.String,System.String},System.Boolean,System.Threading.CancellationToken)"> | ||||
|         <member name="M:ThingsGateway.Application.RpcSingletonService.InvokeDeviceMethodAsync(System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.Boolean,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             反向RPC入口方法 | ||||
|             </summary> | ||||
|             <param name="sourceDes">触发该方法的源说明</param> | ||||
|             <param name="item">指定键为变量名称,值为附带方法参数或写入值</param> | ||||
|             <param name="items">指定键为变量名称,值为附带方法参数或写入值</param> | ||||
|             <param name="isBlazor">如果是true,不检查<see cref="P:ThingsGateway.Application.MemoryVariable.RpcWriteEnable"/>字段</param> | ||||
|             <param name="token"><see cref="T:System.Threading.CancellationToken"/> 取消源</param> | ||||
|             <returns></returns> | ||||
| @@ -2577,6 +2583,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> | ||||
|             日志源 | ||||
| @@ -2607,6 +2623,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> | ||||
|             操作源 | ||||
| @@ -3505,7 +3531,7 @@ | ||||
|             执行特殊方法 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken,System.Threading.CancellationToken)"> | ||||
|         <member name="M:ThingsGateway.Application.CollectDeviceCore.InVokeWriteAsync(System.Collections.Generic.Dictionary{ThingsGateway.Application.DeviceVariableRunTime,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             执行变量写入 | ||||
|             </summary> | ||||
|   | ||||
| @@ -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); | ||||
|                                     } | ||||
|                                 } | ||||
|  | ||||
|   | ||||
| @@ -330,11 +330,6 @@ public class CollectDeviceCore | ||||
|                 return ThreadRunReturn.Continue; | ||||
|             } | ||||
|  | ||||
|             if (DeviceVariableSourceReads.Count == 0 && Device.DeviceVariableRunTimes.Where(a => string.IsNullOrEmpty(a.OtherMethod)).Any()) | ||||
|             { | ||||
|                 //无采集变量 | ||||
|                 return ThreadRunReturn.Continue; | ||||
|             } | ||||
|             if (token.IsCancellationRequested) | ||||
|                 return ThreadRunReturn.Break; | ||||
|  | ||||
| @@ -398,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 | ||||
| @@ -438,11 +433,11 @@ public class CollectDeviceCore | ||||
|                 if (_driver.IsConnected()) | ||||
|                 { | ||||
|                     //更新设备活动时间 | ||||
|                     Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 0); | ||||
|                     Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, errorCount: 0); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     Device.SetDeviceStatus(SysDateTimeExtensions.CurrentDateTime, 999); | ||||
|                     Device.SetDeviceStatus(errorCount: 999); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -534,7 +529,7 @@ public class CollectDeviceCore | ||||
|  | ||||
|                         if (!string.IsNullOrEmpty(methodResult.MethodStr)) | ||||
|                         { | ||||
|                             string[] strs = methodResult.MethodStr?.Trim()?.Split(';'); | ||||
|                             string[] strs = methodResult.MethodStr?.Trim()?.TrimEnd(';').Split(';'); | ||||
|                             try | ||||
|                             { | ||||
|                                 int index = 0; | ||||
| @@ -546,6 +541,8 @@ public class CollectDeviceCore | ||||
|                                     } | ||||
|                                     else | ||||
|                                     { | ||||
|                                         if (strs.Length <= index) | ||||
|                                             continue; | ||||
|                                         //得到对于的方法参数值 | ||||
|                                         methodResult.MethodObj[i] = methodResult.Converter.ConvertFrom(strs[index], ps[i].ParameterType); | ||||
|                                         index++; | ||||
| @@ -601,8 +598,8 @@ public class CollectDeviceCore | ||||
|  | ||||
|                     if (!string.IsNullOrEmpty(deviceVariableMethodSource.MethodStr) || !string.IsNullOrEmpty(value)) | ||||
|                     { | ||||
|                         string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.Split(';'); | ||||
|                         string[] strs2 = value?.Trim()?.Split(';'); | ||||
|                         string[] strs1 = deviceVariableMethodSource.MethodStr?.Trim()?.TrimEnd(';').Split(';'); | ||||
|                         string[] strs2 = value?.Trim()?.TrimEnd(';').Split(';'); | ||||
|                         //通过分号分割,并且合并参数 | ||||
|                         var strs = strs1?.SpliceArray(strs2); | ||||
|                         int index = 0; | ||||
| @@ -668,18 +665,25 @@ public class CollectDeviceCore | ||||
|                     if (method.HasReturn && result != null && result.IsSuccess) | ||||
|                     { | ||||
|                         var content = deviceVariableMethodSource.Converter.ConvertTo(result.Content?.ToString()?.Replace($"\0", "")); | ||||
|                         var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content); | ||||
|                         if (!operResult.IsSuccess) | ||||
|                         if (isRead) | ||||
|                         { | ||||
|                             _logger?.LogWarning(operResult.Message, ToString()); | ||||
|                             var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(content); | ||||
|                             if (!operResult.IsSuccess) | ||||
|                             { | ||||
|                                 _logger?.LogWarning(operResult.Message, ToString()); | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null); | ||||
|                         if (!operResult.IsSuccess) | ||||
|                         if (isRead&& !result.IsSuccess) | ||||
|                         { | ||||
|                             _logger?.LogWarning(operResult.Message, ToString()); | ||||
|                             var operResult = deviceVariableMethodSource.DeviceVariable.SetValue(null,isOnline: false); | ||||
|                             if (!operResult.IsSuccess) | ||||
|                             { | ||||
|                                 _logger?.LogWarning(operResult.Message, ToString()); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     return result; | ||||
| @@ -708,46 +712,46 @@ public class CollectDeviceCore | ||||
|     /// 执行变量写入 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     internal async Task<OperResult> InVokeWriteAsync(DeviceVariableRunTime deviceVariable, JToken value, CancellationToken token) | ||||
|     internal async Task<Dictionary<string, OperResult>> InVokeWriteAsync(Dictionary<DeviceVariableRunTime, JToken> writeInfoLists, CancellationToken token) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await easyLock.WaitAsync(); | ||||
|             if (IsShareChannel) _driver.InitDataAdapter(); | ||||
|             Dictionary<string, OperResult> results = new(); | ||||
|             foreach (var deviceVariable in writeInfoLists.Keys) | ||||
|             { | ||||
|                 if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions)) | ||||
|                 { | ||||
|                     var jToken = writeInfoLists[deviceVariable]; | ||||
|                     object rawdata; | ||||
|                     if (jToken is JValue jValue) | ||||
|                     { | ||||
|                         rawdata = jValue.Value; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         rawdata = jToken.ToString(); | ||||
|                     } | ||||
|                     object data; | ||||
|                     try | ||||
|                     { | ||||
|                         data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata); | ||||
|                         writeInfoLists[deviceVariable] = JToken.FromObject(data); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         results.Add(deviceVariable.Name, new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message)); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             if (!string.IsNullOrEmpty(deviceVariable.WriteExpressions)) | ||||
|             { | ||||
|                 var jToken = value; | ||||
|                 object rawdata; | ||||
|                 if (jToken is JValue jValue) | ||||
|                 { | ||||
|                     rawdata = jValue.Value; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     rawdata = jToken.ToString(); | ||||
|                 } | ||||
|                 object data; | ||||
|                 try | ||||
|                 { | ||||
|                     data = deviceVariable.WriteExpressions.GetExpressionsResult(rawdata); | ||||
|                     var result = await _driver.WriteValueAsync(deviceVariable, JToken.FromObject(data), token); | ||||
|                     return result; | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     return new OperResult(deviceVariable.Name + " 转换写入表达式失败:" + ex.Message); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var result = await _driver.WriteValueAsync(deviceVariable, value, token); | ||||
|                 return result; | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return (new OperResult(ex)); | ||||
|             var result = await _driver.WriteValuesAsync(writeInfoLists. | ||||
|                 Where(a => !results.Any(b => b.Key == a.Key.Name)). | ||||
|                ToDictionary(item => item.Key, item => item.Value), | ||||
|                 token); | ||||
|  | ||||
|             return result; | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
| @@ -755,6 +759,8 @@ public class CollectDeviceCore | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 执行轮询特殊方法,并设置变量值 | ||||
|     /// </summary> | ||||
|   | ||||
| @@ -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); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -21,7 +21,7 @@ using ThingsGateway.Application; | ||||
|  | ||||
| namespace ThingsGateway.Blazor; | ||||
| /// <summary> | ||||
| /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>excel | ||||
| /// 导入excel | ||||
| /// </summary> | ||||
| public partial class ImportExcel | ||||
| { | ||||
| @@ -33,21 +33,21 @@ public partial class ImportExcel | ||||
|  | ||||
|     bool isSaveImport; | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 导入 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public Func<Dictionary<string, ImportPreviewOutputBase>, Task> Import { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>ʾ | ||||
|     /// 是否显示 | ||||
|     /// </summary> | ||||
|     public bool IsShowImport { get; set; } | ||||
|     /// <summary> | ||||
|     /// Ԥ<EFBFBD><EFBFBD> | ||||
|     /// 预览 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public Func<IBrowserFile, Task<Dictionary<string, ImportPreviewOutputBase>>> Preview { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 当前步数 | ||||
|     /// </summary> | ||||
|     public int Step { get; set; } | ||||
|  | ||||
| @@ -75,7 +75,7 @@ public partial class ImportExcel | ||||
|             StateHasChanged(); | ||||
|             await Import.Invoke(ImportPreviews); | ||||
|             _importFile = null; | ||||
|             await PopupService.EnqueueSnackbarAsync("<EFBFBD>ɹ<EFBFBD>", AlertTypes.Success); | ||||
|             await PopupService.EnqueueSnackbarAsync("成功", AlertTypes.Success); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -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> | ||||
| @@ -54,7 +54,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase | ||||
|     /// </summary> | ||||
|     public UdpSessionPage UdpSessionPage; | ||||
|     /// <summary> | ||||
|     /// ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>1-TCPCLIENT<EFBFBD><EFBFBD>2-<2D><><EFBFBD>ڣ<EFBFBD>3-UDP<EFBFBD><EFBFBD>4-TCPServer | ||||
|     /// 选择,1-TCPCLIENT,2-串口,3-UDP,4-TCPServer | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public ChannelEnum Channel { get; set; } | ||||
| @@ -65,12 +65,12 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase | ||||
|     public override ThingsGateway.Foundation.IReadWriteDevice Plc { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// ģ<EFBFBD><EFBFBD> | ||||
|     /// 模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment ChildContent { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD> | ||||
|     /// 自定义模板 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public RenderFragment OtherContent { get; set; } | ||||
| @@ -79,7 +79,7 @@ public partial class DefalutDebugDriverPage : DriverDebugUIBase | ||||
|     { | ||||
|         Plc?.SafeDispose(); | ||||
|         TcpClientPage?.SafeDispose(); | ||||
|         SerialClientPage?.SafeDispose(); | ||||
|         SerialSessionPage?.SafeDispose(); | ||||
|         TcpServerPage?.SafeDispose(); | ||||
|         UdpSessionPage?.SafeDispose(); | ||||
|         base.Dispose(); | ||||
| @@ -94,13 +94,13 @@ 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) | ||||
|                 UdpSessionPage.LogAction = LogOut; | ||||
|             //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|             //载入配置 | ||||
|             StateHasChanged(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
| 
 | ||||
| @@ -17,10 +17,10 @@ using TouchSocket.Core; | ||||
| namespace ThingsGateway.Blazor; | ||||
| 
 | ||||
| /// <inheritdoc/> | ||||
| public partial class SerialClientPage | ||||
| public partial class SerialSessionPage | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 日志输出 | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
| 
 | ||||
| @@ -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(); | ||||
| @@ -47,16 +47,16 @@ public partial class SerialClientPage | ||||
|         LogMessage.AddLogger(new EasyLogger(LogOut) { LogLevel = TouchSocket.Core.LogLevel.Trace }); | ||||
|         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(); | ||||
|     } | ||||
| 
 | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -23,7 +23,7 @@ namespace ThingsGateway.Blazor; | ||||
| public partial class TcpClientPage | ||||
| { | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
|  | ||||
| @@ -33,7 +33,7 @@ public partial class TcpClientPage | ||||
|     /// </summary> | ||||
|     private string IP = "127.0.0.1"; | ||||
|     /// <summary> | ||||
|     /// <EFBFBD>˿<EFBFBD> | ||||
|     /// 端口 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     public int Port { get; set; } = 502; | ||||
| @@ -73,7 +73,7 @@ public partial class TcpClientPage | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public TcpClientEx GetTcpClient() | ||||
| @@ -82,8 +82,8 @@ 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); | ||||
|         //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|         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(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor; | ||||
| public partial class TcpServerPage | ||||
| { | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
|  | ||||
| @@ -62,7 +62,7 @@ public partial class TcpServerPage | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public TcpService GetTcpServer() | ||||
| @@ -72,8 +72,7 @@ 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); | ||||
|         //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|         //载入配置 | ||||
|         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(); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -19,7 +19,7 @@ namespace ThingsGateway.Blazor; | ||||
| public partial class UdpSessionPage : IDisposable | ||||
| { | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 日志输出 | ||||
|     /// </summary> | ||||
|     public Action<LogLevel, object, string, Exception> LogAction; | ||||
|  | ||||
| @@ -62,7 +62,7 @@ public partial class UdpSessionPage : IDisposable | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 获取对象 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     public UdpSession GetUdpSession() | ||||
| @@ -71,9 +71,9 @@ 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)); | ||||
|         //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|         //载入配置 | ||||
|         UdpSession.Setup(config); | ||||
|         return UdpSession; | ||||
|     } | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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("删除", "确定 ?"); | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -32,7 +32,7 @@ using ThingsGateway.Application; | ||||
| namespace ThingsGateway.Blazor; | ||||
|  | ||||
| /// <summary> | ||||
| /// <EFBFBD>豸״̬ҳ<EFBFBD><EFBFBD> | ||||
| /// 设备状态页面 | ||||
| /// </summary> | ||||
| public partial class DeviceStatusPage : IDisposable | ||||
| { | ||||
| @@ -110,7 +110,7 @@ public partial class DeviceStatusPage : IDisposable | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?"); | ||||
|             var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?"); | ||||
|             if (confirm) | ||||
|             { | ||||
|                 isAllRestart = true; | ||||
| @@ -142,8 +142,8 @@ public partial class DeviceStatusPage : IDisposable | ||||
|     } | ||||
|     async Task ConfigAsync(long devId, bool? isStart) | ||||
|     { | ||||
|         var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ"; | ||||
|         var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?"); | ||||
|         var str = isStart == true ? "启动" : "暂停"; | ||||
|         var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?"); | ||||
|         if (confirm) | ||||
|         { | ||||
|             CollectDeviceHostService.ConfigDeviceThread(devId, isStart == true); | ||||
| @@ -167,19 +167,19 @@ public partial class DeviceStatusPage : IDisposable | ||||
|             memoryStream.Seek(0, SeekOrigin.Begin); | ||||
|             using var streamRef = new DotNetStreamReference(stream: memoryStream); | ||||
|             Helper ??= await JS.InvokeAsync<IJSObjectReference>("import", $"/_content/ThingsGateway.Admin.Blazor.Core/js/downloadFileFromStream.js"); | ||||
|             await Helper.InvokeVoidAsync("downloadFileFromStream", $"<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef); | ||||
|             await Helper.InvokeVoidAsync("downloadFileFromStream", $"报文导出{SysDateTimeExtensions.CurrentDateTime.ToFileDateTimeFormat()}.txt", streamRef); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             isDownExport = false; | ||||
|         } | ||||
|     } | ||||
|     //ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     //去除单个采集重启 | ||||
|     //async Task RestartAsync(long devId) | ||||
|     //{ | ||||
|     //    try | ||||
|     //    { | ||||
|     //        var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?"); | ||||
|     //        var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?"); | ||||
|     //        if (confirm) | ||||
|     //        { | ||||
|     //            isRestart = true; | ||||
| @@ -231,8 +231,8 @@ public partial class DeviceStatusPage : IDisposable | ||||
|  | ||||
|     async Task UpConfigAsync(long devId, bool? isStart) | ||||
|     { | ||||
|         var str = isStart == true ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>ͣ"; | ||||
|         var confirm = await PopupService.OpenConfirmDialogAsync(str, $"ȷ<EFBFBD><EFBFBD>{str}?"); | ||||
|         var str = isStart == true ? "启动" : "暂停"; | ||||
|         var confirm = await PopupService.OpenConfirmDialogAsync(str, $"确定{str}?"); | ||||
|         if (confirm) | ||||
|         { | ||||
|             UploadDeviceHostService.ConfigDeviceThread(devId, isStart == true); | ||||
| @@ -253,7 +253,7 @@ public partial class DeviceStatusPage : IDisposable | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             var confirm = await PopupService.OpenConfirmDialogAsync("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?"); | ||||
|             var confirm = await PopupService.OpenConfirmDialogAsync("重启", "确定重启?"); | ||||
|             if (confirm) | ||||
|             { | ||||
|                 isRestart = true; | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -28,7 +28,7 @@ using ThingsGateway.Application; | ||||
|  | ||||
| namespace ThingsGateway.Blazor; | ||||
| /// <summary> | ||||
| /// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ | ||||
| /// 实时数据页 | ||||
| /// </summary> | ||||
| public partial class DeviceVariableRunTimePage | ||||
| { | ||||
| @@ -37,13 +37,13 @@ public partial class DeviceVariableRunTimePage | ||||
|     List<DeviceTree> _deviceGroups = new(); | ||||
|     string _searchName; | ||||
|     /// <summary> | ||||
|     /// <EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 设备名称 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     [SupplyParameterFromQuery] | ||||
|     public string DeviceName { get; set; } | ||||
|     /// <summary> | ||||
|     /// <EFBFBD>ϴ<EFBFBD><EFBFBD>豸<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
|     /// 上传设备名称 | ||||
|     /// </summary> | ||||
|     [Parameter] | ||||
|     [SupplyParameterFromQuery] | ||||
| @@ -149,15 +149,23 @@ public partial class DeviceVariableRunTimePage | ||||
|     private EventCallback<string> WriteValueAsync; | ||||
|     private async Task OnWriteValueAsync(DeviceVariableRunTime tag, string value) | ||||
|     { | ||||
|         var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", new KeyValuePair<string, string>(tag.Name, value), true); | ||||
|         if (!data.IsSuccess) | ||||
|         var data = await RpcCore?.InvokeDeviceMethodAsync($"BLAZOR-{UserResoures.CurrentUser.Account}-{App.HttpContext.Connection.RemoteIpAddress.MapToIPv4()}", | ||||
|  | ||||
|             new Dictionary<string, string>() | ||||
|             { | ||||
|  | ||||
|                 { tag.Name, value} | ||||
|             } | ||||
|  | ||||
|             , true); | ||||
|         if (data.Count > 0 && !data.FirstOrDefault().Value.IsSuccess) | ||||
|         { | ||||
|             throw new(data.Message); | ||||
|             throw new(data.FirstOrDefault().Value.Message); | ||||
|         } | ||||
|     } | ||||
|     private async Task WriteAsync(DeviceVariableRunTime collectVariableRunTime) | ||||
|     { | ||||
|         // <EFBFBD><EFBFBD><EFBFBD>첽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD> | ||||
|         // 将异步方法添加到事件回调上 | ||||
|         WriteValueAsync = EventCallback.Factory.Create<string>(this, value => OnWriteValueAsync(collectVariableRunTime, value)); | ||||
|         await PopupService.OpenAsync(typeof(WriteValue), new Dictionary<string, object>() | ||||
|         { | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -19,7 +19,7 @@ using ThingsGateway.Application; | ||||
| namespace ThingsGateway.Blazor; | ||||
|  | ||||
| /// <summary> | ||||
| /// Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣҳ<EFBFBD><EFBFBD> | ||||
| /// 硬件信息页面 | ||||
| /// </summary> | ||||
| public partial class HardwareInfoPage | ||||
| { | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -25,7 +25,7 @@ using ThingsGateway.Application; | ||||
| namespace ThingsGateway.Blazor; | ||||
|  | ||||
| /// <summary> | ||||
| /// <EFBFBD><EFBFBD>ʷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD> | ||||
| /// 历史报警页面 | ||||
| /// </summary> | ||||
| public partial class HistoryAlarmPage | ||||
| { | ||||
| @@ -75,7 +75,7 @@ public partial class HistoryAlarmPage | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning)); | ||||
|                     await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning)); | ||||
|                     return new() | ||||
|                     { | ||||
|                         Current = 1, | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -23,7 +23,7 @@ using ThingsGateway.Application; | ||||
|  | ||||
| namespace ThingsGateway.Blazor; | ||||
| /// <summary> | ||||
| /// ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD> | ||||
| /// 时序库页面 | ||||
| /// </summary> | ||||
| public partial class HistoryValuePage | ||||
| { | ||||
| @@ -74,7 +74,7 @@ public partial class HistoryValuePage | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("<EFBFBD><EFBFBD>ѯʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>" + ex.Message, AlertTypes.Warning)); | ||||
|                 await InvokeAsync(async () => await PopupService.EnqueueSnackbarAsync("查询失败,请检查网络连接:" + ex.Message, AlertTypes.Warning)); | ||||
|                 return new() | ||||
|                 { | ||||
|                     Current = 1, | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| #region copyright | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊȫ<EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  <EFBFBD>˴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD>룩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD><EFBFBD>Diego<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| //  Դ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><EFBFBD>Ŀ<EFBFBD>ԴЭ<EFBFBD>鼰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD> | ||||
| //  GiteeԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://gitee.com/diego2098/ThingsGateway | ||||
| //  GithubԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֿ⣺https://github.com/kimdiego2098/ThingsGateway | ||||
| //  ʹ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQȺ<EFBFBD><EFBFBD>605534569 | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| @@ -22,7 +22,7 @@ using ThingsGateway.Application; | ||||
|  | ||||
| namespace ThingsGateway.Blazor; | ||||
| /// <summary> | ||||
| /// ʵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | ||||
| /// 实时报警 | ||||
| /// </summary> | ||||
| public partial class RealAlarmPage | ||||
| { | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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("删除", "确定 ?"); | ||||
|   | ||||
| @@ -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"> | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
|   | ||||
| @@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation; | ||||
| /// <summary> | ||||
| /// 自增 | ||||
| /// </summary> | ||||
| public sealed class EasyIncrementCount : DisposableObject | ||||
| public sealed class EasyIncrementCount : IDisposable | ||||
| { | ||||
|     private long current = 0; | ||||
|     private readonly EasyLock easyLock; | ||||
| @@ -30,6 +30,11 @@ public sealed class EasyIncrementCount : DisposableObject | ||||
|         IncreaseTick = tick; | ||||
|         easyLock = new EasyLock(); | ||||
|     } | ||||
|     /// <inheritdoc cref="EasyIncrementCount"/> | ||||
|     ~EasyIncrementCount() | ||||
|     { | ||||
|         easyLock.SafeDispose(); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Tick | ||||
| @@ -117,10 +122,10 @@ public sealed class EasyIncrementCount : DisposableObject | ||||
|         } | ||||
|         easyLock.Release(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Dispose(bool disposing) | ||||
|     public void Dispose() | ||||
|     { | ||||
|         easyLock.SafeDispose(); | ||||
|         base.Dispose(disposing); | ||||
|     } | ||||
| } | ||||
| @@ -15,11 +15,15 @@ namespace ThingsGateway.Foundation; | ||||
| /// <summary> | ||||
| /// EasyLock,使用轻量级SemaphoreSlim锁,只允许一个并发量,并记录并发信息 | ||||
| /// </summary> | ||||
| public sealed class EasyLock : DisposableObject | ||||
| public sealed class EasyLock : IDisposable | ||||
| { | ||||
|     private static long lockWaitCount; | ||||
|     private readonly Lazy<SemaphoreSlim> m_waiterLock = new(() => new SemaphoreSlim(1)); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     ~EasyLock() | ||||
|     { | ||||
|         m_waiterLock.Value.SafeDispose(); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 当前正在等待的数量 | ||||
|     /// </summary> | ||||
| @@ -28,6 +32,13 @@ public sealed class EasyLock : DisposableObject | ||||
|     /// 当前锁是否在等待当中 | ||||
|     /// </summary> | ||||
|     public bool IsWaitting => m_waiterLock.Value.CurrentCount == 0; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         m_waiterLock.Value.SafeDispose(); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 离开锁 | ||||
|     /// </summary> | ||||
| @@ -73,10 +84,5 @@ public sealed class EasyLock : DisposableObject | ||||
|         await m_waiterLock.Value.WaitAsync(timeSpan, token); | ||||
|         Interlocked.Decrement(ref lockWaitCount); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Dispose(bool disposing) | ||||
|     { | ||||
|         m_waiterLock.Value.SafeDispose(); | ||||
|         base.Dispose(disposing); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -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(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -325,28 +329,32 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient | ||||
|     /// <param name="disposing"></param> | ||||
|     protected override void Dispose(bool disposing) | ||||
|     { | ||||
|         try | ||||
|         if (!DisposedValue) | ||||
|         { | ||||
|             privateEasyLock.Wait(); | ||||
|             if (this.m_online) | ||||
|             try | ||||
|             { | ||||
|                 this.m_online = false; | ||||
|                 this.MainSocket.TryClose(); | ||||
|                 this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|  | ||||
|                 this.MainSocket.SafeDispose(); | ||||
|                 this.m_delaySender.SafeDispose(); | ||||
|                 this.m_workStream.SafeDispose(); | ||||
|                 this.DataHandlingAdapter.SafeDispose(); | ||||
|                 this.PluginsManager.SafeDispose(); | ||||
|                 this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                 EasyLock.Wait(); | ||||
|                 if (this.m_online) | ||||
|                 { | ||||
|                     this.m_online = false; | ||||
|                     this.MainSocket.TryClose(); | ||||
|                     this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|  | ||||
|                     this.MainSocket.SafeDispose(); | ||||
|                     this.m_delaySender.SafeDispose(); | ||||
|                     this.m_workStream.SafeDispose(); | ||||
|                     this.DataHandlingAdapter.SafeDispose(); | ||||
|                     this.PluginsManager.SafeDispose(); | ||||
|                     this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 EasyLock.Release(); | ||||
|             } | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             privateEasyLock.Release(); | ||||
|         } | ||||
|         privateEasyLock.SafeDispose(); | ||||
|         EasyLock.SafeDispose(); | ||||
|  | ||||
|         base.Dispose(disposing); | ||||
|     } | ||||
| @@ -354,7 +362,6 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient | ||||
|     #endregion 断开操作 | ||||
|  | ||||
|     #region Connect | ||||
|     private EasyLock privateEasyLock { get; set; } = new(); | ||||
|     /// <summary> | ||||
|     /// 建立Tcp的连接。 | ||||
|     /// </summary> | ||||
| @@ -367,7 +374,7 @@ public class TcpClientBaseEx : BaseSocket, ITcpClient | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             privateEasyLock.Wait(); | ||||
|             EasyLock.Wait(); | ||||
|             if (this.m_online) | ||||
|             { | ||||
|                 return; | ||||
| @@ -378,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); | ||||
| @@ -402,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(); | ||||
| @@ -418,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; | ||||
| @@ -455,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 | ||||
|             { | ||||
| @@ -473,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(); | ||||
| @@ -498,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(); | ||||
| @@ -519,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/> | ||||
| @@ -543,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) | ||||
|         { | ||||
| @@ -678,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); | ||||
|     } | ||||
| @@ -699,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) | ||||
| @@ -745,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)) | ||||
| @@ -758,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); | ||||
| @@ -798,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)) | ||||
| @@ -856,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; | ||||
| @@ -957,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); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -1044,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); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -1088,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) | ||||
| @@ -1111,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); | ||||
|  | ||||
|   | ||||
| @@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation; | ||||
| internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClient> where TClient : IClient, IDefaultSender, ISender | ||||
| { | ||||
|     private readonly Func<ResponsedData, bool> m_func; | ||||
|     private readonly SemaphoreSlim m_lock = new(1); | ||||
|     private readonly EasyLock easyLock = new(); | ||||
|     private readonly WaitData<ResponsedData> m_waitData = new WaitData<ResponsedData>(); | ||||
|     private readonly WaitDataAsync<ResponsedData> m_waitDataAsync = new WaitDataAsync<ResponsedData>(); | ||||
|  | ||||
| @@ -55,6 +55,7 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie | ||||
|         this.Client = default; | ||||
|         this.m_waitData.SafeDispose(); | ||||
|         this.m_waitDataAsync.SafeDispose(); | ||||
|         this.easyLock.SafeDispose(); | ||||
|         base.Dispose(disposing); | ||||
|     } | ||||
|  | ||||
| @@ -69,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(); | ||||
| @@ -121,16 +122,16 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             m_lock.Wait(); | ||||
|             easyLock.Wait(); | ||||
|             this.m_breaked = false; | ||||
|             this.Reset(); | ||||
|             if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient) | ||||
|             { | ||||
|                 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) | ||||
|             { | ||||
| @@ -184,14 +185,14 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             m_lock.Release(); | ||||
|             easyLock.Release(); | ||||
|             if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient) | ||||
|             { | ||||
|                 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) | ||||
|             { | ||||
| @@ -224,16 +225,16 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await m_lock.WaitAsync(); | ||||
|             await easyLock.WaitAsync(); | ||||
|             this.m_breaked = false; | ||||
|             this.Reset(); | ||||
|             if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient) | ||||
|             { | ||||
|                 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) | ||||
|             { | ||||
| @@ -287,14 +288,14 @@ internal class WaitingClientEx<TClient> : DisposableObject, IWaitingClient<TClie | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             m_lock.Release(); | ||||
|             easyLock.Release(); | ||||
|             if (this.WaitingOptions.BreakTrigger && this.Client is ITcpClientBase tcpClient) | ||||
|             { | ||||
|                 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) | ||||
|             { | ||||
|   | ||||
| @@ -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 | ||||
|             { | ||||
|   | ||||
| @@ -46,19 +46,6 @@ public static class StringExtensions | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将16进制的字符转换为int32。 | ||||
|     /// </summary> | ||||
|     /// <param name="hexString"></param> | ||||
|     /// <returns></returns> | ||||
|     public static int ByHexStringToInt32(this string hexString) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(hexString)) | ||||
|         { | ||||
|             return default; | ||||
|         } | ||||
|         return int.Parse(hexString, System.Globalization.NumberStyles.HexNumber); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc cref="Path.Combine(string[])"/> | ||||
|     /// 并把\\转为/ | ||||
|   | ||||
| @@ -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; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -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; } | ||||
|  | ||||
| } | ||||
| @@ -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); | ||||
| 
 | ||||
| } | ||||
| @@ -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); | ||||
| } | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
| @@ -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> | ||||
|     /// 是否处于发送状态 | ||||
|   | ||||
| @@ -10,20 +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; | ||||
| using TouchSocket.Sockets; | ||||
| 
 | ||||
| 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> | ||||
|     /// 接收数据 | ||||
| @@ -40,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连接 | ||||
| @@ -89,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> | ||||
| @@ -105,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> | ||||
| @@ -121,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> | ||||
| @@ -140,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; | ||||
| @@ -198,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 断开操作 | ||||
| @@ -255,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> | ||||
| @@ -279,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) | ||||
|         { | ||||
| @@ -338,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) | ||||
|         { | ||||
| @@ -384,7 +433,7 @@ public class SerialClientBase : BaseSerial, ISerialClient | ||||
|     } | ||||
| 
 | ||||
|     /// <inheritdoc/> | ||||
|     public ISerialClient Setup(TouchSocketConfig config) | ||||
|     public ISerialSession Setup(TouchSocketConfig config) | ||||
|     { | ||||
|         if (config == null) | ||||
|         { | ||||
| @@ -402,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; | ||||
| @@ -537,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) | ||||
| @@ -553,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) | ||||
| @@ -566,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> | ||||
| @@ -574,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; | ||||
| @@ -604,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 同步发送 | ||||
| @@ -772,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); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -804,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; | ||||
|     } | ||||
| } | ||||
| @@ -1,7 +1,7 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net45;net6.0;net7.0</TargetFrameworks> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks> | ||||
| 		<OpenApiGenerateDocuments>false</OpenApiGenerateDocuments> | ||||
| 		<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||||
| 		<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> | ||||
| @@ -13,7 +13,7 @@ | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> | ||||
| 		<PackageReference Include="TouchSocket" Version="2.0.0-beta.135" /> | ||||
| 		<PackageReference Include="TouchSocket" Version="2.0.0-beta.156" /> | ||||
| 	</ItemGroup> | ||||
| 	<ItemGroup Condition="'$(TargetFramework)'!='net45'"> | ||||
| 		<PackageReference Include="System.IO.Ports" Version="7.0.0" /> | ||||
|   | ||||
| @@ -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> | ||||
| @@ -588,6 +588,9 @@ | ||||
|         <member name="M:ThingsGateway.Foundation.EasyIncrementCount.#ctor(System.Int64,System.Int64,System.Int32)"> | ||||
|             <inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyIncrementCount.Finalize"> | ||||
|             <inheritdoc cref="T:ThingsGateway.Foundation.EasyIncrementCount"/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.EasyIncrementCount.IncreaseTick"> | ||||
|             <summary> | ||||
|             Tick | ||||
| @@ -623,7 +626,7 @@ | ||||
|             重置当前序号的初始值 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose(System.Boolean)"> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyIncrementCount.Dispose"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.EasyLock"> | ||||
| @@ -631,6 +634,9 @@ | ||||
|             EasyLock,使用轻量级SemaphoreSlim锁,只允许一个并发量,并记录并发信息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyLock.Finalize"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.EasyLock.LockWaitCount"> | ||||
|             <summary> | ||||
|             当前正在等待的数量 | ||||
| @@ -641,6 +647,9 @@ | ||||
|             当前锁是否在等待当中 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyLock.Dispose"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyLock.Release"> | ||||
|             <summary> | ||||
|             离开锁 | ||||
| @@ -666,9 +675,6 @@ | ||||
|             进入锁 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.EasyLock.Dispose(System.Boolean)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.TcpClientEx"> | ||||
|             <summary> | ||||
|             简单TCP客户端 | ||||
| @@ -679,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> | ||||
| @@ -815,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> | ||||
| @@ -831,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)"> | ||||
| @@ -840,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> | ||||
| @@ -869,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> | ||||
| @@ -880,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)"> | ||||
| @@ -897,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}})"> | ||||
| @@ -906,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)"> | ||||
| @@ -917,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}})"> | ||||
| @@ -935,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)"> | ||||
| @@ -946,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)"> | ||||
| @@ -957,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"> | ||||
| @@ -1031,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[])"> | ||||
| @@ -1099,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"> | ||||
| @@ -1283,13 +1295,6 @@ | ||||
|             <param name="value"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.ByHexStringToInt32(System.String)"> | ||||
|             <summary> | ||||
|             将16进制的字符转换为int32。 | ||||
|             </summary> | ||||
|             <param name="hexString"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Extension.String.StringExtensions.CombinePathOS(System.String,System.String[])"> | ||||
|             <summary> | ||||
|             <inheritdoc cref="M:System.IO.Path.Combine(System.String[])"/> | ||||
| @@ -1821,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"> | ||||
| @@ -1831,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> | ||||
| @@ -1943,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"> | ||||
| @@ -2296,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 | ||||
|   | ||||
| @@ -31,11 +31,11 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     private DataFormat dataFormat; | ||||
|     /// <inheritdoc/> | ||||
|     [JsonIgnore] | ||||
|     public Encoding Encoding { get; set; } = Encoding.UTF8; | ||||
|     public virtual Encoding Encoding { get; set; } = Encoding.UTF8; | ||||
|     /// <inheritdoc/> | ||||
|     public BcdFormat? BcdFormat { get; set; } | ||||
|     public virtual BcdFormat? BcdFormat { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     public int StringLength { get; set; } | ||||
|     public virtual int StringLength { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
| @@ -55,7 +55,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public DataFormat DataFormat | ||||
|     public virtual DataFormat DataFormat | ||||
|     { | ||||
|         get | ||||
|         { | ||||
| @@ -69,9 +69,9 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public EndianType EndianType => endianType; | ||||
|     public virtual EndianType EndianType => endianType; | ||||
|     /// <inheritdoc/> | ||||
|     public bool IsStringReverseByteWord { get; set; } | ||||
|     public virtual bool IsStringReverseByteWord { get; set; } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public virtual IThingsGatewayBitConverter CreateByDateFormat(DataFormat dataFormat) | ||||
| @@ -86,7 +86,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return byteConverter; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(bool value) | ||||
|     public virtual byte[] GetBytes(bool value) | ||||
|     { | ||||
|         return GetBytes(new bool[1] | ||||
|         { | ||||
| @@ -95,13 +95,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(bool[] values) | ||||
|     public virtual byte[] GetBytes(bool[] values) | ||||
|     { | ||||
|         return values?.BoolArrayToByte(); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(short value) | ||||
|     public virtual byte[] GetBytes(short value) | ||||
|     { | ||||
|         byte[] bytes = BitConverter.GetBytes(value); | ||||
|         if (!IsSameOfSet()) | ||||
| @@ -111,7 +111,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return bytes; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(short[] value) | ||||
|     public virtual byte[] GetBytes(short[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -123,7 +123,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(ushort value) | ||||
|     public virtual byte[] GetBytes(ushort value) | ||||
|     { | ||||
|         byte[] bytes = BitConverter.GetBytes(value); | ||||
|         if (!IsSameOfSet()) | ||||
| @@ -133,7 +133,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return bytes; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(ushort[] value) | ||||
|     public virtual byte[] GetBytes(ushort[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -144,12 +144,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(int value) | ||||
|     public virtual byte[] GetBytes(int value) | ||||
|     { | ||||
|         return ByteTransDataFormat4(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(int[] value) | ||||
|     public virtual byte[] GetBytes(int[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -160,12 +160,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(uint value) | ||||
|     public virtual byte[] GetBytes(uint value) | ||||
|     { | ||||
|         return ByteTransDataFormat4(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(uint[] value) | ||||
|     public virtual byte[] GetBytes(uint[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -176,12 +176,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(long value) | ||||
|     public virtual byte[] GetBytes(long value) | ||||
|     { | ||||
|         return ByteTransDataFormat8(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(long[] value) | ||||
|     public virtual byte[] GetBytes(long[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -192,12 +192,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(ulong value) | ||||
|     public virtual byte[] GetBytes(ulong value) | ||||
|     { | ||||
|         return ByteTransDataFormat8(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(ulong[] value) | ||||
|     public virtual byte[] GetBytes(ulong[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -208,12 +208,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(float value) | ||||
|     public virtual byte[] GetBytes(float value) | ||||
|     { | ||||
|         return ByteTransDataFormat4(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(float[] value) | ||||
|     public virtual byte[] GetBytes(float[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -224,12 +224,12 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(double value) | ||||
|     public virtual byte[] GetBytes(double value) | ||||
|     { | ||||
|         return ByteTransDataFormat8(BitConverter.GetBytes(value)); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(double[] value) | ||||
|     public virtual byte[] GetBytes(double[] value) | ||||
|     { | ||||
|         byte[] numArray = new byte[value.Length * 2]; | ||||
|         for (int index = 0; index < value.Length; ++index) | ||||
| @@ -240,7 +240,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] GetBytes(string value) | ||||
|     public virtual byte[] GetBytes(string value) | ||||
|     { | ||||
|         if (value == null) | ||||
|         { | ||||
| @@ -280,7 +280,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public bool IsSameOfSet() | ||||
|     public virtual bool IsSameOfSet() | ||||
|     { | ||||
|         return !(BitConverter.IsLittleEndian ^ (endianType == EndianType.Little)); | ||||
|     } | ||||
| @@ -288,7 +288,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public bool ToBoolean(byte[] buffer, int offset) | ||||
|     public virtual bool ToBoolean(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = new byte[buffer.Length]; | ||||
|         Array.Copy(buffer, 0, bytes, 0, buffer.Length); | ||||
| @@ -296,7 +296,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public byte ToByte(byte[] buffer, int offset) | ||||
|     public virtual byte ToByte(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = new byte[1]; | ||||
|         Array.Copy(buffer, offset, bytes, 0, bytes.Length); | ||||
| @@ -304,7 +304,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public byte[] ToByte(byte[] buffer, int offset, int length) | ||||
|     public virtual byte[] ToByte(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         byte[] bytes = new byte[length]; | ||||
|         Array.Copy(buffer, offset, bytes, 0, bytes.Length); | ||||
| @@ -317,7 +317,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     /// <param name="buffer"></param> | ||||
|     /// <param name="offset"></param> | ||||
|     /// <returns></returns> | ||||
|     public double ToDouble(byte[] buffer, int offset) | ||||
|     public virtual double ToDouble(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat8(buffer, offset); | ||||
|  | ||||
| @@ -325,7 +325,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public short ToInt16(byte[] buffer, int offset) | ||||
|     public virtual short ToInt16(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = new byte[2]; | ||||
|         Array.Copy(buffer, offset, bytes, 0, bytes.Length); | ||||
| @@ -337,7 +337,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public int ToInt32(byte[] buffer, int offset) | ||||
|     public virtual int ToInt32(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat4(buffer, offset); | ||||
|  | ||||
| @@ -345,14 +345,14 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public long ToInt64(byte[] buffer, int offset) | ||||
|     public virtual long ToInt64(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat8(buffer, offset); | ||||
|         return BitConverter.ToInt64(bytes, 0); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public float ToSingle(byte[] buffer, int offset) | ||||
|     public virtual float ToSingle(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat4(buffer, offset); | ||||
|  | ||||
| @@ -360,13 +360,13 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public string ToString(byte[] buffer) | ||||
|     public virtual string ToString(byte[] buffer) | ||||
|     { | ||||
|         return ToString(buffer, 0, buffer.Length); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public string ToString(byte[] buffer, int offset, int length) | ||||
|     public virtual string ToString(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         byte[] numArray = buffer.SelectMiddle(offset, length); | ||||
|         if (BcdFormat != null) | ||||
| @@ -385,7 +385,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ushort ToUInt16(byte[] buffer, int offset) | ||||
|     public virtual ushort ToUInt16(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = new byte[2]; | ||||
|         Array.Copy(buffer, offset, bytes, 0, 2); | ||||
| @@ -397,7 +397,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public uint ToUInt32(byte[] buffer, int offset) | ||||
|     public virtual uint ToUInt32(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat4(buffer, offset); | ||||
|  | ||||
| @@ -405,7 +405,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ulong ToUInt64(byte[] buffer, int offset) | ||||
|     public virtual ulong ToUInt64(byte[] buffer, int offset) | ||||
|     { | ||||
|         byte[] bytes = ByteTransDataFormat8(buffer, offset); | ||||
|         return BitConverter.ToUInt64(bytes, 0); | ||||
| @@ -508,7 +508,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public bool[] ToBoolean(byte[] buffer, int offset, int len) | ||||
|     public virtual bool[] ToBoolean(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         bool[] flagArray = new bool[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -519,7 +519,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public double[] ToDouble(byte[] buffer, int offset, int len) | ||||
|     public virtual double[] ToDouble(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         double[] numArray = new double[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -530,7 +530,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public short[] ToInt16(byte[] buffer, int offset, int len) | ||||
|     public virtual short[] ToInt16(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         short[] numArray = new short[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -541,7 +541,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public int[] ToInt32(byte[] buffer, int offset, int len) | ||||
|     public virtual int[] ToInt32(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         int[] numArray = new int[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -552,7 +552,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public long[] ToInt64(byte[] buffer, int offset, int len) | ||||
|     public virtual long[] ToInt64(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         long[] numArray = new long[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -562,7 +562,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|         return numArray; | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public float[] ToSingle(byte[] buffer, int offset, int len) | ||||
|     public virtual float[] ToSingle(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         float[] numArray = new float[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -573,7 +573,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ushort[] ToUInt16(byte[] buffer, int offset, int len) | ||||
|     public virtual ushort[] ToUInt16(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         ushort[] numArray = new ushort[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -584,7 +584,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public uint[] ToUInt32(byte[] buffer, int offset, int len) | ||||
|     public virtual uint[] ToUInt32(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         uint[] numArray = new uint[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
| @@ -595,7 +595,7 @@ public class ThingsGatewayBitConverter : IThingsGatewayBitConverter | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ulong[] ToUInt64(byte[] buffer, int offset, int len) | ||||
|     public virtual ulong[] ToUInt64(byte[] buffer, int offset, int len) | ||||
|     { | ||||
|         ulong[] numArray = new ulong[len]; | ||||
|         for (int index = 0; index < len; ++index) | ||||
|   | ||||
| @@ -0,0 +1,14 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<OutputType>Exe</OutputType> | ||||
| 		<TargetFramework>net6.0</TargetFramework> | ||||
| 		<ImplicitUsings>enable</ImplicitUsings> | ||||
| 		<Nullable>enable</Nullable> | ||||
| 	</PropertyGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| </Project> | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>ModbusDemo</name> | ||||
|         <name>DLT645Test</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|     </members> | ||||
| @@ -0,0 +1,112 @@ | ||||
| using ThingsGateway.Foundation; | ||||
| using ThingsGateway.Foundation.Adapter.DLT645; | ||||
| using ThingsGateway.Foundation.Extension.Byte; | ||||
| using ThingsGateway.Foundation.Serial; | ||||
|  | ||||
| using TouchSocket.Core; | ||||
| using TouchSocket.Sockets; | ||||
|  | ||||
| namespace DLT645Test | ||||
| { | ||||
|     internal class Program | ||||
|     { | ||||
|         static async Task Main(string[] args) | ||||
|         { | ||||
|  | ||||
|             await DLT645_2007ClientAsync(); | ||||
|  | ||||
|             Console.ReadLine(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         private static async Task DLT645_2007ClientAsync() | ||||
|         { | ||||
|             //链路基础配置项 | ||||
|             var config = new TouchSocketConfig(); | ||||
|             config.SetRemoteIPHost(new IPHost("127.0.0.1:502"))//TCP/UDP链路才需要 | ||||
|             .SetSerialProperty(new SerialProperty() //串口链路才需要 | ||||
|             { | ||||
|                 PortName = "COM1" | ||||
|             }); | ||||
|  | ||||
|             var serialSession = new SerialsSession();//链路对象 | ||||
|             serialSession.Setup(config); | ||||
|  | ||||
|             //创建协议对象,构造函数需要传入对应链路对象 | ||||
|  | ||||
|             DLT645_2007 dlt6452007 = new(serialSession)//传入链路 | ||||
|             { | ||||
|                 //协议配置 | ||||
|                 DataFormat = DataFormat.ABCD, | ||||
|                 FrameTime = 0, | ||||
|                 CacheTimeout = 1000, | ||||
|                 ConnectTimeOut = 3000, | ||||
|                 TimeOut = 3000, | ||||
|                 EnableFEHead = true, | ||||
|             }; | ||||
|  | ||||
|             #region 读写测试 | ||||
|             //测试读取写入 | ||||
|             Console.WriteLine("dlt6452007:" + dlt6452007.SerialsSession.SerialProperty.ToJsonString()); | ||||
|             await TestAsync(dlt6452007); | ||||
|             #endregion | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private static async Task TestAsync(DLT645_2007 plc) | ||||
|         { | ||||
|             //下面的方法对应PLC读写协议对象都是通用的 | ||||
|             //注意下面的方法都带有CancellationToken传播,一般是在最后一个参数,默认为None | ||||
|  | ||||
|  | ||||
|             //var bytes02010100Result = await plc.ReadAsync("03010100", 20); | ||||
|             ////返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             //Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? bytes02010100Result.Content.ToHexString() : bytes02010100Result.Message)); | ||||
|             //Console.WriteLine("bytes02010100Result:" + (bytes02010100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02010100Result.Content, 0) : bytes02010100Result.Message)); | ||||
|  | ||||
|             //var bytes02020100Result = await plc.ReadAsync("02020100", 20); | ||||
|             ////返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             //Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message)); | ||||
|             //Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToDouble(bytes02020100Result.Content, 0) : bytes02020100Result.Message)); | ||||
|  | ||||
|             //var bytes02020100Result = await plc.ReadAsync("04000103", 1); | ||||
|             ////返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             //Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message)); | ||||
|             //Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message)); | ||||
|  | ||||
|  | ||||
|             var test1 = await plc.ReadDeviceStationAsync(); | ||||
|             Console.WriteLine("bytes02020100Result:" + (test1.IsSuccess ? test1.Content : test1.Message)); | ||||
|  | ||||
|             var test2 = await plc.WriteDeviceStationAsync("311111111114"); | ||||
|             Console.WriteLine("bytes02020100Result:" + (test2.IsSuccess ? test2.Message : test2.Message)); | ||||
|             plc.BroadcastTime(DateTime.Now); | ||||
|             plc.Station = "311111111114"; | ||||
|  | ||||
|             var test3 = await plc.WriteBaudRateAsync(19200); | ||||
|             Console.WriteLine("bytes02020100Result:" + (test3.IsSuccess ? test3.Message : test3.Message)); | ||||
|             var test4 = await plc.FreezeAsync(DateTime.Now); | ||||
|             Console.WriteLine("bytes02020100Result:" + (test4.IsSuccess ? test4.Message : test4.Message)); | ||||
|  | ||||
|             var test5 = await plc.WritePasswordAsync(1, "66666666", "11111111"); | ||||
|             Console.WriteLine("bytes02020100Result:" + (test5.IsSuccess ? test5.Message : test5.Message)); | ||||
|             plc.Password = "11111111"; | ||||
|  | ||||
|  | ||||
|  | ||||
|             var bytes02020100Result1 = await plc.ReadAsync("04000403", 1); | ||||
|             //返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? bytes02020100Result1.Content.ToHexString() : bytes02020100Result1.Message)); | ||||
|             Console.WriteLine("bytes02020100Result:" + (bytes02020100Result1.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result1.Content) : bytes02020100Result1.Message)); | ||||
|  | ||||
|             var test = await plc.WriteAsync("04000403", "33"); | ||||
|             //返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             Console.WriteLine("test:" + test.Message); | ||||
|             var bytes02020100Result = await plc.ReadAsync("04000403", 1); | ||||
|             //返回带有是否成功等参数,实际数据在data.Content中 | ||||
|             Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? bytes02020100Result.Content.ToHexString() : bytes02020100Result.Message)); | ||||
|             Console.WriteLine("bytes02020100Result:" + (bytes02020100Result.IsSuccess ? plc.ThingsGatewayBitConverter.ToString(bytes02020100Result.Content) : bytes02020100Result.Message)); | ||||
|  | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,15 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
| 	<PropertyGroup> | ||||
| 		<OutputType>Exe</OutputType> | ||||
| 		<TargetFramework>net6.0</TargetFramework> | ||||
| 		<ImplicitUsings>enable</ImplicitUsings> | ||||
| 		<Nullable>enable</Nullable> | ||||
| 	</PropertyGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| </Project> | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>OPCUAClientDemo</name> | ||||
|         <name>ModbusTest</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|     </members> | ||||
| @@ -12,7 +12,7 @@ namespace ModbusDemo | ||||
|     { | ||||
|         static async Task Main(string[] args) | ||||
|         { | ||||
|             //await ModbusClientAsync(); | ||||
|             await ModbusClientAsync(); | ||||
| 
 | ||||
|             await ModbusServerAsync(); | ||||
| 
 | ||||
| @@ -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); | ||||
| @@ -7,6 +7,7 @@ | ||||
|     <Nullable>enable</Nullable> | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" /> | ||||
|   </ItemGroup> | ||||
| @@ -0,0 +1,8 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>OPCUAClientTest</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|     </members> | ||||
| </doc> | ||||
| @@ -12,14 +12,17 @@ namespace ModbusDemo | ||||
|             { | ||||
|                 OPCNode = new() | ||||
|                 { | ||||
|                     OPCUrl = "opc.tcp://desktop-p5gb4iq:50001/StandardServer", | ||||
|                     OPCUrl = "opc.tcp://127.0.0.1:49320", | ||||
|                     IsUseSecurity = true, | ||||
|                 } | ||||
|             }; | ||||
|             await oPCUAClient.ConnectAsync(); | ||||
| 
 | ||||
|             var testData1 = await oPCUAClient.ReadJTokenValueAsync(new[] { "ns=2;i=2897" }); | ||||
|             await oPCUAClient.WriteNodeAsync("ns=2;i=2897", testData1.FirstOrDefault().Item3); | ||||
|             await oPCUAClient.WriteNodeAsync(new() | ||||
|             { | ||||
|                 {"ns=2;i=2897", testData1.FirstOrDefault().Item3 } | ||||
|             }); | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| @@ -1,14 +0,0 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <OutputType>Exe</OutputType> | ||||
|     <TargetFramework>net6.0</TargetFramework> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\..\Foundataion\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
| @@ -1,7 +1,7 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Version>2.0.7.0</Version> | ||||
| 		<Version>2.1.0.4</Version> | ||||
| 		<Authors>Diego</Authors> | ||||
| 		<Product>ThingsGateway</Product> | ||||
| 		<Copyright>© 2023-present Diego</Copyright> | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,476 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.ComponentModel; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Byte; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
| using ThingsGateway.Foundation.Serial; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// DLT645_2007 | ||||
| /// </summary> | ||||
| public class DLT645_2007 : ReadWriteDevicesSerialBase | ||||
| { | ||||
|  | ||||
|     /// <summary> | ||||
|     /// DLT645_2007 | ||||
|     /// </summary> | ||||
|     /// <param name="serialSession"></param> | ||||
|     public DLT645_2007(SerialsSession serialSession) : base(serialSession) | ||||
|     { | ||||
|         ThingsGatewayBitConverter = new DLT645_2007BitConverter(EndianType.Big); | ||||
|         RegisterByteLength = 2; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 组包缓存时间/ms | ||||
|     /// </summary> | ||||
|     [Description("组包缓存时间ms")] | ||||
|     public int CacheTimeout { get; set; } = 1000; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 增加FE FE FE FE的报文头部 | ||||
|     /// </summary> | ||||
|     [Description("前导符报文头")] | ||||
|     public bool EnableFEHead { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 帧前时间ms | ||||
|     /// </summary> | ||||
|     [Description("帧前时间ms")] | ||||
|     public int FrameTime { get; set; } | ||||
|     /// <summary> | ||||
|     /// 写入需操作员代码 | ||||
|     /// </summary> | ||||
|     [Description("操作员代码")] | ||||
|     public string OperCode { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入密码 | ||||
|     /// </summary> | ||||
|     [Description("写入密码")] | ||||
|     public string Password { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 通讯地址BCD码,一般应该是12个字符 | ||||
|     /// </summary> | ||||
|     [Description("通讯地址")] | ||||
|     public string Station { get; set; } | ||||
|     /// <inheritdoc/> | ||||
|     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) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, length, (byte)ControlCode.Read, Station); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter() | ||||
|     { | ||||
|         var dataHandleAdapter = new DLT645_2007DataHandleAdapter | ||||
|         { | ||||
|             EnableFEHead = EnableFEHead | ||||
|         }; | ||||
|         SerialsSession.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override async Task<OperResult> WriteAsync(string address, string value, CancellationToken token = default) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             Password ??= string.Empty; | ||||
|             OperCode ??= string.Empty; | ||||
|             if (Password.Length < 8) | ||||
|                 Password = Password.PadLeft(8, '0'); | ||||
|             if (OperCode.Length < 8) | ||||
|                 OperCode = OperCode.PadLeft(8, '0'); | ||||
|             var data = DataTransUtil.SpliceArray(Password.ByHexStringToBytes(), OperCode.ByHexStringToBytes()); | ||||
|             string[] strArray = value.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command(address, 1, (byte)ControlCode.Write, Station, data, strArray); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<byte[]>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, uint value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, byte value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, double value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, float value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, long value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ulong value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, ushort value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, short value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, int value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override Task<OperResult> WriteAsync(string address, bool[] value, CancellationToken token = default) => WriteAsync(address, value.ToString(), token); | ||||
|  | ||||
|  | ||||
|     #region 其他方法 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 广播校时 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public OperResult BroadcastTime(DateTime dateTime, CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Connect(token); | ||||
|             string str = $"{dateTime.Second:D2}{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}{dateTime.Year % 100:D2}"; | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.BroadcastTime, str.ByHexStringToBytes().Reverse().ToArray(), "999999999999".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 SerialsSession.Send(commandResult.Content); | ||||
|                 return OperResult.CreateSuccessResult(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 冻结 | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> FreezeAsync(DateTime dateTime, CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             string str = $"{dateTime.Minute:D2}{dateTime.Hour:D2}{dateTime.Day:D2}{dateTime.Month:D2}"; | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.Freeze, str.ByHexStringToBytes().Reverse().ToArray(), Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OperResult.CreateFailedResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 读取通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult<string>> ReadDeviceStationAsync(CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.ReadStation, null, "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     var buffer = result1.Content.SelectMiddle(0, 6).BytesAdd(-0x33); | ||||
|                     return OperResult.CreateSuccessResult(buffer.Reverse().ToArray().ToHexString()); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OperResult.CreateFailedResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 修改波特率 | ||||
|     /// </summary> | ||||
|     /// <param name="baudRate"></param> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteBaudRateAsync(int baudRate, CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             byte baudRateByte; | ||||
|             switch (baudRate) | ||||
|             { | ||||
|                 case 600: baudRateByte = 0x02; break; | ||||
|                 case 1200: baudRateByte = 0x04; break; | ||||
|                 case 2400: baudRateByte = 0x08; break; | ||||
|                 case 4800: baudRateByte = 0x10; break; | ||||
|                 case 9600: baudRateByte = 0x20; break; | ||||
|                 case 19200: baudRateByte = 0x40; break; | ||||
|                 default: return new OperResult<string>($"不支持此波特率:{baudRate}"); | ||||
|             } | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteBaudRate, new byte[] { baudRateByte }, Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OperResult.CreateFailedResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 更新通信地址 | ||||
|     /// </summary> | ||||
|     /// <param name="station"></param> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WriteDeviceStationAsync(string station, CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WriteStation, station.ByHexStringToBytes().Reverse().ToArray(), "AAAAAAAAAAAA".ByHexStringToBytes()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OperResult.CreateFailedResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 修改密码 | ||||
|     /// </summary> | ||||
|     /// <param name="level"></param> | ||||
|     /// <param name="oldPassword"></param> | ||||
|     /// <param name="newPassword"></param> | ||||
|     /// <param name="token"></param> | ||||
|     /// <returns></returns> | ||||
|     public async Task<OperResult> WritePasswordAsync(byte level, string oldPassword, string newPassword, CancellationToken token = default) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await ConnectAsync(token); | ||||
|  | ||||
|             if (Station.IsNullOrEmpty()) Station = string.Empty; | ||||
|             if (Station.Length < 12) Station = Station.PadLeft(12, '0'); | ||||
|             string str = $"04000C{level:D2}"; | ||||
|  | ||||
|             var commandResult = DLT645Helper.GetDLT645_2007Command((byte)ControlCode.WritePassword, | ||||
|                 str.ByHexStringToBytes().Reverse().ToArray() | ||||
|                 .SpliceArray(oldPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 .SpliceArray(newPassword.ByHexStringToBytes().Reverse().ToArray()) | ||||
|                 , Station.ByHexStringToBytes().Reverse().ToArray()); | ||||
|             if (commandResult.IsSuccess) | ||||
|             { | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(commandResult.Content, TimeOut, token); | ||||
|                 var result1 = ((MessageBase)result.RequestInfo); | ||||
|                 if (result1.IsSuccess) | ||||
|                 { | ||||
|                     return OperResult.CreateSuccessResult(); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     return OperResult.CreateFailedResult<string>(result1); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return OperResult.CreateFailedResult<string>(commandResult); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<string>(ex); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
| } | ||||
| /// <summary> | ||||
| /// 控制码 | ||||
| /// </summary> | ||||
| public enum ControlCode : byte | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 读数据 | ||||
|     /// </summary> | ||||
|     Read = 0x11, | ||||
|     /// <summary> | ||||
|     /// 读后续数据 | ||||
|     /// </summary> | ||||
|     ReadSub = 0x12, | ||||
|     /// <summary> | ||||
|     /// 读站号 | ||||
|     /// </summary> | ||||
|     ReadStation = 0x13, | ||||
|     /// <summary> | ||||
|     /// 写数据 | ||||
|     /// </summary> | ||||
|     Write = 0x14, | ||||
|     /// <summary> | ||||
|     /// 写站号 | ||||
|     /// </summary> | ||||
|     WriteStation = 0x15, | ||||
|     /// <summary> | ||||
|     /// 广播校时 | ||||
|     /// </summary> | ||||
|     BroadcastTime = 0x08, | ||||
|     /// <summary> | ||||
|     /// 冻结 | ||||
|     /// </summary> | ||||
|     Freeze = 0x16, | ||||
|     /// <summary> | ||||
|     /// 更新波特率 | ||||
|     /// </summary> | ||||
|     WriteBaudRate = 0x17, | ||||
|     /// <summary> | ||||
|     /// 更新密码 | ||||
|     /// </summary> | ||||
|     WritePassword = 0x18, | ||||
| } | ||||
| @@ -0,0 +1,146 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Byte; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
|  | ||||
| /// <summary> | ||||
| /// DLT645_2007Address | ||||
| /// </summary> | ||||
| public class DLT645_2007Address : DeviceAddressBase | ||||
| { | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public DLT645_2007Address() | ||||
|     { | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public DLT645_2007Address(string address, ushort len) | ||||
|     { | ||||
|         Parse(address, len); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public DLT645_2007Address(string address, byte[] station) | ||||
|     { | ||||
|         Station = station; | ||||
|         Parse(address, 0); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 数据标识 | ||||
|     /// </summary> | ||||
|     public byte[] DataId { get; set; } = new byte[0]; | ||||
|     /// <summary> | ||||
|     /// 反转解析 | ||||
|     /// </summary> | ||||
|     public bool Reverse { get; set; } = true; | ||||
|     /// <summary> | ||||
|     /// 站号信息 | ||||
|     /// </summary> | ||||
|     public byte[] Station { get; set; } = new byte[0]; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void Parse(string address, int length) | ||||
|     { | ||||
|         var result = ParseFrom(address, length); | ||||
|         if (result.IsSuccess) | ||||
|         { | ||||
|             Length = result.Content.Length; | ||||
|             AddressStart = result.Content.AddressStart; | ||||
|             DataId = result.Content.DataId; | ||||
|             Station = result.Content.Station; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             throw new Exception(result.Message); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 解析地址 | ||||
|     /// </summary> | ||||
|     /// <param name="address"></param> | ||||
|     /// <param name="length"></param> | ||||
|     /// <returns></returns> | ||||
|     public static OperResult<DLT645_2007Address> ParseFrom(string address, int length) | ||||
|     { | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             DLT645_2007Address dLT645_2007Address = new(); | ||||
|             byte[] array; | ||||
|             array = new byte[0]; | ||||
|             dLT645_2007Address.Length = length; | ||||
|             if (address.IndexOf(';') < 0) | ||||
|             { | ||||
|                 array = address.ByHexStringToBytes().Reverse().ToArray(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 string[] strArray = address.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); | ||||
|  | ||||
|                 for (int index = 0; index < strArray.Length; ++index) | ||||
|                 { | ||||
|                     if (strArray[index].ToUpper().StartsWith("S=")) | ||||
|                     { | ||||
|                         var station = strArray[index].Substring(2); | ||||
|                         if (station.IsNullOrEmpty()) return new OperResult<DLT645_2007Address>("通讯地址不能为空"); | ||||
|                         if (station.Length < 12) | ||||
|                             station = station.PadLeft(12, '0'); | ||||
|                         dLT645_2007Address.Station = station.ByHexStringToBytes().Reverse().ToArray(); | ||||
|                     } | ||||
|                     else if (!strArray[index].Contains("r=")) | ||||
|                     { | ||||
|                         dLT645_2007Address.Reverse = strArray[index].Substring(2).GetBoolValue(); | ||||
|                     } | ||||
|                     else if (!strArray[index].Contains("=")) | ||||
|                     { | ||||
|                         array = strArray[index].ByHexStringToBytes().Reverse().ToArray(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             dLT645_2007Address.DataId = array; | ||||
|             return OperResult.CreateSuccessResult(dLT645_2007Address); | ||||
|  | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             return new OperResult<DLT645_2007Address>(ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|     { | ||||
|         StringBuilder stringGeter = new(); | ||||
|         if (Station.Length > 0) | ||||
|         { | ||||
|             stringGeter.Append("s=" + Station.Reverse().ToArray().ToHexString() + ";"); | ||||
|         } | ||||
|         if (DataId.Length > 0) | ||||
|         { | ||||
|             stringGeter.Append(DataId.Reverse().ToArray().ToHexString() + ";"); | ||||
|         } | ||||
|         if (!Reverse) | ||||
|         { | ||||
|             stringGeter.Append("s=" + Reverse.ToString() + ";"); | ||||
|         } | ||||
|         return stringGeter.ToString(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,106 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Foundation.Extension.Byte; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
| /// <summary> | ||||
| /// DLT645_2007 | ||||
| /// </summary> | ||||
| public class DLT645_2007BitConverter : ThingsGatewayBitConverter | ||||
| { | ||||
|     /// <summary> | ||||
|     /// DLT645_2007 | ||||
|     /// </summary> | ||||
|     public DLT645_2007BitConverter(EndianType endianType) : base(endianType) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// DLT645协议转换double | ||||
|     /// </summary> | ||||
|     /// <param name="buffer">带数据项标识</param> | ||||
|     /// <param name="offset"></param> | ||||
|     /// <returns></returns> | ||||
|     public override double ToDouble(byte[] buffer, int offset) | ||||
|     { | ||||
|         return Convert.ToDouble(this.ToString(buffer, offset, buffer.Length)); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString(byte[] buffer) | ||||
|     { | ||||
|         return this.ToString(buffer, 0, buffer.Length); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         buffer = buffer.SelectMiddle(offset, length); | ||||
|         buffer = buffer.BytesAdd(-0x33); | ||||
|         var dataInfos = DLT645Helper.GetDataInfos(buffer); | ||||
|         StringBuilder stringBuilder = new(); | ||||
|         foreach (var dataInfo in dataInfos) | ||||
|         { | ||||
|             //实际数据 | ||||
|             var content = buffer.SelectMiddle(4, dataInfo.ByteLength).Reverse().ToArray(); | ||||
|             if (dataInfo.IsSigned)//可能为负数 | ||||
|             { | ||||
|                 if (content[0] > 0x80)//最高位是表示正负 | ||||
|                 { | ||||
|                     content[0] = (byte)(content[0] - 0x80); | ||||
|                     if (dataInfo.Digtal == 0)//无小数点 | ||||
|                     { | ||||
|                         stringBuilder.AppendLine($"-{content.ToHexString()}"); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         stringBuilder.AppendLine((-(Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString()); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     ToString(stringBuilder, dataInfo, content); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 ToString(stringBuilder, dataInfo, content); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return stringBuilder.ToString(); | ||||
|  | ||||
|         static void ToString(StringBuilder stringBuilder, DataInfo dataInfo, byte[] content) | ||||
|         { | ||||
|             if (dataInfo.Digtal < 0) | ||||
|             { | ||||
|                 stringBuilder.AppendLine($"{Encoding.ASCII.GetString(content)}"); | ||||
|             } | ||||
|             else if (dataInfo.Digtal == 0)//无小数点 | ||||
|             { | ||||
|                 stringBuilder.AppendLine($"{content.ToHexString()}"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 stringBuilder.AppendLine(((Convert.ToDouble(content.ToHexString()) / Math.Pow(10.0, dataInfo.Digtal))).ToString()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,192 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| using System.ComponentModel; | ||||
|  | ||||
| using ThingsGateway.Foundation.Adapter.Modbus; | ||||
| using ThingsGateway.Foundation.Extension.Generic; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
|  | ||||
| /// <summary> | ||||
| /// DLT645_2007DataHandleAdapter | ||||
| /// </summary> | ||||
| public class DLT645_2007DataHandleAdapter : ReadWriteDevicesTcpDataHandleAdapter<DLT645_2007Message> | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 增加FE FE FE FE的报文头部 | ||||
|     /// </summary> | ||||
|     [Description("前导符报文头")] | ||||
|     public bool EnableFEHead { get; set; } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override byte[] PackCommand(byte[] command) | ||||
|     { | ||||
|         //打包时加上4个FE字节 | ||||
|         if (EnableFEHead) | ||||
|         { | ||||
|             return DataTransUtil.SpliceArray(new byte[4] { 0xFE, 0xFE, 0xFE, 0xFE }, command); | ||||
|         } | ||||
|         return command; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override DLT645_2007Message GetInstance() | ||||
|     { | ||||
|         return new DLT645_2007Message(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override FilterResult UnpackResponse(DLT645_2007Message request, byte[] send, byte[] body, byte[] response) | ||||
|     { | ||||
|         //因为设备可能带有FE前导符开头,这里找到0x68的位置 | ||||
|         int headCodeIndex = -1; | ||||
|         if (response != null) | ||||
|         { | ||||
|             for (int index = 0; index < response.Length; index++) | ||||
|             { | ||||
|                 if (response[index] == 0x68) | ||||
|                 { | ||||
|                     headCodeIndex = index; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         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) | ||||
|             return FilterResult.Cache; | ||||
|  | ||||
|  | ||||
|         var len = 10 + response[headCodeIndex + 9] + 2; | ||||
|  | ||||
|         if (response.Length - headCodeIndex < len) | ||||
|         { | ||||
|             return FilterResult.Cache; | ||||
|         } | ||||
|         if (response.Length - headCodeIndex >= len && response[len + headCodeIndex - 1] == 0x16) | ||||
|         { | ||||
|  | ||||
|             //检查校验码 | ||||
|             int sumCheck = 0; | ||||
|             for (int i = headCodeIndex; i < len + headCodeIndex - 2; i++) | ||||
|                 sumCheck += response[i]; | ||||
|             if ((byte)sumCheck != response[len + headCodeIndex - 2]) | ||||
|             { | ||||
|                 //校验错误 | ||||
|                 request.Message = "和校验错误"; | ||||
|                 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); | ||||
|                 var error = DLT645Helper.Get2007ErrorMessage(byte1); | ||||
|                 request.Message = "异常控制码:" + $"0x{response[headCodeIndex + 8]:X2},错误信息:{error}"; | ||||
|                 request.ResultCode = ResultCode.Fail; | ||||
|                 return FilterResult.Success; | ||||
|             } | ||||
|  | ||||
|             if (send[sendHeadCodeIndex + 8] == (byte)ControlCode.Read || | ||||
|     send[sendHeadCodeIndex + 8] == (byte)ControlCode.Write | ||||
|     ) | ||||
|             { | ||||
|                 //数据标识不符合时,返回错误 | ||||
|                 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 | ||||
|         { | ||||
|             request.ResultCode = ResultCode.Error; | ||||
|             return FilterResult.Success; | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user