Compare commits
	
		
			13 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 378763e4ee | ||
|   | 517bd0394d | ||
|   | 70adb97fb5 | ||
|   | 623d44cabe | ||
|   | 0d479ca00b | ||
|   | 8bc49ef437 | ||
|   | f83fcec786 | ||
|   | 93690ce40d | ||
|   | f82c5f2f27 | ||
|   | a83c1c3899 | ||
|   | 91d6aed109 | ||
|   | db8f8fe51d | ||
|   | 4596004b17 | 
| @@ -1,6 +1,6 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.5</Version> | ||||
| 		<Version>3.0.0.10</Version> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net6.0;net7.0</TargetFrameworks> | ||||
| 		<Authors>Diego</Authors> | ||||
|   | ||||
| @@ -144,6 +144,15 @@ public partial class MainLayout | ||||
|         var dataStringPro = | ||||
| """ | ||||
| [ | ||||
|   { | ||||
|     "Title": "Melsec", | ||||
|     "Children": [ | ||||
|       { | ||||
|         "Href": "/QnA3E_Binary", | ||||
|         "Title": "QnA3E_Binary" | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   { | ||||
|     "Title": "ABCIP", | ||||
|     "Children": [ | ||||
|   | ||||
| @@ -4,6 +4,14 @@ | ||||
| 		<DefineConstants>Pro</DefineConstants> | ||||
| 	</PropertyGroup> | ||||
| 	<ItemGroup Condition="'$(SolutionName)'=='ThingsGateway - Pro'"> | ||||
|  | ||||
|  | ||||
|  | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor.cs" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.Melsec\Page\QnA3E_BinaryDebugPage.razor" Link="Pages\Melsec\QnA3E_BinaryDebugPage.razor" /> | ||||
| 		<ProjectReference Include="..\..\FoundationPro\ThingsGateway.Foundation.Adapter.Melsec\ThingsGateway.Foundation.Adapter.Melsec.csproj" /> | ||||
|  | ||||
| 		 | ||||
| 		 | ||||
| 		<Compile Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor.cs" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor.cs" /> | ||||
| 		<Content Include="..\..\PluginPro\ThingsGateway.Plugin.AllenBradleyCip\Page\AllenBradleyCipTcpDebugPage.razor" Link="Pages\ABCIP\AllenBradleyCipTcpDebugPage.razor" /> | ||||
| @@ -107,12 +115,20 @@ | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" /> | ||||
| 	<ItemGroup > | ||||
| 		<PackageReference Include="ThingsGateway.Foundation.Adapter.DLT645" Version="*" /> | ||||
| 		<PackageReference Include="ThingsGateway.Foundation.Adapter.Modbus" Version="*" /> | ||||
| 		<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCDA" Version="*" /> | ||||
| 		<PackageReference Include="ThingsGateway.Foundation.Adapter.OPCUA" Version="*" /> | ||||
| 		<PackageReference Include="ThingsGateway.Foundation.Adapter.Siemens" Version="*" /> | ||||
| 		<!--<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.DLT645\ThingsGateway.Foundation.Adapter.DLT645.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Modbus\ThingsGateway.Foundation.Adapter.Modbus.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCDA\ThingsGateway.Foundation.Adapter.OPCDA.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.OPCUA\ThingsGateway.Foundation.Adapter.OPCUA.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" /> | ||||
| 		<ProjectReference Include="..\..\Foundation\ThingsGateway.Foundation.Adapter.Siemens\ThingsGateway.Foundation.Adapter.Siemens.csproj" />--> | ||||
|  | ||||
| 	</ItemGroup> | ||||
| 	<ItemGroup > | ||||
| 		<ProjectReference Include="..\..\Web\ThingsGateway.Components\ThingsGateway.Components.csproj" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| @@ -124,10 +140,6 @@ | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <Folder Include="Pages\Mqtt\" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 	  <Content Include="..\..\Plugin\ThingsGateway.Plugin.Mqtt\Page\MqttClientDebugPage.razor" Link="Pages\Mqtt\MqttClientDebugPage.razor" /> | ||||
|   | ||||
| @@ -1,9 +1,12 @@ | ||||
| <Project> | ||||
| 	<PropertyGroup> | ||||
| 		<Version>3.0.0.5</Version> | ||||
| 		<Version>3.0.0.10</Version> | ||||
| 		<GenerateDocumentationFile>True</GenerateDocumentationFile> | ||||
| 		<LangVersion>latest</LangVersion> | ||||
| 		<TargetFrameworks>net45;netstandard2.0;net6.0;net7.0</TargetFrameworks> | ||||
| 		<Description> | ||||
| 			ThingsGateway.Foundation是工业设备通讯类库,归属于ThingsGateway边缘网关项目,说明文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| 		</Description> | ||||
| 		<Authors>Diego</Authors> | ||||
| 		<Product>ThingsGateway</Product> | ||||
| 		<Copyright>© 2023-present Diego</Copyright> | ||||
| @@ -16,7 +19,6 @@ | ||||
| 		<PackageReadmeFile>README.md</PackageReadmeFile> | ||||
| 		<PackageIcon>icon.png</PackageIcon> | ||||
| 		<IncludeSymbols>true</IncludeSymbols> | ||||
| 		<SymbolPackageFormat>snupkg</SymbolPackageFormat> | ||||
| 		<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> | ||||
| 		<PackageProjectUrl>https://diego2098.gitee.io/thingsgateway-docs/</PackageProjectUrl> | ||||
| 		<PackageTags>ThingsGateway;Diego;dotNET China;Blazor;设备采集;边缘网关</PackageTags> | ||||
| @@ -42,5 +44,10 @@ | ||||
| 		</None> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<PropertyGroup Condition="'$(Configuration)' == 'Release'"> | ||||
| 		<DebugSymbols>True</DebugSymbols> | ||||
| 		<DebugType>Embedded</DebugType> | ||||
| 		<EmbedAllSources>True</EmbedAllSources> | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| </Project> | ||||
| @@ -20,15 +20,12 @@ public class DLT645_2007Message : MessageBase, IMessage | ||||
|     public override int HeadBytesLength => -1; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override bool CheckHeadBytes(byte[] head) | ||||
|     public override bool CheckHeadBytes(byte[] heads) | ||||
|     { | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void SendBytesThen() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.DLT645; | ||||
|  | ||||
| internal static class PackHelper | ||||
|   | ||||
| @@ -1,442 +0,0 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>ThingsGateway.Foundation.Adapter.DLT645</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DataInfo"> | ||||
|             <summary> | ||||
|             解析参数 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.ByteLength"> | ||||
|             <summary> | ||||
|             解析长度 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.Digtal"> | ||||
|             <summary> | ||||
|             小数位 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DataInfo.IsSigned"> | ||||
|             <summary> | ||||
|             有符号解析 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDataInfos(System.Byte[])"> | ||||
|             <summary> | ||||
|             获取返回的解析信息 | ||||
|             </summary> | ||||
|             <param name="buffer"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645Helper.GetDLT645_2007Command(System.String,System.Int32,System.Byte,System.String,System.Byte[],System.String[])"> | ||||
|             <summary> | ||||
|             获取DLT645报文 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.#ctor(ThingsGateway.Foundation.Serial.SerialSession)"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|             <param name="serialSession"></param> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.EnableFEHead"> | ||||
|             <summary> | ||||
|             增加FE FE FE FE的报文头部 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.OperCode"> | ||||
|             <summary> | ||||
|             写入需操作员代码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Password"> | ||||
|             <summary> | ||||
|             写入密码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.Station"> | ||||
|             <summary> | ||||
|             通讯地址BCD码,一般应该是12个字符 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.GetAddressDescription"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.SetDataAdapter"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.String,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.BroadcastTime(System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             广播校时 | ||||
|             </summary> | ||||
|             <param name="dateTime"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.FreezeAsync(System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             冻结 | ||||
|             </summary> | ||||
|             <param name="dateTime"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.ReadDeviceStationAsync(System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取通信地址 | ||||
|             </summary> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             修改波特率 | ||||
|             </summary> | ||||
|             <param name="baudRate"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             更新通信地址 | ||||
|             </summary> | ||||
|             <param name="station"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             修改密码 | ||||
|             </summary> | ||||
|             <param name="level"></param> | ||||
|             <param name="oldPassword"></param> | ||||
|             <param name="newPassword"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.ControlCode"> | ||||
|             <summary> | ||||
|             控制码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Read"> | ||||
|             <summary> | ||||
|             读数据 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadSub"> | ||||
|             <summary> | ||||
|             读后续数据 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.ReadStation"> | ||||
|             <summary> | ||||
|             读站号 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Write"> | ||||
|             <summary> | ||||
|             写数据 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteStation"> | ||||
|             <summary> | ||||
|             写站号 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.BroadcastTime"> | ||||
|             <summary> | ||||
|             广播校时 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.Freeze"> | ||||
|             <summary> | ||||
|             冻结 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WriteBaudRate"> | ||||
|             <summary> | ||||
|             更新波特率 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.DLT645.ControlCode.WritePassword"> | ||||
|             <summary> | ||||
|             更新密码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address"> | ||||
|             <summary> | ||||
|             DLT645_2007Address | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.UInt16)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.#ctor(System.String,System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.DataId"> | ||||
|             <summary> | ||||
|             数据标识 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Reverse"> | ||||
|             <summary> | ||||
|             反转解析 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Station"> | ||||
|             <summary> | ||||
|             站号信息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.Parse(System.String,System.Int32)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ParseFrom(System.String,System.Int32)"> | ||||
|             <summary> | ||||
|             解析地址 | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <param name="length"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007Address.ToString"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.#ctor(ThingsGateway.Foundation.Core.EndianType)"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToDouble(System.Byte[],System.Int32)"> | ||||
|             <summary> | ||||
|             DLT645协议转换double | ||||
|             </summary> | ||||
|             <param name="buffer">带数据项标识</param> | ||||
|             <param name="offset"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007BitConverter.ToString(System.Byte[],System.Int32,System.Int32)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter"> | ||||
|             <summary> | ||||
|             DLT645_2007DataHandleAdapter | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.EnableFEHead"> | ||||
|             <summary> | ||||
|             增加FE FE FE FE的报文头部 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.GetInstance"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007DataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message,System.Byte[],System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.#ctor(ThingsGateway.Foundation.Core.TcpClient)"> | ||||
|             <summary> | ||||
|             DLT645_2007 | ||||
|             </summary> | ||||
|             <param name="tcpClient"></param> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.EnableFEHead"> | ||||
|             <summary> | ||||
|             增加FE FE FE FE的报文头部 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.OperCode"> | ||||
|             <summary> | ||||
|             写入需操作员代码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Password"> | ||||
|             <summary> | ||||
|             写入密码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.Station"> | ||||
|             <summary> | ||||
|             通讯地址BCD码,一般应该是12个字符 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.GetAddressDescription"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.SetDataAdapter"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.String,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Byte,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Double,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Single,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int64,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt64,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.UInt16,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int16,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.BroadcastTime(System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             广播校时 | ||||
|             </summary> | ||||
|             <param name="dateTime"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.FreezeAsync(System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             冻结 | ||||
|             </summary> | ||||
|             <param name="dateTime"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.ReadDeviceStationAsync(System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取通信地址 | ||||
|             </summary> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteBaudRateAsync(System.Int32,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             修改波特率 | ||||
|             </summary> | ||||
|             <param name="baudRate"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WriteDeviceStationAsync(System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             更新通信地址 | ||||
|             </summary> | ||||
|             <param name="station"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.DLT645.DLT645_2007OverTcp.WritePasswordAsync(System.Byte,System.String,System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             修改密码 | ||||
|             </summary> | ||||
|             <param name="level"></param> | ||||
|             <param name="oldPassword"></param> | ||||
|             <param name="newPassword"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.HeadBytesLength"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.CheckHeadBytes(System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Modbus.DLT645_2007Message.SendBytesThen"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
| @@ -20,15 +20,12 @@ public class ModbusRtuMessage : MessageBase, IMessage | ||||
|     public override int HeadBytesLength => -1; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override bool CheckHeadBytes(byte[] head) | ||||
|     public override bool CheckHeadBytes(byte[] heads) | ||||
|     { | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void SendBytesThen() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -24,7 +24,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|     /// <summary> | ||||
|     /// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|     /// </summary> | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, OperResult> WriteData; | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SerialSession, Task<OperResult>> WriteData; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 继电器 | ||||
| @@ -267,12 +267,13 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Received(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     protected override async Task Received(SerialSession client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|  | ||||
|             var requestInfo = e.RequestInfo; | ||||
|             //接收外部报文 | ||||
|             if (requestInfo is ModbusSerialServerMessage modbusServerMessage) | ||||
|             { | ||||
| @@ -312,7 +313,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|                             // 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|                             if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                                 if (result.IsSuccess) | ||||
| @@ -349,7 +350,7 @@ public class ModbusSerialServer : ReadWriteDevicesSerialSessionBase | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|  | ||||
|                             if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, SerialSession)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                                 if (result.IsSuccess) | ||||
|   | ||||
| @@ -30,14 +30,11 @@ public class ModbusSerialServerMessage : MessageBase, IMessage | ||||
|     public override int HeadBytesLength => -1; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override bool CheckHeadBytes(byte[] head) | ||||
|     public override bool CheckHeadBytes(byte[] heads) | ||||
|     { | ||||
|         BodyLength = -1; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void SendBytesThen() | ||||
|     { | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -23,10 +23,10 @@ public class ModbusTcpMessage : MessageBase, IMessage | ||||
|     /// </summary> | ||||
|     public bool IsCheckMessageId { get; set; } = false; | ||||
|     /// <inheritdoc/> | ||||
|     public override bool CheckHeadBytes(byte[] head) | ||||
|     public override bool CheckHeadBytes(byte[] heads) | ||||
|     { | ||||
|         if (head == null || head.Length <= 0) return false; | ||||
|         HeadBytes = head; | ||||
|         if (heads == null || heads.Length <= 0) return false; | ||||
|         HeadBytes = heads; | ||||
|  | ||||
|         int num = (HeadBytes[4] * 256) + HeadBytes[5]; | ||||
|         BodyLength = num; | ||||
|   | ||||
| @@ -84,15 +84,6 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
|             return new OperResult<byte[]>(ex); | ||||
|         } | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     protected override void Connecting(SocketClient client, ConnectingEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "正在连接"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override void SetDataAdapter(object socketClient = null) | ||||
| @@ -195,7 +186,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
|                 var item = commandResult.Content; | ||||
|                 if (FrameTime != 0) | ||||
|                     Thread.Sleep(FrameTime); | ||||
|                 var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true }); | ||||
|                 var WaitingClientEx = client.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var result = WaitingClientEx.SendThenResponse(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
| @@ -222,7 +213,7 @@ public class ModbusTcpDtu : ReadWriteDevicesTcpServerBase | ||||
|  | ||||
|                 var item = commandResult.Content; | ||||
|                 await Task.Delay(FrameTime, cancellationToken); | ||||
|                 var WaitingClientEx = client.GetWaitingClientEx(new() { BreakTrigger = true }); | ||||
|                 var WaitingClientEx = client.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|                 var result = await WaitingClientEx.SendThenResponseAsync(item, TimeOut, cancellationToken); | ||||
|                 return (MessageBase)result.RequestInfo; | ||||
|             } | ||||
|   | ||||
| @@ -25,7 +25,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|     /// <summary> | ||||
|     /// 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|     /// </summary> | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, OperResult> WriteData; | ||||
|     public Func<ModbusAddress, byte[], IThingsGatewayBitConverter, SocketClient, Task<OperResult>> WriteData; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 继电器 | ||||
| @@ -284,12 +284,13 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|     { | ||||
|         return Task.FromResult(Write(address, value)); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Received(SocketClient client, IRequestInfo requestInfo) | ||||
|     protected override async Task Received(SocketClient client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|  | ||||
|             var requestInfo = e.RequestInfo; | ||||
|             //接收外部报文 | ||||
|             if (requestInfo is ModbusTcpServerMessage modbusServerMessage) | ||||
|             { | ||||
| @@ -330,7 +331,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|                             // 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端 | ||||
|                             if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData.ByteToBoolArray(modbusServerMessage.Length)); | ||||
|                                 if (result.IsSuccess) | ||||
| @@ -367,7 +368,7 @@ public class ModbusTcpServer : ReadWriteDevicesTcpServerBase | ||||
|                         if (WriteData != null) | ||||
|                         { | ||||
|  | ||||
|                             if ((WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             if ((await WriteData(modbusServerMessage.CurModbusAddress, modbusServerMessage.Content, ThingsGatewayBitConverter, client)).IsSuccess) | ||||
|                             { | ||||
|                                 var result = Write(modbusServerMessage.CurModbusAddress.ToString(), coreData); | ||||
|                                 if (result.IsSuccess) | ||||
|   | ||||
| @@ -29,10 +29,10 @@ namespace ThingsGateway.Foundation.Adapter.Modbus | ||||
|         /// <inheritdoc/> | ||||
|         public override int HeadBytesLength => 6; | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CheckHeadBytes(byte[] head) | ||||
|         public override bool CheckHeadBytes(byte[] heads) | ||||
|         { | ||||
|             if (head == null || head.Length != 6) return false; | ||||
|             HeadBytes = head; | ||||
|             if (heads == null || heads.Length != 6) return false; | ||||
|             HeadBytes = heads; | ||||
|  | ||||
|             int num = (HeadBytes[4] * 256) + HeadBytes[5]; | ||||
|             BodyLength = num; | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
| 	 | ||||
| </Project> | ||||
|   | ||||
| @@ -1,579 +0,0 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>ThingsGateway.Foundation.Adapter.OPCDA</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})"> | ||||
|             <summary> | ||||
|             移除符合条件的元素 | ||||
|             </summary> | ||||
|             <typeparam name="T"></typeparam> | ||||
|             <param name="this"></param> | ||||
|             <param name="where"></param> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_SYSTEM_DEFAULT"> | ||||
|             <summary> | ||||
|             The WIN32 system default locale. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.LOCALE_USER_DEFAULT"> | ||||
|             <summary> | ||||
|             The WIN32 user default locale. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.CreateInstance(System.Guid,System.String)"> | ||||
|             <summary> | ||||
|             创建一个COM服务器的实例。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.GetSystemMessage(System.Int32)"> | ||||
|             <summary> | ||||
|             指定错误消息文本检索系统。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.InitializeSecurity"> | ||||
|             <summary> | ||||
|             初始化COM安全。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID)"> | ||||
|             <summary> | ||||
|             从枚举器读取guid。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.ReadClasses(ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID)"> | ||||
|             <summary> | ||||
|             从枚举器读取guid。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Comn.ComInterop.RealseComServer(System.Object)"> | ||||
|             <summary> | ||||
|             释放 COM 对象 | ||||
|             </summary> | ||||
|             <param name="m_server"></param> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCDA.Comn.Convert.FILETIME_BaseTime"> | ||||
|             <summary> | ||||
|             windows的filetime是从1601-1-1 00:00:00开始的,datetime是从1-1-1 00:00:00开始的 | ||||
|             datetime和filetime的滴答单位都是100ns(100纳秒,千万分之一秒),所以转换时只需要考虑开始时间即可 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnDataChangedHandler"> | ||||
|             <summary> | ||||
|             值变化 | ||||
|             </summary> | ||||
|             <param name="opcItems"></param> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnReadCompletedHandler"> | ||||
|             <summary> | ||||
|             读取 | ||||
|             </summary> | ||||
|             <param name="opcItems"></param> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OnWriteCompletedHandler"> | ||||
|             <summary> | ||||
|             写入 | ||||
|             </summary> | ||||
|             <param name="opcItems"></param> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult"> | ||||
|             <summary> | ||||
|             返回结果 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Name"> | ||||
|             <summary> | ||||
|             ID | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Quality"> | ||||
|             <summary> | ||||
|             Quality | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.TimeStamp"> | ||||
|             <summary> | ||||
|             TimeStamp | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ItemReadResult.Value"> | ||||
|             <summary> | ||||
|             Value | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.InitIoInterfaces(System.Object)"> | ||||
|             <summary> | ||||
|             建立连接 | ||||
|             </summary> | ||||
|             <param name="handle"></param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcGroup.ReadAsync"> | ||||
|             <summary> | ||||
|             组读取 | ||||
|             </summary> | ||||
|             <exception cref="T:System.Runtime.InteropServices.ExternalException"></exception> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem"> | ||||
|             <summary> | ||||
|             OpcItem | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.#ctor(System.String)"> | ||||
|             <summary> | ||||
|             OpcItem | ||||
|             </summary> | ||||
|             <param name="itemId"></param> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.AccessPath"> | ||||
|             <summary> | ||||
|             AccessPath | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Blob"> | ||||
|             <summary> | ||||
|             Blob | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.BlobSize"> | ||||
|             <summary> | ||||
|             BlobSize | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ClientHandle"> | ||||
|             <summary> | ||||
|             ClientHandle | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.IsActive"> | ||||
|             <summary> | ||||
|             active(1) or not(0) | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ItemID"> | ||||
|             <summary> | ||||
|             数据项在opc server的完全名称 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Quality"> | ||||
|             <summary> | ||||
|             Quality | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.RunTimeDataType"> | ||||
|             <summary> | ||||
|             RunTimeDataType | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.ServerHandle"> | ||||
|             <summary> | ||||
|             ServerHandle | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.TimeStamp"> | ||||
|             <summary> | ||||
|             TimeStamp | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem.Value"> | ||||
|             <summary> | ||||
|             Value | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.AddGroup(System.String,System.Boolean,System.Int32,System.Single)"> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.Browse(System.String)"> | ||||
|             <summary> | ||||
|             获取节点 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcServer.GetServerStatus"> | ||||
|             <summary> | ||||
|             服务器状态 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus"> | ||||
|             <summary> | ||||
|             ServerStatus | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.CurrentTime"> | ||||
|             <summary> | ||||
|             CurrentTime | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.LastUpdateTime"> | ||||
|             <summary> | ||||
|             LastUpdateTime | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.ServerState"> | ||||
|             <summary> | ||||
|             ServerState | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.StartTime"> | ||||
|             <summary> | ||||
|             StartTime | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.VendorInfo"> | ||||
|             <summary> | ||||
|             VendorInfo | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.Da.ServerStatus.Version"> | ||||
|             <summary> | ||||
|             Version | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery"> | ||||
|             <summary> | ||||
|             OpcDiscovery | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.Discovery.OpcDiscovery.GetOpcServer(System.String,System.String)"> | ||||
|             <summary> | ||||
|             GetOpcServer | ||||
|             </summary> | ||||
|             <param name="serverName"></param> | ||||
|             <param name="host"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPoint"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IConnectionPointContainer"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnectionPoints"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumConnections"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumGUID"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumString"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumUnknown"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCCommon"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCEnumGUID"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerList2"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCShutdown"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CONNECTDATA"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEDIRECTION"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEFILTER"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSETYPE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCDATASOURCE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCENUMSCOPE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCEUTYPE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCNAMESPACETYPE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer10"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer20"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_OPCDAServer30"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.CATID_XMLDAServer10"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IEnumOPCItemAttributes"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO2"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCAsyncIO3"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowse"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCBrowseServerAddressSpace"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCDataCallback"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCGroupStateMgt2"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemDeadbandMgt"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemIO"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemMgt"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemProperties"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCItemSamplingMgt"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCPublicGroupStateMgt"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServer"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCServerPublicGroups"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.IOPCSyncIO2"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCBROWSEELEMENT"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADER"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCGROUPHEADERWRITE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMATTRIBUTES"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMDEF"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER1"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADER2"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMHEADERWRITE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTIES"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMPROPERTY"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMRESULT"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMSTATE"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCITEMVQT"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.OPCSERVERSTATUS"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Constants"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Qualities"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.Rcw.Properties"> | ||||
|             <exclude /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.DataChangedEventHandler"> | ||||
|             <summary> | ||||
|             订阅变化项 | ||||
|             </summary> | ||||
|             <param name="values"></param> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient"> | ||||
|             <summary> | ||||
|             OPCDAClient | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ItemDicts"> | ||||
|             <summary> | ||||
|             当前保存的需订阅列表 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.#ctor(ThingsGateway.Foundation.Core.ILog)"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <param name="logger"></param> | ||||
|         </member> | ||||
|         <member name="E:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.DataChangedHandler"> | ||||
|             <summary> | ||||
|             数据变化事件 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.IsConnected"> | ||||
|             <summary> | ||||
|             是否连接成功 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.OPCNode"> | ||||
|             <summary> | ||||
|             当前配置 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItems(System.Collections.Generic.Dictionary{System.String,System.Collections.Generic.List{ThingsGateway.Foundation.Adapter.OPCDA.Da.OpcItem}})"> | ||||
|             <summary> | ||||
|             添加节点,需要在连接成功后执行 | ||||
|             </summary> | ||||
|             <param name="items">组名称/变量节点,注意每次添加的组名称不能相同</param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.AddItemsWithSave(System.Collections.Generic.List{System.String})"> | ||||
|             <summary> | ||||
|             设置节点并保存,每次重连会自动添加节点 | ||||
|             </summary> | ||||
|             <param name="items"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Connect"> | ||||
|             <summary> | ||||
|             连接服务器 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Disconnect"> | ||||
|             <summary> | ||||
|             断开连接 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetBrowseElements(System.String)"> | ||||
|             <summary> | ||||
|             浏览节点 | ||||
|             </summary> | ||||
|             <param name="itemId"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.GetServerStatus"> | ||||
|             <summary> | ||||
|             获取服务状态 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Init(ThingsGateway.Foundation.Adapter.OPCDA.OPCNode)"> | ||||
|             <summary> | ||||
|             初始化设置 | ||||
|             </summary> | ||||
|             <param name="node"></param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ReadItemsWithGroup(System.String)"> | ||||
|             <summary> | ||||
|             按OPC组读取组内变量,结果会在订阅事件中返回 | ||||
|             </summary> | ||||
|             <param name="groupName">组名称,值为null时读取全部组</param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.RemoveItems(System.Collections.Generic.List{System.String})"> | ||||
|             <summary> | ||||
|             移除节点 | ||||
|             </summary> | ||||
|             <param name="items"></param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.ToString"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.WriteItem(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken})"> | ||||
|             <summary> | ||||
|             批量写入值 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient.Dispose(System.Boolean)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode"> | ||||
|             <summary> | ||||
|             OPCDA连接配置项 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ActiveSubscribe"> | ||||
|             <summary> | ||||
|             是否订阅 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.CheckRate"> | ||||
|             <summary> | ||||
|             内部检测重连间隔/min | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.DeadBand"> | ||||
|             <summary> | ||||
|             死区 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.GroupSize"> | ||||
|             <summary> | ||||
|             分组大小 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCIP"> | ||||
|             <summary> | ||||
|             OPCIP | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.OPCName"> | ||||
|             <summary> | ||||
|             OPCNAME | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.UpdateRate"> | ||||
|             <summary> | ||||
|             订阅间隔 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCDA.OPCNode.ToString"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
| @@ -1,468 +0,0 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>ThingsGateway.Foundation.Adapter.OPCUA</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.RemoveWhere``1(System.Collections.Generic.ICollection{``0},System.Func{``0,System.Boolean})"> | ||||
|             <summary> | ||||
|             移除符合条件的元素 | ||||
|             </summary> | ||||
|             <typeparam name="T"></typeparam> | ||||
|             <param name="this"></param> | ||||
|             <param name="where"></param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.CollectionExtensions.SelectAsync``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,System.Threading.Tasks.Task{``1}})"> | ||||
|             <summary> | ||||
|             异步Select | ||||
|             </summary> | ||||
|             <typeparam name="T"></typeparam> | ||||
|             <typeparam name="TResult"></typeparam> | ||||
|             <param name="source"></param> | ||||
|             <param name="selector"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils"> | ||||
|             <summary> | ||||
|             辅助类 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.Browse(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean)"> | ||||
|             <summary> | ||||
|             Browses the address space and returns the references found. | ||||
|             </summary> | ||||
|             <param name="session">The session.</param> | ||||
|             <param name="nodesToBrowse">The set of browse operations to perform.</param> | ||||
|             <param name="throwOnError">if set to <c>true</c> a exception will be thrown on an error.</param> | ||||
|             <returns> | ||||
|             The references found. Null if an error occurred. | ||||
|             </returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.PrepareBrowseNext(Opc.Ua.BrowseResultCollection)"> | ||||
|             <summary> | ||||
|             Create the continuation point collection from the browse result | ||||
|             collection for the BrowseNext service. | ||||
|             </summary> | ||||
|             <param name="browseResultCollection">The browse result collection to use.</param> | ||||
|             <returns>The collection of continuation points for the BrowseNext service.</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescriptionCollection,System.Boolean,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             浏览地址空间 | ||||
|             </summary> | ||||
|             <param name="session"></param> | ||||
|             <param name="nodesToBrowse"></param> | ||||
|             <param name="throwOnError"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|             <exception cref="T:Opc.Ua.ServiceResultException"></exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseAsync(Opc.Ua.Client.ISession,Opc.Ua.BrowseDescription,System.Boolean,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             浏览地址空间 | ||||
|             </summary> | ||||
|             <param name="session"></param> | ||||
|             <param name="nodeToBrowse"></param> | ||||
|             <param name="throwOnError"></param> | ||||
|             <param name="cancellationToken"></param> | ||||
|             <returns></returns> | ||||
|             <exception cref="T:Opc.Ua.ServiceResultException"></exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.BrowseSuperTypesAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,System.Boolean)"> | ||||
|             <summary> | ||||
|             浏览地址空间并返回指定类型的所有节点 | ||||
|             </summary> | ||||
|             <param name="session"></param> | ||||
|             <param name="typeId"></param> | ||||
|             <param name="throwOnError"></param> | ||||
|             <returns></returns> | ||||
|             <exception cref="T:Opc.Ua.ServiceResultException"></exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForInstanceAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})"> | ||||
|             <summary> | ||||
|             Collects the fields for the instance. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsForType(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId})"> | ||||
|             <summary> | ||||
|             Collects the fields for the type. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ConstructEventAsync(Opc.Ua.Client.ISession,Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList,System.Collections.Generic.Dictionary{Opc.Ua.NodeId,System.Type},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.NodeId})"> | ||||
|             <summary> | ||||
|             Constructs an event object from a notification. | ||||
|             </summary> | ||||
|             <param name="session">The session.</param> | ||||
|             <param name="monitoredItem">The monitored item that produced the notification.</param> | ||||
|             <param name="notification">The notification.</param> | ||||
|             <param name="knownEventTypes">The known event types.</param> | ||||
|             <param name="eventTypeMappings">Mapping between event types and known event types.</param> | ||||
|             <returns> | ||||
|             The event object. Null if the notification is not a valid event type. | ||||
|             </returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.DiscoverServers(Opc.Ua.ApplicationConfiguration)"> | ||||
|             <summary> | ||||
|             Discovers the servers on the local machine. | ||||
|             </summary> | ||||
|             <param name="configuration">The configuration.</param> | ||||
|             <returns>A list of server urls.</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.FindEventType(Opc.Ua.Client.MonitoredItem,Opc.Ua.EventFieldList)"> | ||||
|             <summary> | ||||
|             Finds the type of the event for the notification. | ||||
|             </summary> | ||||
|             <param name="monitoredItem">The monitored item.</param> | ||||
|             <param name="notification">The notification.</param> | ||||
|             <returns>The NodeId of the EventType.</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAttributeDisplayText(Opc.Ua.Client.ISession,System.UInt32,Opc.Ua.Variant)"> | ||||
|             <summary> | ||||
|             指定的属性的显示文本。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.SelectEndpoint(System.String,System.Boolean)"> | ||||
|             <summary> | ||||
|             Finds the endpoint that best matches the current settings. | ||||
|             </summary> | ||||
|             <param name="discoveryUrl">The discovery URL.</param> | ||||
|             <param name="useSecurity">if set to <c>true</c> select an endpoint that uses security.</param> | ||||
|             <returns>The best available endpoint.</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.TranslateBrowsePaths(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.NamespaceTable,System.Threading.CancellationToken,System.String[])"> | ||||
|             <summary> | ||||
|             返回一组相对路径的节点id | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.CollectFieldsAsync(Opc.Ua.Client.ISession,Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection,Opc.Ua.SimpleAttributeOperandCollection,System.Collections.Generic.List{Opc.Ua.NodeId},System.Collections.Generic.Dictionary{Opc.Ua.NodeId,Opc.Ua.QualifiedNameCollection})"> | ||||
|             <summary> | ||||
|             Collects the fields for the instance node. | ||||
|             </summary> | ||||
|             <param name="session">The session.</param> | ||||
|             <param name="nodeId">The node id.</param> | ||||
|             <param name="parentPath">The parent path.</param> | ||||
|             <param name="fields">The event fields.</param> | ||||
|             <param name="fieldNodeIds">The node id for the declaration of the field.</param> | ||||
|             <param name="foundNodes">The table of found nodes.</param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.ContainsPath(Opc.Ua.SimpleAttributeOperandCollection,Opc.Ua.QualifiedNameCollection)"> | ||||
|             <summary> | ||||
|             判断指定的select子句包含的浏览路径。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetAccessLevelDisplayText(System.Byte)"> | ||||
|              <summary> | ||||
|             访问级别属性的显示文本。 | ||||
|              </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.FormUtils.GetEventNotifierDisplayText(System.Byte)"> | ||||
|             <summary> | ||||
|             事件通知属性的显示文本 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils"> | ||||
|             <summary> | ||||
|             扩展方法 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Decode(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)"> | ||||
|             <summary> | ||||
|             解析获取DataValue | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecoderObject(Opc.Ua.IServiceMessageContext,Opc.Ua.NodeId,Opc.Ua.BuiltInType,System.Int32,Newtonsoft.Json.Linq.JToken)"> | ||||
|             <summary> | ||||
|             解析获取object | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.DecodeRawData(Opc.Ua.JsonDecoder,Opc.Ua.BuiltInType,System.Int32,System.String)"> | ||||
|             <summary> | ||||
|             DecodeRawData | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.Encode(Opc.Ua.IServiceMessageContext,Opc.Ua.BuiltInType,System.Object)"> | ||||
|             <summary> | ||||
|             OPCUAValue解析为Jtoken | ||||
|             </summary> | ||||
|             <param name="Context"></param> | ||||
|             <param name="type"></param> | ||||
|             <param name="value"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CreateEncoder(Opc.Ua.IServiceMessageContext,System.IO.Stream,System.Boolean,System.Boolean,System.Boolean,System.Boolean)"> | ||||
|             <summary> | ||||
|             CreateEncoder | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.JsonUtils.CalculateActualValueRank(Newtonsoft.Json.Linq.JToken)"> | ||||
|             <summary> | ||||
|             维度 | ||||
|             </summary> | ||||
|             <param name="jToken"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode"> | ||||
|             <summary> | ||||
|             OPCUAClient配置项 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.OPCUrl"> | ||||
|             <summary> | ||||
|             OPCUrl | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UserName"> | ||||
|             <summary> | ||||
|             登录账号 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.Password"> | ||||
|             <summary> | ||||
|             登录密码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.CheckDomain"> | ||||
|             <summary> | ||||
|             检查域 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.UpdateRate"> | ||||
|             <summary> | ||||
|             更新间隔 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ActiveSubscribe"> | ||||
|             <summary> | ||||
|             是否订阅 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.GroupSize"> | ||||
|             <summary> | ||||
|             分组大小 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.DeadBand"> | ||||
|             <summary> | ||||
|             死区 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.KeepAliveInterval"> | ||||
|             <summary> | ||||
|             KeepAliveInterval/ms | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.IsUseSecurity"> | ||||
|             <summary> | ||||
|             安全策略 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCNode.ToString"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.DataChangedEventHandler"> | ||||
|             <summary> | ||||
|             订阅委托 | ||||
|             </summary> | ||||
|             <param name="value"></param> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient"> | ||||
|             <summary> | ||||
|             OPCUAClient | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCNode"> | ||||
|             <summary> | ||||
|             当前配置 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ProductUri"> | ||||
|             <summary> | ||||
|             ProductUri | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Variables"> | ||||
|             <summary> | ||||
|             当前保存的变量名称列表 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient._variableDicts"> | ||||
|             <summary> | ||||
|             当前的变量名称/OPC变量节点 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.dic_subscriptions"> | ||||
|             <summary> | ||||
|             当前的订阅组,组名称/组 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReConnectHandler"> | ||||
|             <summary> | ||||
|             SessionReconnectHandler | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.#ctor(ThingsGateway.Foundation.Core.ILog)"> | ||||
|             <summary> | ||||
|             默认的构造函数,实例化一个新的OPC UA类 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="E:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.DataChangedHandler"> | ||||
|             <summary> | ||||
|             订阅 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AppConfig"> | ||||
|             <summary> | ||||
|             配置信息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Connected"> | ||||
|             <summary> | ||||
|             连接状态 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.OPCUAName"> | ||||
|             <summary> | ||||
|             OPCUAClient | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Session"> | ||||
|             <summary> | ||||
|             当前活动会话。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.AddSubscriptionAsync(System.String,System.String[])"> | ||||
|             <summary> | ||||
|             新增订阅,需要指定订阅组名称,订阅的tag名数组 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveAllSubscription"> | ||||
|             <summary> | ||||
|             移除所有的订阅消息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.RemoveSubscription(System.String)"> | ||||
|             <summary> | ||||
|             移除订阅消息 | ||||
|             </summary> | ||||
|             <param name="subscriptionName">组名称</param> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.BrowseNodeReferenceAsync(System.String)"> | ||||
|             <summary> | ||||
|             浏览一个节点的引用 | ||||
|             </summary> | ||||
|             <param name="tag">节点值</param> | ||||
|             <returns>引用节点描述</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.CallMethodByNodeId(System.String,System.String,System.Object[])"> | ||||
|             <summary> | ||||
|             调用服务器的方法 | ||||
|             </summary> | ||||
|             <param name="tagParent">方法的父节点tag</param> | ||||
|             <param name="tag">方法的节点tag</param> | ||||
|             <param name="args">传递的参数</param> | ||||
|             <returns>输出的结果值</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadHistoryRawDataValues(System.String,System.DateTime,System.DateTime,System.UInt32,System.Boolean,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取历史数据 | ||||
|             </summary> | ||||
|             <param name="tag">节点的索引</param> | ||||
|             <param name="start">开始时间</param> | ||||
|             <param name="end">结束时间</param> | ||||
|             <param name="count">读取的个数</param> | ||||
|             <param name="containBound">是否包含边界</param> | ||||
|             <param name="cancellationToken">cancellationToken</param> | ||||
|             <returns>读取的数据列表</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync"> | ||||
|             <summary> | ||||
|             连接到服务器 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Disconnect"> | ||||
|             <summary> | ||||
|             断开连接。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ConnectAsync(System.String)"> | ||||
|             <summary> | ||||
|             Creates a new session. | ||||
|             </summary> | ||||
|             <returns>The new session object.</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(System.String[],System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             从服务器读取值 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.WriteNodeAsync(System.Collections.Generic.Dictionary{System.String,Newtonsoft.Json.Linq.JToken},System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             异步写opc标签 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadJTokenValueAsync(Opc.Ua.NodeId[],System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             从服务器读取值 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNodeAsync(System.String,System.Boolean,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             从服务器或缓存读取节点 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.String,System.UInt32,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取一个节点的所有属性 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributeAsync(System.Collections.Generic.List{System.String},System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取节点的所有属性 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.ReadNoteAttributes(System.String)"> | ||||
|             <summary> | ||||
|             读取一个节点的所有属性 | ||||
|             </summary> | ||||
|             <param name="tag">节点信息</param> | ||||
|             <returns>节点的特性值</returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Dispose(System.Boolean)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.OPCUA.OPCUAClient.Server_ReconnectComplete(System.Object,System.EventArgs)"> | ||||
|             <summary> | ||||
|             连接处理器连接事件处理完成。 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute"> | ||||
|             <summary> | ||||
|             读取属性过程中用于描述的 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Name"> | ||||
|             <summary> | ||||
|             属性的名称 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.StatusCode"> | ||||
|             <summary> | ||||
|             操作结果状态描述 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Type"> | ||||
|             <summary> | ||||
|             属性的类型描述 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.OPCUA.OPCNodeAttribute.Value"> | ||||
|             <summary> | ||||
|             属性的值,如果读取错误,返回文本描述 | ||||
|             </summary> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.Siemens; | ||||
|  | ||||
| /// <summary> | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Adapter.Siemens; | ||||
|  | ||||
| internal static class PackHelper | ||||
|   | ||||
| @@ -67,7 +67,6 @@ namespace ThingsGateway.Foundation.Adapter.Siemens | ||||
|                     break; | ||||
|  | ||||
|             } | ||||
|             tcpClient.Connected += Connected; | ||||
|  | ||||
|         } | ||||
|         /// <summary> | ||||
| @@ -293,8 +292,8 @@ namespace ThingsGateway.Foundation.Adapter.Siemens | ||||
|         /// <inheritdoc/> | ||||
|         public override void SetDataAdapter(object socketClient = null) | ||||
|         { | ||||
|             SiemensS7PLCDataHandleAdapter DataHandleAdapter = new(); | ||||
|             TcpClient.SetDataHandlingAdapter(DataHandleAdapter); | ||||
|             SiemensS7PLCDataHandleAdapter dataHandleAdapter = new(); | ||||
|             TcpClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|         } | ||||
|  | ||||
|  | ||||
| @@ -476,17 +475,20 @@ namespace ThingsGateway.Foundation.Adapter.Siemens | ||||
|         } | ||||
|         #endregion | ||||
|  | ||||
|         private void Connected(ITcpClient client, ConnectedEventArgs e) | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task Connected(ITcpClient client, ConnectedEventArgs e) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 var result1 = SendThenResponse(ISO_CR); | ||||
|                 NormalDataHandlingAdapter dataHandleAdapter = new(); | ||||
|                 TcpClient.SetDataHandlingAdapter(dataHandleAdapter); | ||||
|                 var result1 = await SendThenResponseAsync(ISO_CR); | ||||
|                 if (!result1.IsSuccess) | ||||
|                 { | ||||
|                     Logger?.Warning($"{client.IP} : {client.Port}:ISO_TP握手失败-{result1.Message}"); | ||||
|                     return; | ||||
|                 } | ||||
|                 var result2 = SendThenResponse(S7_PN); | ||||
|                 var result2 = await SendThenResponseAsync(S7_PN); | ||||
|                 if (!result2.IsSuccess) | ||||
|                 { | ||||
|                     Logger?.Warning($"{client.IP} : {client.Port}:PDU初始化失败-{result2.Message}"); | ||||
| @@ -499,7 +501,11 @@ namespace ThingsGateway.Foundation.Adapter.Siemens | ||||
|             { | ||||
|                 Logger.Exception(ex); | ||||
|             } | ||||
|  | ||||
|             finally | ||||
|             { | ||||
|                 SetDataAdapter(); | ||||
|             } | ||||
|             await base.Connected(client, e); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,336 +0,0 @@ | ||||
| <?xml version="1.0"?> | ||||
| <doc> | ||||
|     <assembly> | ||||
|         <name>ThingsGateway.Foundation.Adapter.Siemens</name> | ||||
|     </assembly> | ||||
|     <members> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7Area"> | ||||
|             <summary> | ||||
|             区域 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PE"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.PA"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.MK"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.DB"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.CT"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.TM"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AI"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7Area.AQ"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress"> | ||||
|             <summary> | ||||
|             西门子PLC地址数据信息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.BitCode"> | ||||
|             <summary> | ||||
|             bit位偏移 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DataCode"> | ||||
|             <summary> | ||||
|             数据块代码 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.DbBlock"> | ||||
|             <summary> | ||||
|             DB块数据信息 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetAddressStart(System.String,System.Boolean)"> | ||||
|             <summary> | ||||
|             获取起始地址 | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <param name="isCounterOrTimer"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.GetBitCode(System.String)"> | ||||
|             <summary> | ||||
|             获取bit | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String)"> | ||||
|             <summary> | ||||
|             解析地址 | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ParseFrom(System.String,System.Int32)"> | ||||
|             <summary> | ||||
|             解析地址 | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <param name="length"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.Parse(System.String,System.Int32)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensAddress.ToString"> | ||||
|             <inheritdoc /> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.DateTime"> | ||||
|             <summary> | ||||
|             https://github.com/S7NetPlus/s7netplus/blob/develop/S7.Net/Types/DateTime.cs | ||||
|             Contains the methods to convert between <see cref="T:System.DateTime"/> and S7 representation of datetime values. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMaximumDateTime"> | ||||
|             <summary> | ||||
|             The maximum <see cref="T:System.DateTime"/> value supported by the specification. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.DateTime.SpecMinimumDateTime"> | ||||
|             <summary> | ||||
|             The minimum <see cref="T:System.DateTime"/> value supported by the specification. | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.FromByteArray(System.Byte[])"> | ||||
|             <summary> | ||||
|             Parses a <see cref="T:System.DateTime"/> value from bytes. | ||||
|             </summary> | ||||
|             <param name="bytes">Input bytes read from PLC.</param> | ||||
|             <returns>A <see cref="T:System.DateTime"/> object representing the value read from PLC.</returns> | ||||
|             <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of | ||||
|               <paramref name="bytes"/> is not 8 or any value in <paramref name="bytes"/> | ||||
|               is outside the valid range of values.</exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToArray(System.Byte[])"> | ||||
|             <summary> | ||||
|             Parses an array of <see cref="T:System.DateTime"/> values from bytes. | ||||
|             </summary> | ||||
|             <param name="bytes">Input bytes read from PLC.</param> | ||||
|             <returns>An array of <see cref="T:System.DateTime"/> objects representing the values read from PLC.</returns> | ||||
|             <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the length of | ||||
|               <paramref name="bytes"/> is not a multiple of 8 or any value in | ||||
|               <paramref name="bytes"/> is outside the valid range of values.</exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime)"> | ||||
|             <summary> | ||||
|             Converts a <see cref="T:System.DateTime"/> value to a byte array. | ||||
|             </summary> | ||||
|             <param name="dateTime">The DateTime value to convert.</param> | ||||
|             <returns>A byte array containing the S7 date time representation of <paramref name="dateTime"/>.</returns> | ||||
|             <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the value of | ||||
|               <paramref name="dateTime"/> is before <see cref="P:SpecMinimumDateTime"/> | ||||
|               or after <see cref="P:SpecMaximumDateTime"/>.</exception> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.DateTime.ToByteArray(System.DateTime[])"> | ||||
|             <summary> | ||||
|             Converts an array of <see cref="T:System.DateTime"/> values to a byte array. | ||||
|             </summary> | ||||
|             <param name="dateTimes">The DateTime values to convert.</param> | ||||
|             <returns>A byte array containing the S7 date time representations of <paramref name="dateTimes"/>.</returns> | ||||
|             <exception cref="T:System.ArgumentOutOfRangeException">Thrown when any value of | ||||
|               <paramref name="dateTimes"/> is before <see cref="P:SpecMinimumDateTime"/> | ||||
|               or after <see cref="P:SpecMaximumDateTime"/>.</exception> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensHelper.S7_MULRW_HEADER"> | ||||
|             <summary> | ||||
|             S7连读写请求头(包含ISO头和COTP头)  | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Bit"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Byte"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Char"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Word"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Int"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DWord"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.DInt"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Real"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Counter"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.S7WordLength.Timer"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.HeadBytesLength"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage.CheckHeadBytes(System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S200Smart"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S300"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S400"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1200"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="F:ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum.S1500"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC"> | ||||
|             <summary> | ||||
|             相关命令含义源自网络资料/Shrap7/s7netplus | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.#ctor(ThingsGateway.Foundation.Core.TcpClient,ThingsGateway.Foundation.Adapter.Siemens.SiemensEnum)"> | ||||
|             <summary> | ||||
|             传入PLC类型,程序内会改变相应PLC类型的S7协议LocalTSAP, RemoteTSAP等 | ||||
|             </summary> | ||||
|             <param name="tcpClient"></param> | ||||
|             <param name="siemensPLCEnum"></param> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.CurrentPlc"> | ||||
|             <summary> | ||||
|             当前PLC类型 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetAddressDescription"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.GetBitOffset(System.String)"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <param name="address"></param> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.DestTSAP"> | ||||
|             <summary> | ||||
|             远程TSAP,需重新连接 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.LocalTSAP"> | ||||
|             <summary> | ||||
|             本地TSAP,需重新连接 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.PDULength"> | ||||
|             <summary> | ||||
|             PDULength | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Rack"> | ||||
|             <summary> | ||||
|             机架号,需重新连接 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="P:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.Slot"> | ||||
|             <summary> | ||||
|             槽号,需重新连接 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadAsync(System.String,System.Int32,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateAsync(System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取日期 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadDateTimeAsync(System.String,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取时间 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.ReadStringAsync(System.String,System.Text.Encoding,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             读取变长字符串 | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.SetDataAdapter"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.String,System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Byte[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteAsync(System.String,System.Boolean[],System.Threading.CancellationToken)"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateAsync(System.String,System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             写入日期 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLC.WriteDateTimeAsync(System.String,System.DateTime,System.Threading.CancellationToken)"> | ||||
|             <summary> | ||||
|             写入时间 | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="T:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter"> | ||||
|             <summary> | ||||
|             SiemensS7PLCDataHandleAdapter | ||||
|             </summary> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.PackCommand(System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.GetInstance"> | ||||
|             <summary> | ||||
|             <inheritdoc/> | ||||
|             </summary> | ||||
|             <returns></returns> | ||||
|         </member> | ||||
|         <member name="M:ThingsGateway.Foundation.Adapter.Siemens.SiemensS7PLCDataHandleAdapter.UnpackResponse(ThingsGateway.Foundation.Adapter.Siemens.SiemensMessage,System.Byte[],System.Byte[],System.Byte[])"> | ||||
|             <inheritdoc/> | ||||
|         </member> | ||||
|     </members> | ||||
| </doc> | ||||
| @@ -24,8 +24,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     public ReadWriteDevicesSerialSessionBase(SerialSession serialSession) | ||||
|     { | ||||
|         SerialSession = serialSession; | ||||
|         WaitingClientEx = SerialSession.GetWaitingClientEx(new() { BreakTrigger = true }); | ||||
|         SerialSession.Received += Received; | ||||
|         WaitingClientEx = SerialSession.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|         SerialSession.Received -= Received; | ||||
|         SerialSession.Connecting -= Connecting; | ||||
|         SerialSession.Connected -= Connected; | ||||
|         SerialSession.Disconnecting -= Disconnecting; | ||||
| @@ -34,26 +34,21 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|         SerialSession.Connected += Connected; | ||||
|         SerialSession.Disconnecting += Disconnecting; | ||||
|         SerialSession.Disconnected += Disconnected; | ||||
|         SerialSession.Received += Received; | ||||
|         Logger = SerialSession.Logger; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 接收解析 | ||||
|     /// </summary> | ||||
|     protected virtual void Received(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     /// <returns></returns> | ||||
|     protected virtual Task Received(SerialSession client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     } | ||||
|     private void Received(SerialSession client, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Received(byteBlock, requestInfo); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Logger.Exception(this, ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 串口管理对象 | ||||
| @@ -86,11 +81,12 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         Disconnect(); | ||||
|         SerialSession.Received -= Received; | ||||
|         SerialSession.Connecting -= Connecting; | ||||
|         SerialSession.Connected -= Connected; | ||||
|         SerialSession.Disconnecting -= Disconnecting; | ||||
|         SerialSession.Disconnected -= Disconnected; | ||||
|         Disconnect(); | ||||
|         if (CascadeDisposal) | ||||
|             SerialSession.SafeDispose(); | ||||
|     } | ||||
| @@ -100,8 +96,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             ResponsedData result = SerialSession.GetWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
| @@ -115,8 +111,8 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = await SerialSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             ResponsedData result = await SerialSession.GetWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
| @@ -130,24 +126,34 @@ public abstract class ReadWriteDevicesSerialSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         return SerialSession.SerialProperty.ToString(); | ||||
|     } | ||||
|     private void Connected(ISerialSession client, ConnectedEventArgs e) | ||||
|     /// <summary> | ||||
|     /// Connected | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     /// <returns></returns> | ||||
|     protected virtual Task Connected(ISerialSession client, ConnectedEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.SerialProperty.ToString() + "连接成功"); | ||||
|         SetDataAdapter(); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Connecting(ISerialSession client, SerialConnectingEventArgs e) | ||||
|     private Task Connecting(ISerialSession client, SerialConnectingEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.SerialProperty.ToString() + "正在连接"); | ||||
|         SetDataAdapter(); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Disconnected(ISerialSessionBase client, DisconnectEventArgs e) | ||||
|     private Task Disconnected(ISerialSessionBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.SerialProperty.ToString() + "断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Disconnecting(ISerialSessionBase client, DisconnectEventArgs e) | ||||
|     private Task Disconnecting(ISerialSessionBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.SerialProperty.ToString() + "正在主动断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
| } | ||||
| @@ -23,7 +23,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     public ReadWriteDevicesTcpClientBase(TcpClient tcpClient) | ||||
|     { | ||||
|         TcpClient = tcpClient; | ||||
|         WaitingClientEx = TcpClient.GetWaitingClientEx(new() { BreakTrigger = true }); | ||||
|         WaitingClientEx = TcpClient.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|         TcpClient.Connecting -= Connecting; | ||||
|         TcpClient.Connected -= Connected; | ||||
|         TcpClient.Disconnecting -= Disconnecting; | ||||
| @@ -59,7 +59,7 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     /// <inheritdoc/> | ||||
|     public override Task ConnectAsync(CancellationToken cancellationToken) | ||||
|     { | ||||
|         return TcpClient.ConnectAsync(ConnectTimeOut); | ||||
|         return TcpClient.ConnectAsync(ConnectTimeOut, cancellationToken); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
| @@ -72,11 +72,11 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         Disconnect(); | ||||
|         TcpClient.Connecting -= Connecting; | ||||
|         TcpClient.Connected -= Connected; | ||||
|         TcpClient.Disconnecting -= Disconnecting; | ||||
|         TcpClient.Disconnected -= Disconnected; | ||||
|         Disconnect(); | ||||
|         if (CascadeDisposal) | ||||
|             TcpClient.SafeDispose(); | ||||
|     } | ||||
| @@ -86,8 +86,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { BreakTrigger = true, ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, }; | ||||
|             ResponsedData result = TcpClient.GetWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
| @@ -101,8 +101,8 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = await TcpClient.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             ResponsedData result = await TcpClient.GetWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
| @@ -116,24 +116,34 @@ public abstract class ReadWriteDevicesTcpClientBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         return TcpClient.RemoteIPHost.ToString(); | ||||
|     } | ||||
|     private void Connected(ITcpClient client, ConnectedEventArgs e) | ||||
|     /// <summary> | ||||
|     /// Connected | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     /// <returns></returns> | ||||
|     protected virtual Task Connected(ITcpClient client, ConnectedEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.RemoteIPHost.ToString() + "连接成功"); | ||||
|         SetDataAdapter(); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Connecting(ITcpClient client, ConnectingEventArgs e) | ||||
|     private Task Connecting(ITcpClient client, ConnectingEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.RemoteIPHost.ToString() + "正在连接"); | ||||
|         SetDataAdapter(); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     private Task Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Disconnecting(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     private Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
| } | ||||
| @@ -23,9 +23,14 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase | ||||
|     public ReadWriteDevicesTcpServerBase(TcpService tcpService) | ||||
|     { | ||||
|         TcpService = tcpService; | ||||
|         TcpService.Received -= Received; | ||||
|         TcpService.Connecting -= Connecting; | ||||
|         TcpService.Connected -= Connected; | ||||
|         TcpService.Disconnecting -= Disconnecting; | ||||
|         TcpService.Disconnected -= Disconnected; | ||||
|         TcpService.Received += Received; | ||||
|         TcpService.Connecting += Connecting; | ||||
|         TcpService.Connected += Connected; | ||||
|         TcpService.Received += Received; | ||||
|         TcpService.Disconnecting += Disconnecting; | ||||
|         TcpService.Disconnected += Disconnected; | ||||
|         Logger = TcpService.Logger; | ||||
| @@ -63,65 +68,63 @@ public abstract class ReadWriteDevicesTcpServerBase : ReadWriteDevicesBase | ||||
|     /// <inheritdoc/> | ||||
|     public override void Dispose() | ||||
|     { | ||||
|         Disconnect(); | ||||
|         TcpService.Received -= Received; | ||||
|         TcpService.Connecting -= Connecting; | ||||
|         TcpService.Connected -= Connected; | ||||
|         TcpService.Disconnecting -= Disconnecting; | ||||
|         TcpService.Disconnected -= Disconnected; | ||||
|         Disconnect(); | ||||
|         if (CascadeDisposal) | ||||
|             TcpService.SafeDispose(); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 接收解析 | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     /// <returns></returns> | ||||
|     protected virtual Task Received(SocketClient client, ReceivedDataEventArgs e) | ||||
|     { | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|     { | ||||
|         return TcpService.ServerName; | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 接收解析 | ||||
|     /// </summary> | ||||
|     protected virtual void Received(SocketClient client, IRequestInfo requestInfo) | ||||
|     { | ||||
|  | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     protected virtual void Connected(SocketClient client, ConnectedEventArgs e) | ||||
|     protected virtual Task Connected(SocketClient client, ConnectedEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "连接成功"); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected virtual void Connecting(SocketClient client, ConnectingEventArgs e) | ||||
|     protected virtual Task Connecting(SocketClient client, ConnectingEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "正在连接"); | ||||
|         SetDataAdapter(client); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected virtual void Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     protected virtual Task Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected virtual void Disconnecting(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     protected virtual Task Disconnecting(ITcpClientBase client, DisconnectEventArgs e) | ||||
|     { | ||||
|         Logger?.Debug(client.IP + ":" + client.Port + "正在主动断开连接-" + e.Message); | ||||
|         return EasyTask.CompletedTask; | ||||
|     } | ||||
|  | ||||
|     private void Received(SocketClient client, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             Received(client, requestInfo); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             Logger.Exception(this, ex); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -22,7 +22,7 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         UdpSession = udpSession; | ||||
|         SetDataAdapter(); | ||||
|         WaitingClientEx = UdpSession.GetWaitingClientEx(new() { BreakTrigger = true }); | ||||
|         WaitingClientEx = UdpSession.GetWaitingClient(new() { ThrowBreakException = true }); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -64,8 +64,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             ResponsedData result = UdpSession.GetWaitingClient(waitingOptions).SendThenResponse(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
| @@ -79,8 +79,8 @@ public abstract class ReadWriteDevicesUdpSessionBase : ReadWriteDevicesBase | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true, AdapterFilter = AdapterFilter.NoneAll }; | ||||
|             ResponsedData result = await UdpSession.GetWaitingClientEx(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             waitingOptions ??= new WaitingOptions { ThrowBreakException = true }; | ||||
|             ResponsedData result = await UdpSession.GetWaitingClient(waitingOptions).SendThenResponseAsync(data, TimeOut, cancellationToken); | ||||
|             return OperResult.CreateSuccessResult(result.Data); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|   | ||||
| @@ -143,6 +143,21 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat | ||||
|         GoSend(bytes, 0, bytes.Length); | ||||
|         Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}"); | ||||
|     } | ||||
|     /// <summary> | ||||
|     /// 发送方法,会重新建立<see cref="Request"/> | ||||
|     /// </summary> | ||||
|     protected async Task GoSendAsync(byte[] item) | ||||
|     { | ||||
|         byte[] bytes; | ||||
|         if (IsSendPackCommand) | ||||
|             bytes = PackCommand(item); | ||||
|         else | ||||
|             bytes = item; | ||||
|         Request = GetInstance(); | ||||
|         Request.SendBytes = bytes; | ||||
|         await GoSendAsync(bytes, 0, bytes.Length); | ||||
|         Logger?.Trace($"{FoundationConst.LogMessageHeader}{ToString()}- 发送:{Request.SendBytes.ToHexString(' ')}"); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void PreviewSend(byte[] buffer, int offset, int length) | ||||
| @@ -150,6 +165,12 @@ public abstract class ReadWriteDevicesTcpDataHandleAdapter<TRequest> : CustomDat | ||||
|         GoSend(buffer); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         return GoSendAsync(buffer); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 报文拆包 | ||||
|     /// </summary> | ||||
|   | ||||
| @@ -128,11 +128,6 @@ public abstract class ReadWriteDevicesUdpDataHandleAdapter<TRequest> : UdpDataHa | ||||
|     { | ||||
|         throw new System.NotImplementedException();//因为设置了不支持拼接发送,所以该方法可以不实现。 | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     protected override void PreviewSend(IRequestInfo requestInfo) | ||||
|     { | ||||
|         throw new System.NotImplementedException();//因为设置了不支持,所以该方法可以不实现。 | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     protected override void Reset() | ||||
|   | ||||
| @@ -43,7 +43,7 @@ public abstract class MessageBase : OperResult<byte[]>, IMessage | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public abstract bool CheckHeadBytes(byte[] head); | ||||
|     public abstract bool CheckHeadBytes(byte[] heads); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 写入<see cref="SendBytes"/>后触发此方法 | ||||
|   | ||||
| @@ -51,7 +51,7 @@ public interface IMessage : IOperResult, IRequestInfo | ||||
|     /// <summary> | ||||
|     /// 检查头子节的合法性,并赋值<see cref="BodyLength"/><br /> | ||||
|     /// </summary> | ||||
|     /// <param name="head">接收的头子节</param> | ||||
|     /// <param name="heads">接收的头子节</param> | ||||
|     /// <returns>是否成功的结果</returns> | ||||
|     bool CheckHeadBytes(byte[] head); | ||||
|     bool CheckHeadBytes(byte[] heads); | ||||
| } | ||||
| @@ -19,5 +19,20 @@ | ||||
| 		<PackageReference Include="System.IO.Ports" Version="7.0.0" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\favicon-16x16.png" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\favicon-32x32.png" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\index.html" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\oauth2-redirect.html" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\openapi.json" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-bundle.js" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-es-bundle-core.js" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-es-bundle.js" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui-standalone-preset.js" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui.css" /> | ||||
| 		<EmbeddedResource Include="TouchSocket\WebApi.Swagger\api\swagger-ui.js" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|     /// 具有释放的对象。 | ||||
|     /// 并未实现析构函数相关。 | ||||
|     /// </summary> | ||||
|     public class DisposableObject : IDisposable | ||||
|     public partial class DisposableObject : IDisposable | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 判断是否已释放。 | ||||
|   | ||||
| @@ -69,14 +69,6 @@ namespace ThingsGateway.Foundation.Core | ||||
|             this.Owner = owner; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         public void SendInput(IRequestInfo requestInfo) | ||||
|         { | ||||
|             this.PreviewSend(requestInfo); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在解析时发生错误。 | ||||
| @@ -96,11 +88,6 @@ namespace ThingsGateway.Foundation.Core | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected abstract void PreviewSend(IRequestInfo requestInfo); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 重置解析器到初始状态,一般在<see cref="OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。 | ||||
|   | ||||
| @@ -78,6 +78,24 @@ namespace ThingsGateway.Foundation.Core | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return this.GoSendAsync(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -242,6 +242,131 @@ namespace ThingsGateway.Foundation.Core | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             if (length < this.MinPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送数据小于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|  | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|  | ||||
|             ByteBlock byteBlock = null; | ||||
|             byte[] lenBytes = null; | ||||
|  | ||||
|             switch (this.FixedHeaderType) | ||||
|             { | ||||
|                 case FixedHeaderType.Byte: | ||||
|                     { | ||||
|                         var dataLen = (byte)(length - offset); | ||||
|                         byteBlock = new ByteBlock(dataLen + 1); | ||||
|                         lenBytes = new byte[] { dataLen }; | ||||
|                         break; | ||||
|                     } | ||||
|                 case FixedHeaderType.Ushort: | ||||
|                     { | ||||
|                         var dataLen = (ushort)(length - offset); | ||||
|                         byteBlock = new ByteBlock(dataLen + 2); | ||||
|                         lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen); | ||||
|                         break; | ||||
|                     } | ||||
|                 case FixedHeaderType.Int: | ||||
|                     { | ||||
|                         var dataLen = length - offset; | ||||
|                         byteBlock = new ByteBlock(dataLen + 4); | ||||
|                         lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen); | ||||
|                         break; | ||||
|                     } | ||||
|             } | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 byteBlock.Write(lenBytes); | ||||
|                 byteBlock.Write(buffer, offset, length); | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             if (transferBytes.Count == 0) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             var length = 0; | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|  | ||||
|             if (length < this.MinPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送数据小于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|  | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送数据大于设定值,相同解析器可能无法收到有效数据,已终止发送"); | ||||
|             } | ||||
|  | ||||
|             ByteBlock byteBlock = null; | ||||
|             byte[] lenBytes = null; | ||||
|  | ||||
|             switch (this.FixedHeaderType) | ||||
|             { | ||||
|                 case FixedHeaderType.Byte: | ||||
|                     { | ||||
|                         var dataLen = (byte)length; | ||||
|                         byteBlock = new ByteBlock(dataLen + 1); | ||||
|                         lenBytes = new byte[] { dataLen }; | ||||
|                         break; | ||||
|                     } | ||||
|                 case FixedHeaderType.Ushort: | ||||
|                     { | ||||
|                         var dataLen = (ushort)length; | ||||
|                         byteBlock = new ByteBlock(dataLen + 2); | ||||
|                         lenBytes = TouchSocketBitConverter.Default.GetBytes(dataLen); | ||||
|                         break; | ||||
|                     } | ||||
|                 case FixedHeaderType.Int: | ||||
|                     { | ||||
|                         byteBlock = new ByteBlock(length + 4); | ||||
|                         lenBytes = TouchSocketBitConverter.Default.GetBytes(length); | ||||
|                         break; | ||||
|                     } | ||||
|             } | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 byteBlock.Write(lenBytes); | ||||
|                 foreach (var item in transferBytes) | ||||
|                 { | ||||
|                     byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                 } | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -183,6 +183,70 @@ namespace ThingsGateway.Foundation.Core | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             var dataLen = length - offset; | ||||
|             if (dataLen > this.FixedSize) | ||||
|             { | ||||
|                 throw new OverlengthException("发送的数据包长度大于FixedSize"); | ||||
|             } | ||||
|             var byteBlock = new ByteBlock(this.FixedSize); | ||||
|  | ||||
|             byteBlock.Write(buffer, offset, length); | ||||
|             for (var i = byteBlock.Pos; i < this.FixedSize; i++) | ||||
|             { | ||||
|                 byteBlock.Buffer[i] = 0; | ||||
|             } | ||||
|             byteBlock.SetLength(this.FixedSize); | ||||
|             try | ||||
|             { | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             var length = 0; | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|  | ||||
|             if (length > this.FixedSize) | ||||
|             { | ||||
|                 throw new OverlengthException("发送的数据包长度大于FixedSize"); | ||||
|             } | ||||
|             var byteBlock = new ByteBlock(this.FixedSize); | ||||
|  | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|             } | ||||
|  | ||||
|             Array.Clear(byteBlock.Buffer, byteBlock.Pos, this.FixedSize); | ||||
|             byteBlock.SetLength(this.FixedSize); | ||||
|             try | ||||
|             { | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -240,5 +240,64 @@ namespace ThingsGateway.Foundation.Core | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送的数据长度大于适配器设定的最大值,接收方可能会抛弃。"); | ||||
|             } | ||||
|             var dataLen = length - offset + this.m_terminatorCode.Length; | ||||
|             var byteBlock = new ByteBlock(dataLen); | ||||
|             byteBlock.Write(buffer, offset, length); | ||||
|             byteBlock.Write(this.m_terminatorCode); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             var length = 0; | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|             if (length > this.MaxPackageSize) | ||||
|             { | ||||
|                 throw new Exception("发送的数据长度大于适配器设定的最大值,接收方可能会抛弃。"); | ||||
|             } | ||||
|             var dataLen = length + this.m_terminatorCode.Length; | ||||
|             var byteBlock = new ByteBlock(dataLen); | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|             } | ||||
|  | ||||
|             byteBlock.Write(this.m_terminatorCode); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 await this.GoSendAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 byteBlock.Dispose(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -10,6 +10,19 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| #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 | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Core | ||||
| { | ||||
|     /// <summary> | ||||
| @@ -37,4 +50,4 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// </summary> | ||||
|         public bool? UpdateCacheTimeWhenRev { get; set; } | ||||
|     } | ||||
| } | ||||
| } | ||||
| @@ -36,9 +36,9 @@ namespace ThingsGateway.Foundation.Core | ||||
|         public TimeSpan CacheTimeout { get; set; } = TimeSpan.FromSeconds(1); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 是否启用缓存超时。默认true。 | ||||
|         /// 是否启用缓存超时。默认false。 | ||||
|         /// </summary> | ||||
|         public bool CacheTimeoutEnable { get; set; } = true; | ||||
|         public bool CacheTimeoutEnable { get; set; } = false; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当接收数据处理完成后,回调该函数执行接收 | ||||
| @@ -46,10 +46,15 @@ namespace ThingsGateway.Foundation.Core | ||||
|         public Action<ByteBlock, IRequestInfo> ReceivedCallBack { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当接收数据处理完成后,回调该函数执行发送 | ||||
|         /// 当发送数据处理完成后,回调该函数执行发送 | ||||
|         /// </summary> | ||||
|         public Action<byte[], int, int> SendCallBack { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据处理完成后,回调该函数执行异步发送 | ||||
|         /// </summary> | ||||
|         public Func<byte[], int, int, Task> SendAsyncCallBack { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 是否在收到数据时,即刷新缓存时间。默认true。 | ||||
|         /// <list type="number"> | ||||
| @@ -64,6 +69,12 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// </summary> | ||||
|         protected DateTime LastCacheTime { get; set; } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CanSendRequestInfo => false; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public override bool CanSplicingSend => false; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 收到数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
| @@ -80,6 +91,17 @@ namespace ThingsGateway.Foundation.Core | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         #region SendInput | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         public void SendInput(IRequestInfo requestInfo) | ||||
|         { | ||||
|             this.PreviewSend(requestInfo); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
| @@ -100,6 +122,98 @@ namespace ThingsGateway.Foundation.Core | ||||
|             this.PreviewSend(transferBytes); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         /// <returns></returns> | ||||
|         public Task SendInputAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             return this.PreviewSendAsync(requestInfo); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer"></param> | ||||
|         /// <param name="offset"></param> | ||||
|         /// <param name="length"></param> | ||||
|         public Task SendInputAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return this.PreviewSendAsync(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送数据的切入点,该方法由框架自动调用。 | ||||
|         /// </summary> | ||||
|         /// <param name="transferBytes"></param> | ||||
|         public Task SendInputAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             return this.PreviewSendAsync(transferBytes); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected virtual void PreviewSend(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">数据</param> | ||||
|         /// <param name="offset">偏移</param> | ||||
|         /// <param name="length">长度</param> | ||||
|         protected virtual void PreviewSend(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             this.GoSend(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 组合发送预处理数据, | ||||
|         /// 当属性SplicingSend实现为True时,系统才会调用该方法。 | ||||
|         /// </summary> | ||||
|         /// <param name="transferBytes">代发送数据组合</param> | ||||
|         protected virtual void PreviewSend(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected virtual Task PreviewSendAsync(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">数据</param> | ||||
|         /// <param name="offset">偏移</param> | ||||
|         /// <param name="length">长度</param> | ||||
|         protected virtual Task PreviewSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return this.GoSendAsync(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 组合发送预处理数据, | ||||
|         /// 当属性SplicingSend实现为True时,系统才会调用该方法。 | ||||
|         /// </summary> | ||||
|         /// <param name="transferBytes">代发送数据组合</param> | ||||
|         protected virtual Task PreviewSendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         #endregion SendInput | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
| @@ -130,27 +244,24 @@ namespace ThingsGateway.Foundation.Core | ||||
|             this.SendCallBack.Invoke(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 异步发送已经经过预先处理后的数据 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer"></param> | ||||
|         /// <param name="offset"></param> | ||||
|         /// <param name="length"></param> | ||||
|         /// <returns></returns> | ||||
|         protected Task GoSendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return this.SendAsyncCallBack.Invoke(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当接收到数据后预先处理数据,然后调用<see cref="GoReceived(ByteBlock, IRequestInfo)"/>处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         protected abstract void PreviewReceived(ByteBlock byteBlock); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前预先处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">数据</param> | ||||
|         /// <param name="offset">偏移</param> | ||||
|         /// <param name="length">长度</param> | ||||
|         protected abstract void PreviewSend(byte[] buffer, int offset, int length); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 组合发送预处理数据, | ||||
|         /// 当属性SplicingSend实现为True时,系统才会调用该方法。 | ||||
|         /// </summary> | ||||
|         /// <param name="transferBytes">代发送数据组合</param> | ||||
|         protected abstract void PreviewSend(IList<ArraySegment<byte>> transferBytes); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 重置解析器到初始状态,一般在<see cref="DataHandlingAdapter.OnError(string, bool, bool)"/>被触发时,由返回值指示是否调用。 | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -63,9 +63,11 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// <returns></returns> | ||||
|         public static SingleStreamDataAdapterTester CreateTester(SingleStreamDataHandlingAdapter adapter, int bufferLength = 1024, Action<ByteBlock, IRequestInfo> receivedCallBack = default) | ||||
|         { | ||||
|             var tester = new SingleStreamDataAdapterTester(); | ||||
|             tester.m_adapter = adapter; | ||||
|             tester.m_bufferLength = bufferLength; | ||||
|             var tester = new SingleStreamDataAdapterTester | ||||
|             { | ||||
|                 m_adapter = adapter, | ||||
|                 m_bufferLength = bufferLength | ||||
|             }; | ||||
|             adapter.SendCallBack = tester.SendCallback; | ||||
|             adapter.ReceivedCallBack = tester.OnReceived; | ||||
|             tester.m_receivedCallBack = receivedCallBack; | ||||
| @@ -129,7 +131,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|         { | ||||
|             while (!this.m_dispose) | ||||
|             { | ||||
|                 if (this.tryGet(out var byteBlocks)) | ||||
|                 if (this.TryGet(out var byteBlocks)) | ||||
|                 { | ||||
|                     foreach (var block in byteBlocks) | ||||
|                     { | ||||
| @@ -163,7 +165,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|             this.m_asyncBytes.Enqueue(asyncByte); | ||||
|         } | ||||
|  | ||||
|         private bool tryGet(out List<ByteBlock> byteBlocks) | ||||
|         private bool TryGet(out List<ByteBlock> byteBlocks) | ||||
|         { | ||||
|             byteBlocks = new List<ByteBlock>(); | ||||
|             ByteBlock block = null; | ||||
|   | ||||
| @@ -70,10 +70,9 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="fromType"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public object Resolve(Type fromType, object[] ps = null, string key = "") | ||||
|         public object Resolve(Type fromType, string key = "") | ||||
|         { | ||||
|             if (fromType == typeof(IContainer)) | ||||
|             { | ||||
| @@ -108,11 +107,11 @@ namespace ThingsGateway.Foundation.Core | ||||
|                             { | ||||
|                                 if (descriptor.ToType.IsGenericType) | ||||
|                                 { | ||||
|                                     return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()), ps)); | ||||
|                                     return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()))); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     return (descriptor.ToInstance = this.Create(descriptor, descriptor.ToType, ps)); | ||||
|                                     return descriptor.ToInstance = this.Create(descriptor, descriptor.ToType); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
| @@ -120,11 +119,11 @@ namespace ThingsGateway.Foundation.Core | ||||
|  | ||||
|                     if (descriptor.ToType.IsGenericType) | ||||
|                     { | ||||
|                         return this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments()), ps); | ||||
|                         return this.Create(descriptor, descriptor.ToType.MakeGenericType(fromType.GetGenericArguments())); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         return this.Create(descriptor, descriptor.ToType, ps); | ||||
|                         return this.Create(descriptor, descriptor.ToType); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @@ -143,10 +142,10 @@ namespace ThingsGateway.Foundation.Core | ||||
|                     } | ||||
|                     lock (descriptor) | ||||
|                     { | ||||
|                         return descriptor.ToInstance ??= this.Create(descriptor, descriptor.ToType, ps); | ||||
|                         return descriptor.ToInstance ??= this.Create(descriptor, descriptor.ToType); | ||||
|                     } | ||||
|                 } | ||||
|                 return this.Create(descriptor, descriptor.ToType, ps); | ||||
|                 return this.Create(descriptor, descriptor.ToType); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -172,7 +171,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|             this.m_registrations.TryRemove(k, out _); | ||||
|         } | ||||
|  | ||||
|         private object Create(DependencyDescriptor descriptor, Type toType, object[] ops) | ||||
|         private object Create(DependencyDescriptor descriptor, Type toType) | ||||
|         { | ||||
|             var ctor = toType.GetConstructors().FirstOrDefault(x => x.IsDefined(typeof(DependencyInjectAttribute), true)); | ||||
|             if (ctor is null) | ||||
| @@ -198,28 +197,21 @@ namespace ThingsGateway.Foundation.Core | ||||
|             { | ||||
|                 for (var i = 0; i < parameters.Length; i++) | ||||
|                 { | ||||
|                     if (ops != null && ops.Length - 1 >= i) | ||||
|                     if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string)) | ||||
|                     { | ||||
|                         ps[i] = ops[i]; | ||||
|                         ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string)) | ||||
|                         if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true)) | ||||
|                         { | ||||
|                             ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default; | ||||
|                             var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                             var type = attribute.Type ?? parameters[i].ParameterType; | ||||
|                             ps[i] = this.Resolve(type, attribute.Key); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true)) | ||||
|                             { | ||||
|                                 var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                                 var type = attribute.Type ?? parameters[i].ParameterType; | ||||
|                                 ps[i] = this.Resolve(type, default, attribute.Key); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 ps[i] = this.Resolve(parameters[i].ParameterType, null); | ||||
|                             } | ||||
|                             ps[i] = this.Resolve(parameters[i].ParameterType, null); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @@ -239,7 +231,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|                         { | ||||
|                             var attribute = item.GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                             var type = attribute.Type ?? item.PropertyType; | ||||
|                             obj = this.Resolve(type, default, attribute.Key); | ||||
|                             obj = this.Resolve(type, attribute.Key); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
| @@ -259,28 +251,21 @@ namespace ThingsGateway.Foundation.Core | ||||
|                     ps = new object[parameters.Length]; | ||||
|                     for (var i = 0; i < ps.Length; i++) | ||||
|                     { | ||||
|                         if (ops != null && ops.Length - 1 >= i) | ||||
|                         if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string)) | ||||
|                         { | ||||
|                             ps[i] = ops[i]; | ||||
|                             ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default; | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             if (parameters[i].ParameterType.IsPrimitive || parameters[i].ParameterType == typeof(string)) | ||||
|                             if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true)) | ||||
|                             { | ||||
|                                 ps[i] = parameters[i].HasDefaultValue ? parameters[i].DefaultValue : default; | ||||
|                                 var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                                 var type = attribute.Type ?? parameters[i].ParameterType; | ||||
|                                 ps[i] = this.Resolve(type, attribute.Key); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 if (parameters[i].IsDefined(typeof(DependencyInjectAttribute), true)) | ||||
|                                 { | ||||
|                                     var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                                     var type = attribute.Type ?? parameters[i].ParameterType; | ||||
|                                     ps[i] = this.Resolve(type, default, attribute.Key); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     ps[i] = this.Resolve(parameters[i].ParameterType, null); | ||||
|                                 } | ||||
|                                 ps[i] = this.Resolve(parameters[i].ParameterType, null); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|   | ||||
| @@ -381,35 +381,11 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T Resolve<T>(this IContainer container, object[] ps, string key = "") | ||||
|         public static T Resolve<T>(this IContainer container, string key = "") | ||||
|         { | ||||
|             return (T)container.Resolve(typeof(T), ps, key); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 创建类型对应的实例 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="container"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T Resolve<T>(this IContainer container) | ||||
|         { | ||||
|             return Resolve<T>(container, null); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 创建类型对应的实例 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T Resolve<T>(this IContainer container, string key) | ||||
|         { | ||||
|             return Resolve<T>(container, null, key); | ||||
|             return (T)container.Resolve(typeof(T), key); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -461,7 +437,7 @@ namespace ThingsGateway.Foundation.Core | ||||
|                             { | ||||
|                                 var attribute = parameters[i].GetCustomAttribute<DependencyInjectAttribute>(); | ||||
|                                 var type = attribute.Type ?? parameters[i].ParameterType; | ||||
|                                 ps[i] = container.Resolve(type, default, attribute.Key); | ||||
|                                 ps[i] = container.Resolve(type, attribute.Key); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
| @@ -489,47 +465,22 @@ namespace ThingsGateway.Foundation.Core | ||||
|             return (T)ResolveWithoutRoot(container, typeof(T)); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         ///  尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T TryResolve<T>(this IContainer container, object[] ps, string key = "") | ||||
|         { | ||||
|             return (T)container.TryResolve(typeof(T), ps, key); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         ///  尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。 | ||||
|         /// </summary> | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="fromType"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public static object TryResolve(this IContainer container, Type fromType, object[] ps, string key = "") | ||||
|         public static object TryResolve(this IContainer container, Type fromType, string key = "") | ||||
|         { | ||||
|             if (container.IsRegistered(fromType)) | ||||
|             { | ||||
|                 return container.Resolve(fromType, ps, key); | ||||
|                 return container.Resolve(fromType, key); | ||||
|             } | ||||
|             return default; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         ///  尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="container"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T TryResolve<T>(this IContainer container) | ||||
|         { | ||||
|             return TryResolve<T>(container, null); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 尝试创建类型对应的实例,如果类型没有注册,则会返回null或者默认值类型。 | ||||
|         /// </summary> | ||||
| @@ -537,9 +488,9 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// <param name="container"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T TryResolve<T>(this IContainer container, string key) | ||||
|         public static T TryResolve<T>(this IContainer container, string key = "") | ||||
|         { | ||||
|             return TryResolve<T>(container, null, key); | ||||
|             return (T)TryResolve(container, typeof(T), key); | ||||
|         } | ||||
|  | ||||
|         #endregion Resolve | ||||
|   | ||||
| @@ -34,10 +34,9 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// 创建目标类型的对应实例。 | ||||
|         /// </summary> | ||||
|         /// <param name="fromType"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         object Resolve(Type fromType, object[] ps = null, string key = ""); | ||||
|         object Resolve(Type fromType, string key = ""); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 判断某类型是否已经注册 | ||||
|   | ||||
| @@ -67,13 +67,13 @@ namespace ThingsGateway.Foundation.Core | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         /// <exception cref="Exception"></exception> | ||||
|         public object Resolve(Type fromType, object[] ps = null, string key = "") | ||||
|         public object Resolve(Type fromType, string key = "") | ||||
|         { | ||||
|             if (fromType.FullName == "ThingsGateway.Foundation.Core.IContainer") | ||||
|             { | ||||
|                 return this; | ||||
|             } | ||||
|             if (this.TryResolve(fromType, out var instance, ps, key)) | ||||
|             if (this.TryResolve(fromType, out var instance, key)) | ||||
|             { | ||||
|                 return instance; | ||||
|             } | ||||
| @@ -100,10 +100,9 @@ namespace ThingsGateway.Foundation.Core | ||||
|         /// </summary> | ||||
|         /// <param name="fromType"></param> | ||||
|         /// <param name="instance"></param> | ||||
|         /// <param name="ps"></param> | ||||
|         /// <param name="key"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual bool TryResolve(Type fromType, out object instance, object[] ps = null, string key = "") | ||||
|         protected virtual bool TryResolve(Type fromType, out object instance, string key = "") | ||||
|         { | ||||
|             if (key.IsNullOrEmpty()) | ||||
|             { | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Core | ||||
| { | ||||
|     /// <summary> | ||||
| @@ -29,5 +30,24 @@ namespace ThingsGateway.Foundation.Core | ||||
|     /// </summary> | ||||
|     public static class TaskExtension | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 同步获取配置ConfigureAwait为false时的结果。 | ||||
|         /// </summary> | ||||
|         /// <typeparam name="T"></typeparam> | ||||
|         /// <param name="task"></param> | ||||
|         /// <returns></returns> | ||||
|         public static T GetFalseAwaitResult<T>(this Task<T> task) | ||||
|         { | ||||
|             return task.ConfigureAwait(false).GetAwaiter().GetResult(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 同步配置ConfigureAwait为false时的执行。 | ||||
|         /// </summary> | ||||
|         /// <param name="task"></param> | ||||
|         public static void GetFalseAwaitResult(this Task task) | ||||
|         { | ||||
|             task.ConfigureAwait(false).GetAwaiter().GetResult(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -30,14 +30,6 @@ namespace ThingsGateway.Foundation.Core | ||||
|     /// </summary> | ||||
|     public interface IPlugin : IDisposable | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 插件执行顺序 | ||||
|         /// <para>该属性值越大,越靠前执行。值相等时,按添加先后顺序</para> | ||||
|         /// <para>该属性效果,仅在<see cref="IPluginsManager.Add(IPlugin)"/>之前设置有效。</para> | ||||
|         /// </summary> | ||||
|         [Obsolete("该属性已被弃用,插件顺序将直接由添加顺序决定。本设置将在正式版发布时直接删除", true)] | ||||
|         int Order { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 在插件被成功添加在<see cref="IPluginsManager"/>时执行。 | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -17,9 +17,6 @@ namespace ThingsGateway.Foundation.Core | ||||
|     /// </summary> | ||||
|     public class PluginBase : DisposableObject, IPlugin | ||||
|     { | ||||
|         /// <inheritdoc/> | ||||
|         [Obsolete("该属性已被弃用,插件顺序将直接由添加顺序决定。本设置将在正式版发布时直接删除", true)] | ||||
|         public int Order { get; set; } | ||||
|  | ||||
|         /// <inheritdoc cref="IPlugin.Loaded(IPluginsManager)"/> | ||||
|         protected virtual void Loaded(IPluginsManager pluginsManager) | ||||
|   | ||||
| @@ -184,7 +184,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 if (!this.Online) | ||||
|                 { | ||||
|                     await base.ConnectAsync(timeout); | ||||
|                     await base.ConnectAsync(timeout, token); | ||||
|                 } | ||||
|  | ||||
|                 var request = new HttpRequest() | ||||
| @@ -223,20 +223,20 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message) | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message) | ||||
|             { | ||||
|                 if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|                 { | ||||
|                     if (this.PluginsManager.Enable) | ||||
|                     { | ||||
|                         this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                         await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                     } | ||||
|                 } | ||||
|                 return false; | ||||
|                 return; | ||||
|             } | ||||
|             return base.HandleReceivedData(byteBlock, requestInfo); | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
| @@ -251,9 +251,9 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             base.OnDisconnected(e); | ||||
|             await base.OnDisconnected(e); | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -62,10 +62,10 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnConnected(TClient socketClient, ConnectedEventArgs e) | ||||
|         protected override async Task OnConnected(TClient socketClient, ConnectedEventArgs e) | ||||
|         { | ||||
|             socketClient.m_internalOnRpcActorInit = this.PrivateOnRpcActorInit; | ||||
|             base.OnConnected(socketClient, e); | ||||
|             await base.OnConnected(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         private IDmtpActor OnServiceFindDmtpActor(string id) | ||||
|   | ||||
| @@ -96,42 +96,55 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         ///// <inheritdoc/> | ||||
|         //protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         //{ | ||||
|         //    if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message) | ||||
|         //    { | ||||
|         //        if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|         //        { | ||||
|         //            if (this.PluginsManager.Enable) | ||||
|         //            { | ||||
|         //                this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|         //            } | ||||
|         //        } | ||||
|  | ||||
|         //        return false; | ||||
|         //    } | ||||
|         //    else | ||||
|         //    { | ||||
|         //        return base.HandleReceivedData(byteBlock, requestInfo); | ||||
|         //    } | ||||
|         //} | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && requestInfo is DmtpMessage message) | ||||
|             if (this.Protocol == DmtpUtility.DmtpProtocol && e.RequestInfo is DmtpMessage message) | ||||
|             { | ||||
|                 if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|                 { | ||||
|                     if (this.PluginsManager.Enable) | ||||
|                     { | ||||
|                         this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                     } | ||||
|                     await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 return base.HandleReceivedData(byteBlock, requestInfo); | ||||
|             } | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.DmtpActor?.Close(false, e.Message); | ||||
|             base.OnDisconnected(e); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="request"></param> | ||||
|         protected override void OnReceivedHttpRequest(HttpRequest request) | ||||
|         protected override async Task OnReceivedHttpRequest(HttpRequest request) | ||||
|         { | ||||
|             if (request.IsMethod(DmtpUtility.Dmtp) && request.IsUpgrade() && | ||||
|                 string.Equals(request.Headers.Get(HttpHeaders.Upgrade), DmtpUtility.Dmtp, StringComparison.OrdinalIgnoreCase)) | ||||
| @@ -142,7 +155,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 this.DefaultSend(new HttpResponse().SetStatus(101, "Switching Protocols").BuildAsBytes()); | ||||
|                 return; | ||||
|             } | ||||
|             base.OnReceivedHttpRequest(request); | ||||
|             await base.OnReceivedHttpRequest(request); | ||||
|         } | ||||
|  | ||||
|         private void SetRpcActor(DmtpActor actor) | ||||
|   | ||||
| @@ -38,23 +38,24 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             this.Protocol = DmtpUtility.DmtpProtocol; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.Id"/> | ||||
|         public string Id => this.DmtpActor.Id; | ||||
|  | ||||
|         #region 字段 | ||||
|  | ||||
|         private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|         private bool m_allowRoute; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private SealedDmtpActor m_smtpActor; | ||||
|         private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|  | ||||
|         #endregion 字段 | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 发送<see cref="IDmtpActor"/>关闭消息。 | ||||
|         /// </summary> | ||||
| @@ -153,7 +154,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|                 } | ||||
|                 if (!this.Online) | ||||
|                 { | ||||
|                     await base.ConnectAsync(timeout); | ||||
|                     await base.ConnectAsync(timeout, token); | ||||
|                 } | ||||
|  | ||||
|                 await this.m_smtpActor.HandshakeAsync(this.Config.GetValue(DmtpConfigExtension.VerifyTokenProperty), | ||||
| @@ -235,20 +236,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         { | ||||
|             var message = (DmtpMessage)requestInfo; | ||||
|             if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|             { | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|                     this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void LoadConfig(TouchSocketConfig config) | ||||
|         { | ||||
| @@ -274,14 +261,31 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             base.OnDisconnected(e); | ||||
|             await base.OnDisconnected(e); | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             var message = (DmtpMessage)e.RequestInfo; | ||||
|             if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|             { | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|             } | ||||
|  | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         #region 内部委托绑定 | ||||
|  | ||||
|         private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private void OnDmtpActorClose(DmtpActor actor, string msg) | ||||
|         { | ||||
|             base.Close(msg); | ||||
| @@ -330,11 +334,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             this.OnRouting(e); | ||||
|         } | ||||
|  | ||||
|         private void DmtpActorSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
|         { | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         #endregion 内部委托绑定 | ||||
|  | ||||
|         #region 事件触发 | ||||
|   | ||||
| @@ -68,14 +68,14 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected override void OnConnecting(TClient socketClient, ConnectingEventArgs e) | ||||
|         protected override async Task OnConnecting(TClient socketClient, ConnectingEventArgs e) | ||||
|         { | ||||
|             socketClient.SetDmtpActor(new SealedDmtpActor(this.m_allowRoute) | ||||
|             { | ||||
|                 Id = e.Id, | ||||
|                 OnFindDmtpActor = this.m_allowRoute ? (this.m_findDmtpActor ?? this.OnServiceFindDmtpActor) : null | ||||
|             }); | ||||
|             base.OnConnecting(socketClient, e); | ||||
|             await base.OnConnecting(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         private IDmtpActor OnServiceFindDmtpActor(string id) | ||||
|   | ||||
| @@ -40,12 +40,12 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             this.Protocol = DmtpUtility.DmtpProtocol; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IDmtpActor DmtpActor { get => this.m_smtpActor; } | ||||
|  | ||||
|         /// <inheritdoc cref="IDmtpActor.IsHandshaked"/> | ||||
|         public bool IsHandshaked => this.DmtpActor != null && this.DmtpActor.IsHandshaked; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 验证超时时间,默认为3000ms | ||||
|         /// </summary> | ||||
| @@ -201,26 +201,23 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             var message = (DmtpMessage)requestInfo; | ||||
|             var message = (DmtpMessage)e.RequestInfo; | ||||
|             if (!this.m_smtpActor.InputReceivedData(message)) | ||||
|             { | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|                     this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|             } | ||||
|             return false; | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnConnected(ConnectedEventArgs e) | ||||
|         protected override async Task OnConnected(ConnectedEventArgs e) | ||||
|         { | ||||
|             this.m_smtpActor.Id = this.Id; | ||||
|             base.OnConnected(e); | ||||
|             await base.OnConnected(e); | ||||
|  | ||||
|             Task.Run(async () => | ||||
|             _ = Task.Run(async () => | ||||
|             { | ||||
|                 await Task.Delay(this.VerifyTimeout); | ||||
|                 if (!this.IsHandshaked) | ||||
| @@ -232,15 +229,10 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.DmtpActor.Close(false, e.Message); | ||||
|             base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         private void ThisOnResetId(DmtpActor rpcActor, WaitSetId waitSetId) | ||||
|         { | ||||
|             this.DirectResetId(waitSetId.NewId); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         private void ThisDmtpActorOutputSend(DmtpActor actor, ArraySegment<byte>[] transferBytes) | ||||
| @@ -248,6 +240,11 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             base.Send(transferBytes); | ||||
|         } | ||||
|  | ||||
|         private void ThisOnResetId(DmtpActor rpcActor, WaitSetId waitSetId) | ||||
|         { | ||||
|             this.DirectResetId(waitSetId.NewId); | ||||
|         } | ||||
|  | ||||
|         #region 发送 | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -75,20 +75,20 @@ namespace ThingsGateway.Foundation.Dmtp.Rpc | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(UdpReceivedDataEventArgs e) | ||||
|         { | ||||
|             var client = this.PrivateGetUdpDmtpClient(remoteEndPoint); | ||||
|             var client = this.PrivateGetUdpDmtpClient(e.EndPoint); | ||||
|             if (client == null) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             var message = DmtpMessage.CreateFrom(byteBlock); | ||||
|             var message = DmtpMessage.CreateFrom(e.ByteBlock); | ||||
|             if (!client.InputReceivedData(message)) | ||||
|             { | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|                     this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message)); | ||||
|                     await this.PluginsManager.RaiseAsync(nameof(IDmtpReceivedPlugin.OnDmtpReceived), client, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -49,9 +49,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         #region 字段 | ||||
| #pragma warning disable CS0414 | ||||
|         private bool m_allowRoute; | ||||
| #pragma warning restore CS0414 | ||||
|  | ||||
|         private ClientWebSocket m_client; | ||||
|         private Func<string, IDmtpActor> m_findDmtpActor; | ||||
|         private ValueCounter m_receiveCounter; | ||||
| @@ -236,18 +234,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             this.DmtpActor.ResetId(newId); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 配置 | ||||
|         /// </summary> | ||||
|         /// <param name="ipHost"></param> | ||||
|         /// <returns></returns> | ||||
|         public IWebSocketDmtpClient Setup(string ipHost) | ||||
|         { | ||||
|             var config = new TouchSocketConfig(); | ||||
|             config.SetRemoteIPHost(new IPHost(ipHost)); | ||||
|             return this.Setup(config); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 配置 | ||||
|         /// </summary> | ||||
| @@ -297,7 +283,6 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|  | ||||
|             if (this.Container.IsRegistered(typeof(IDmtpRouteService))) | ||||
|             { | ||||
|                 this.m_allowRoute = true; | ||||
|                 this.m_findDmtpActor = this.Container.Resolve<IDmtpRouteService>().FindDmtpActor; | ||||
|             } | ||||
|         } | ||||
| @@ -421,10 +406,7 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|             var message = (DmtpMessage)requestInfo; | ||||
|             if (!this.m_dmtpActor.InputReceivedData(message)) | ||||
|             { | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|                     this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|                 } | ||||
|                 this.PluginsManager.Raise(nameof(IDmtpReceivedPlugin.OnDmtpReceived), this, new DmtpMessageEventArgs(message)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -534,5 +516,28 @@ namespace ThingsGateway.Foundation.Dmtp | ||||
|         } | ||||
|  | ||||
|         #endregion 事件触发 | ||||
|  | ||||
|         #region Receiver | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 不支持该功能 | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         /// <exception cref="NotSupportedException"></exception> | ||||
|         public IReceiver CreateReceiver() | ||||
|         { | ||||
|             throw new NotSupportedException("不支持该功能"); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 不支持该功能 | ||||
|         /// </summary> | ||||
|         /// <exception cref="NotSupportedException"></exception> | ||||
|         public void ClearReceiver() | ||||
|         { | ||||
|             throw new NotSupportedException("不支持该功能"); | ||||
|         } | ||||
|  | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
| @@ -1507,7 +1507,7 @@ namespace ThingsGateway.Foundation.Dmtp.FileTransfer | ||||
|                     waitFileSection.Message = ex.Message; | ||||
|                 } | ||||
|  | ||||
|                 waitFileSection.Value.Dispose(); | ||||
|                 waitFileSection.Value.SafeDispose(); | ||||
|                 waitFileSection.Value = default; | ||||
|                 using (var byteBlock = new ByteBlock()) | ||||
|                 { | ||||
|   | ||||
| @@ -213,14 +213,11 @@ namespace ThingsGateway.Foundation.Http | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (requestInfo is HttpResponse response) | ||||
|             if (e.RequestInfo is HttpResponse response) | ||||
|             { | ||||
|                 if (this.m_getContent) | ||||
|                 { | ||||
| @@ -229,18 +226,18 @@ namespace ThingsGateway.Foundation.Http | ||||
|                 this.m_waitData.Set(response); | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|             return base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected override void OnConnecting(ConnectingEventArgs e) | ||||
|         protected override async Task OnConnecting(ConnectingEventArgs e) | ||||
|         { | ||||
|             this.Protocol = Protocol.Http; | ||||
|             this.SetDataHandlingAdapter(new HttpClientDataHandlingAdapter()); | ||||
|             base.OnConnecting(e); | ||||
|             await base.OnConnecting(e); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -20,6 +20,8 @@ using System.Threading.Tasks; | ||||
| using ThingsGateway.Foundation.Core; | ||||
| using ThingsGateway.Foundation.Sockets; | ||||
|  | ||||
| using HttpClient = System.Net.Http.HttpClient; | ||||
| using HttpMethod = System.Net.Http.HttpMethod; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Http | ||||
| { | ||||
| @@ -100,16 +102,6 @@ namespace ThingsGateway.Foundation.Http | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 配置 | ||||
|         /// </summary> | ||||
|         /// <param name="remoteIPHost"></param> | ||||
|         /// <returns></returns> | ||||
|         public HttpClientSlim Setup(string remoteIPHost) | ||||
|         { | ||||
|             return this.Setup(new TouchSocketConfig().SetRemoteIPHost(remoteIPHost)); | ||||
|         } | ||||
|  | ||||
|         private void BuildConfig(TouchSocketConfig config) | ||||
|         { | ||||
|             this.Config = config; | ||||
|   | ||||
| @@ -39,34 +39,35 @@ namespace ThingsGateway.Foundation.Http | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override void OnConnecting(ConnectingEventArgs e) | ||||
|         protected override async Task OnConnecting(ConnectingEventArgs e) | ||||
|         { | ||||
|             this.SetDataHandlingAdapter(new HttpServerDataHandlingAdapter()); | ||||
|             base.OnConnecting(e); | ||||
|             await base.OnConnecting(e); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (requestInfo is HttpRequest request) | ||||
|             if (e.RequestInfo is HttpRequest request) | ||||
|             { | ||||
|                 this.OnReceivedHttpRequest(request); | ||||
|                 await this.OnReceivedHttpRequest(request); | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当收到到Http请求时。覆盖父类方法将不会触发插件。 | ||||
|         /// </summary> | ||||
|         protected virtual void OnReceivedHttpRequest(HttpRequest request) | ||||
|         protected virtual Task OnReceivedHttpRequest(HttpRequest request) | ||||
|         { | ||||
|             if (this.PluginsManager.GetPluginCount(nameof(IHttpPlugin.OnHttpRequest)) > 0) | ||||
|             { | ||||
|                 var e = new HttpContextEventArgs(new HttpContext(request)); | ||||
|  | ||||
|                 this.PluginsManager.Raise(nameof(IHttpPlugin.OnHttpRequest), this, e); | ||||
|                 return this.PluginsManager.RaiseAsync(nameof(IHttpPlugin.OnHttpRequest), this, e); | ||||
|             } | ||||
|  | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,37 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Http | ||||
| { | ||||
|     /// <summary> | ||||
|     /// IHttpDeletePlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpDeletePlugin<in TClient> : IPlugin where TClient : IHttpSocketClient | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 在收到Delete时 | ||||
|         /// </summary> | ||||
|         /// <param name="client"></param> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         Task OnHttpDelete(TClient client, HttpContextEventArgs e); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// IHttpDeletePlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpDeletePlugin : IHttpDeletePlugin<IHttpSocketClient> | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @@ -1,37 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Http | ||||
| { | ||||
|     /// <summary> | ||||
|     /// IHttpGetPlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpGetPlugin<in TClient> : IPlugin where TClient : IHttpSocketClient | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 在收到Get时 | ||||
|         /// </summary> | ||||
|         /// <param name="client"></param> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         Task OnHttpGet(TClient client, HttpContextEventArgs e); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// IHttpGetPlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpGetPlugin : IHttpGetPlugin<IHttpSocketClient> | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @@ -31,8 +31,7 @@ namespace ThingsGateway.Foundation.Http | ||||
|     public interface IHttpPlugin<in TClient> : IPlugin where TClient : IHttpSocketClient | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 在收到Http请求时。注意:此插件的执行在<see cref="IHttpGetPlugin"/>,<see cref="IHttpPostPlugin"/>, | ||||
|         /// <see cref="IHttpDeletePlugin"/>,<see cref="IHttpPutPlugin"/>之前。 | ||||
|         /// 在收到Http请求时 | ||||
|         /// </summary> | ||||
|         /// <param name="client"></param> | ||||
|         /// <param name="e"></param> | ||||
|   | ||||
| @@ -1,37 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  QQ群:605534569 | ||||
| //------------------------------------------------------------------------------ | ||||
| #endregion | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Http | ||||
| { | ||||
|     /// <summary> | ||||
|     /// IHttpPostPlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpPostPlugin<in TClient> : IPlugin where TClient : IHttpSocketClient | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 在收到Post时 | ||||
|         /// </summary> | ||||
|         /// <param name="client"></param> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         Task OnHttpPost(TClient client, HttpContextEventArgs e); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// IHttpPostPlugin | ||||
|     /// </summary> | ||||
|     [Obsolete("该插件已被弃用,请考虑使用“IHttpPlugin”插件代替使用。本插件将在正式版发布时直接移除。", true)] | ||||
|     public interface IHttpPostPlugin : IHttpPostPlugin<IHttpSocketClient> | ||||
|     { | ||||
|     } | ||||
| } | ||||
| @@ -75,7 +75,17 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame); | ||||
|         } | ||||
|  | ||||
| #if NET6_0_OR_GREATER | ||||
|         public async ValueTask<WebSocketReceiveResult> ValueReadAsync(CancellationToken token) | ||||
|         { | ||||
|             if (!this.m_receive) | ||||
|             { | ||||
|                 return new WebSocketReceiveResult(this.ComplateRead, null); | ||||
|             } | ||||
|             await this.m_resetEventForRead.WaitOneAsync(token); | ||||
|             return new WebSocketReceiveResult(this.ComplateRead, this.m_dataFrame); | ||||
|         } | ||||
| #endif | ||||
|         #region 发送 | ||||
|         public void Send(WSDataFrame dataFrame, bool endOfMessage = true) | ||||
|         { | ||||
| @@ -145,7 +155,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|  | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.m_client.RemoveValue(WebSocketClientExtensions.WebSocketProperty); | ||||
|             this.m_client.RemoveValue(WebSocketClientExtension.WebSocketProperty); | ||||
|             this.m_resetEventForComplateRead.SafeDispose(); | ||||
|             this.m_resetEventForRead.SafeDispose(); | ||||
|             this.m_dataFrame = null; | ||||
| @@ -154,8 +164,8 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|  | ||||
|         private void ComplateRead() | ||||
|         { | ||||
|             this.m_resetEventForComplateRead.Set(); | ||||
|             this.m_dataFrame = default; | ||||
|             this.m_resetEventForComplateRead.Set(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -41,5 +41,10 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// WebSocket数据帧 | ||||
|         /// </summary> | ||||
|         public WSDataFrame DataFrame { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 连接已关闭 | ||||
|         /// </summary> | ||||
|         public bool IsClosed => this.DataFrame == null; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -39,10 +39,14 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="dataFrame"></param> | ||||
|         protected override void OnHandleWSDataFrame(WSDataFrame dataFrame) | ||||
|         protected override async Task OnReceivedWSDataFrame(WSDataFrame dataFrame) | ||||
|         { | ||||
|             this.Received?.Invoke(this, dataFrame); | ||||
|             base.OnHandleWSDataFrame(dataFrame); | ||||
|             if (this.Received != null) | ||||
|             { | ||||
|                 await this.Received.Invoke(this, dataFrame); | ||||
|             } | ||||
|  | ||||
|             await base.OnReceivedWSDataFrame(dataFrame); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -211,20 +215,44 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|  | ||||
|         #endregion 事件 | ||||
|  | ||||
|         ///// <inheritdoc/> | ||||
|         //protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         //{ | ||||
|         //    if (this.GetHandshaked()) | ||||
|         //    { | ||||
|         //        var dataFrame = (WSDataFrame)requestInfo; | ||||
|         //        this.OnReceivedWSDataFrame(dataFrame); | ||||
|         //    } | ||||
|         //    else | ||||
|         //    { | ||||
|         //        if (requestInfo is HttpResponse response) | ||||
|         //        { | ||||
|         //            response.Flag = false; | ||||
|         //            base.HandleReceivedData(byteBlock, requestInfo); | ||||
|         //            SpinWait.SpinUntil(() => | ||||
|         //            { | ||||
|         //                return (bool)response.Flag; | ||||
|         //            }, 3000); | ||||
|         //        } | ||||
|         //    } | ||||
|  | ||||
|         //    return false; | ||||
|         //} | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|         { | ||||
|             if (this.GetHandshaked()) | ||||
|             { | ||||
|                 var dataFrame = (WSDataFrame)requestInfo; | ||||
|                 this.OnHandleWSDataFrame(dataFrame); | ||||
|                 var dataFrame = (WSDataFrame)e.RequestInfo; | ||||
|                 await this.OnReceivedWSDataFrame(dataFrame); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (requestInfo is HttpResponse response) | ||||
|                 if (e.RequestInfo is HttpResponse response) | ||||
|                 { | ||||
|                     response.Flag = false; | ||||
|                     base.HandleReceivedData(byteBlock, requestInfo); | ||||
|                     await base.ReceivedData(e); | ||||
|                     SpinWait.SpinUntil(() => | ||||
|                     { | ||||
|                         return (bool)response.Flag; | ||||
| @@ -232,32 +260,32 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             this.SetValue(WebSocketFeature.HandshakedProperty, false); | ||||
|             if (this.TryGetValue(WebSocketClientExtensions.WebSocketProperty, out var internalWebSocket)) | ||||
|             if (this.TryGetValue(WebSocketClientExtension.WebSocketProperty, out var internalWebSocket)) | ||||
|             { | ||||
|                 _ = internalWebSocket.TryInputReceiveAsync(null); | ||||
|             } | ||||
|             base.OnDisconnected(e); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当收到WS数据时。 | ||||
|         /// </summary> | ||||
|         /// <param name="dataFrame"></param> | ||||
|         protected virtual void OnHandleWSDataFrame(WSDataFrame dataFrame) | ||||
|         protected virtual async Task OnReceivedWSDataFrame(WSDataFrame dataFrame) | ||||
|         { | ||||
|             if (this.TryGetValue(WebSocketClientExtensions.WebSocketProperty, out var internalWebSocket)) | ||||
|             if (this.TryGetValue(WebSocketClientExtension.WebSocketProperty, out var internalWebSocket)) | ||||
|             { | ||||
|                 if (internalWebSocket.TryInputReceiveAsync(dataFrame).ConfigureAwait(false).GetAwaiter().GetResult()) | ||||
|                 if (await internalWebSocket.TryInputReceiveAsync(dataFrame)) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
| @@ -265,7 +293,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|  | ||||
|             if (this.PluginsManager.Enable) | ||||
|             { | ||||
|                 this.PluginsManager.Raise(nameof(IWebSocketReceivedPlugin.OnWebSocketReceived), this, new WSDataFrameEventArgs(dataFrame)); | ||||
|                 await this.PluginsManager.RaiseAsync(nameof(IWebSocketReceivedPlugin.OnWebSocketReceived), this, new WSDataFrameEventArgs(dataFrame)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|     /// <summary> | ||||
|     /// WebSocket适配器 | ||||
|     /// </summary> | ||||
|     public class WebSocketDataHandlingAdapter : SingleStreamDataHandlingAdapter | ||||
|     public sealed class WebSocketDataHandlingAdapter : SingleStreamDataHandlingAdapter | ||||
|     { | ||||
|         private WSDataFrame m_dataFrameTemp; | ||||
|  | ||||
| @@ -42,16 +42,6 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// </summary> | ||||
|         private ByteBlock m_tempByteBlock; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         public override bool CanSendRequestInfo => false; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         public override bool CanSplicingSend => false; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 解码 | ||||
|         /// </summary> | ||||
| @@ -183,35 +173,6 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当发送数据前处理数据 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer"></param> | ||||
|         /// <param name="offset"></param> | ||||
|         /// <param name="length"></param> | ||||
|         protected override void PreviewSend(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             this.GoSend(buffer, offset, length); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="transferBytes"></param> | ||||
|         protected override void PreviewSend(IList<ArraySegment<byte>> transferBytes) | ||||
|         { | ||||
|             throw new System.NotImplementedException();//因为设置了不支持拼接发送,所以该方法可以不实现。 | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override void PreviewSend(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -30,5 +30,5 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="dataFrame"></param> | ||||
|     public delegate void WSDataFrameEventHandler<TClient>(TClient client, WSDataFrame dataFrame); | ||||
|     public delegate Task WSDataFrameEventHandler<TClient>(TClient client, WSDataFrame dataFrame); | ||||
| } | ||||
| @@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|     /// <summary> | ||||
|     /// WSClientExtensions | ||||
|     /// </summary> | ||||
|     public static class WebSocketClientExtensions | ||||
|     public static class WebSocketClientExtension | ||||
|     { | ||||
|         #region DependencyProperty | ||||
| 
 | ||||
| @@ -29,7 +29,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     /// <summary> | ||||
|     /// WebSocketConfigExtensions | ||||
|     /// </summary> | ||||
|     public static class WebSocketConfigExtensions | ||||
|     public static class WebSocketConfigExtension | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 构建WebSocketClient类客户端,并连接 | ||||
| @@ -29,7 +29,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|     /// <summary> | ||||
|     /// WSDataFrame辅助扩展类 | ||||
|     /// </summary> | ||||
|     public static class WebSocketDataFrameExtensions | ||||
|     public static class WebSocketDataFrameExtension | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 追加二进制流 | ||||
| @@ -28,7 +28,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|     /// <summary> | ||||
|     /// WebSocketServerExtensions | ||||
|     /// </summary> | ||||
|     public static class WebSocketServerExtensions | ||||
|     public static class WebSocketServerExtension | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 转化Protocol协议标识为<see cref="Protocol.WebSocket"/> | ||||
| @@ -49,7 +49,8 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|                     { | ||||
|                         IsPermitOperation = true | ||||
|                     }; | ||||
|                     await client.PluginsManager.RaiseAsync(nameof(IWebSocketHandshakingPlugin.OnWebSocketHandshaking), client, args); | ||||
|                     await client.PluginsManager.RaiseAsync(nameof(IWebSocketHandshakingPlugin.OnWebSocketHandshaking), client, args).ConfigureAwait(false); | ||||
| 
 | ||||
|                     if (args.Context.Response.Responsed) | ||||
|                     { | ||||
|                         return false; | ||||
| @@ -63,9 +64,10 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|                         using (var byteBlock = new ByteBlock()) | ||||
|                         { | ||||
|                             args.Context.Response.Build(byteBlock); | ||||
|                             await client.DefaultSendAsync(byteBlock); | ||||
|                             await client.DefaultSendAsync(byteBlock).ConfigureAwait(false); | ||||
|                         } | ||||
|                         await client.PluginsManager.RaiseAsync(nameof(IWebSocketHandshakedPlugin.OnWebSocketHandshaked), client, new HttpContextEventArgs(httpContext)); | ||||
|                         await client.PluginsManager.RaiseAsync(nameof(IWebSocketHandshakedPlugin.OnWebSocketHandshaked), client, new HttpContextEventArgs(httpContext)) | ||||
|                             .ConfigureAwait(false); | ||||
|                         return true; | ||||
|                     } | ||||
|                     else | ||||
| @@ -74,7 +76,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|                         using (var byteBlock = new ByteBlock()) | ||||
|                         { | ||||
|                             args.Context.Response.Build(byteBlock); | ||||
|                             await client.DefaultSendAsync(byteBlock); | ||||
|                             await client.DefaultSendAsync(byteBlock).ConfigureAwait(false); | ||||
|                         } | ||||
| 
 | ||||
|                         client.Close("主动拒绝WebSocket连接"); | ||||
| @@ -68,7 +68,14 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// <param name="token"></param> | ||||
|         /// <returns></returns> | ||||
|         Task<WebSocketReceiveResult> ReadAsync(CancellationToken token); | ||||
|  | ||||
| #if NET6_0_OR_GREATER | ||||
|         /// <summary> | ||||
|         /// 值异步等待读取数据 | ||||
|         /// </summary> | ||||
|         /// <param name="token"></param> | ||||
|         /// <returns></returns> | ||||
|         public ValueTask<WebSocketReceiveResult> ValueReadAsync(CancellationToken token); | ||||
| #endif | ||||
|         /// <summary> | ||||
|         /// 采用WebSocket协议,发送WS数据。发送结束后,请及时释放<see cref="WSDataFrame"/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -71,7 +71,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// <summary> | ||||
|         /// 验证连接 | ||||
|         /// </summary> | ||||
|         public Func<IHttpSocketClient, HttpContext, bool> VerifyConnection { get; set; } | ||||
|         public Func<IHttpSocketClient, HttpContext, Task<bool>> VerifyConnection { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 用于WebSocket连接的路径,默认为“/ws” | ||||
| @@ -98,7 +98,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         { | ||||
|             if (client.Protocol == Protocol.Http) | ||||
|             { | ||||
|                 if (this.VerifyConnection.Invoke(client, e.Context)) | ||||
|                 if (await this.VerifyConnection.Invoke(client, e.Context)) | ||||
|                 { | ||||
|                     e.Handled = true; | ||||
|                     _ = client.SwitchProtocolToWebSocket(e.Context); | ||||
| @@ -117,7 +117,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         public async Task OnTcpDisconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|         { | ||||
|             client.SetValue(HandshakedProperty, false); | ||||
|             if (client.TryGetValue(WebSocketClientExtensions.WebSocketProperty, out var internalWebSocket)) | ||||
|             if (client.TryGetValue(WebSocketClientExtension.WebSocketProperty, out var internalWebSocket)) | ||||
|             { | ||||
|                 _ = internalWebSocket.TryInputReceiveAsync(null); | ||||
|             } | ||||
| @@ -145,6 +145,21 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|         /// <param name="func"></param> | ||||
|         /// <returns></returns> | ||||
|         public WebSocketFeature SetVerifyConnection(Func<IHttpSocketClient, HttpContext, bool> func) | ||||
|         { | ||||
|             this.VerifyConnection = async (client, context) => | ||||
|             { | ||||
|                 await EasyTask.CompletedTask; | ||||
|                 return func.Invoke(client, context); | ||||
|             }; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 验证连接 | ||||
|         /// </summary> | ||||
|         /// <param name="func"></param> | ||||
|         /// <returns></returns> | ||||
|         public WebSocketFeature SetVerifyConnection(Func<IHttpSocketClient, HttpContext, Task<bool>> func) | ||||
|         { | ||||
|             this.VerifyConnection = func; | ||||
|             return this; | ||||
| @@ -186,7 +201,7 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|                 ((HttpSocketClient)client).PongWS(); | ||||
|                 return; | ||||
|             } | ||||
|             if (client.TryGetValue(WebSocketClientExtensions.WebSocketProperty, out var internalWebSocket)) | ||||
|             if (client.TryGetValue(WebSocketClientExtension.WebSocketProperty, out var internalWebSocket)) | ||||
|             { | ||||
|                 if (await internalWebSocket.TryInputReceiveAsync(dataFrame)) | ||||
|                 { | ||||
| @@ -196,8 +211,9 @@ namespace ThingsGateway.Foundation.Http.WebSockets | ||||
|             await this.m_pluginsManager.RaiseAsync(nameof(IWebSocketReceivedPlugin.OnWebSocketReceived), client, new WSDataFrameEventArgs(dataFrame)); | ||||
|         } | ||||
|  | ||||
|         private bool ThisVerifyConnection(IHttpSocketClient client, HttpContext context) | ||||
|         private async Task<bool> ThisVerifyConnection(IHttpSocketClient client, HttpContext context) | ||||
|         { | ||||
|             await EasyTask.CompletedTask; | ||||
|             if (context.Request.Method == HttpMethod.Get) | ||||
|             { | ||||
|                 if (this.WSUrl == "/" || context.Request.UrlEquals(this.WSUrl)) | ||||
|   | ||||
| @@ -41,12 +41,6 @@ namespace ThingsGateway.Foundation.Rpc | ||||
|         /// </summary> | ||||
|         ExtensionAsync = 2, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 包含扩展(源代码生成无效) | ||||
|         /// </summary> | ||||
|         [Obsolete("该值已被弃用,请使用颗粒度更小的配置", true)] | ||||
|         IncludeExtension = 4, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 生成实例类同步代码(源代码生成无效) | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation.Serial; | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void SerialConnectingEventHandler<TClient>(TClient client, SerialConnectingEventArgs e); | ||||
| public delegate Task SerialConnectingEventHandler<TClient>(TClient client, SerialConnectingEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// 客户端连接事件。 | ||||
|   | ||||
| @@ -15,21 +15,7 @@ namespace ThingsGateway.Foundation.Serial; | ||||
| /// <summary> | ||||
| /// 串口基接口 | ||||
| /// </summary> | ||||
| public interface ISerial : IDisposable | ||||
| public interface ISerial : ISocket | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 发送缓存区大小。最小值=1024。 | ||||
|     /// </summary> | ||||
|     int SendBufferSize { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 接收缓存区大小。最小值=1024。 | ||||
|     /// </summary> | ||||
|     int ReceiveBufferSize { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 日志记录器 | ||||
|     /// </summary> | ||||
|     ILog Logger { get; set; } | ||||
|  | ||||
| } | ||||
| @@ -53,9 +53,9 @@ public interface ISerialSessionBase : IClient, ISender, IDefaultSender, IPluginO | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 接收模式 | ||||
|     /// 判断是否在线 | ||||
|     /// </summary> | ||||
|     public ReceiveType ReceiveType { get; } | ||||
|     bool Online { get; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 串口描述 | ||||
|   | ||||
| @@ -21,21 +21,23 @@ public abstract class BaseSerial : DependencyObject, ISerial | ||||
|     /// 同步根。 | ||||
|     /// </summary> | ||||
|     protected readonly object SyncRoot = new object(); | ||||
|     private int m_receiveBufferSize = 1024 * 64; | ||||
|     private int m_sendBufferSize = 1024 * 64; | ||||
|     private int m_receiveBufferSize = 1024 * 10; | ||||
|     private int m_sendBufferSize = 1024 * 10; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public virtual int SendBufferSize | ||||
|     { | ||||
|         get => m_sendBufferSize; | ||||
|         set => m_sendBufferSize = value < 1024 ? 1024 : value; | ||||
|         get => this.m_sendBufferSize; | ||||
|         set => this.m_sendBufferSize = value < 1024 ? 1024 : value; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public virtual int ReceiveBufferSize | ||||
|     { | ||||
|         get => m_receiveBufferSize; | ||||
|         set => m_receiveBufferSize = value < 1024 ? 1024 : value; | ||||
|         get => this.m_receiveBufferSize; | ||||
|         set => this.m_receiveBufferSize = value < 1024 ? 1024 : value; | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ILog Logger { get; set; } | ||||
| } | ||||
| @@ -0,0 +1,396 @@ | ||||
| #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.Diagnostics; | ||||
| using System.IO.Ports; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Serial; | ||||
| internal sealed class InternalSerialCore : SerialCore | ||||
| { | ||||
|  | ||||
| } | ||||
| /// <summary> | ||||
| /// Serial核心 | ||||
| /// </summary> | ||||
| public class SerialCore : IDisposable, ISender | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 初始缓存大小 | ||||
|     /// </summary> | ||||
|     public const int BufferSize = 1024 * 10; | ||||
|     #region 字段 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 同步根 | ||||
|     /// </summary> | ||||
|     public readonly object SyncRoot = new object(); | ||||
|  | ||||
|     private long m_bufferRate; | ||||
|     private bool m_disposedValue; | ||||
|     private SpinLock m_lock; | ||||
|     private bool m_online => MainSerialPort?.IsOpen == true; | ||||
|     private int m_receiveBufferSize = BufferSize; | ||||
|     private ValueCounter m_receiveCounter; | ||||
|     private int m_sendBufferSize = BufferSize; | ||||
|     private ValueCounter m_sendCounter; | ||||
|     private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|     #endregion 字段 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Tcp核心 | ||||
|     /// </summary> | ||||
|     public SerialCore() | ||||
|     { | ||||
|         this.m_lock = new SpinLock(Debugger.IsAttached); | ||||
|         this.m_receiveCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
|             OnPeriod = this.OnReceivePeriod | ||||
|         }; | ||||
|  | ||||
|         this.m_sendCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
|             OnPeriod = this.OnSendPeriod | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 析构函数 | ||||
|     /// </summary> | ||||
|     ~SerialCore() | ||||
|     { | ||||
|         this.Dispose(disposing: false); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public bool CanSend => this.m_online; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当中断Tcp的时候。当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。 | ||||
|     /// </summary> | ||||
|     public Action<SerialCore, bool, string> OnBreakOut { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当发生异常的时候 | ||||
|     /// </summary> | ||||
|     public Action<SerialCore, Exception> OnException { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 在线状态 | ||||
|     /// </summary> | ||||
|     public bool Online { get => this.m_online; } | ||||
|     /// <summary> | ||||
|     /// UserToken | ||||
|     /// </summary> | ||||
|     public ByteBlock UserToken { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当收到数据的时候 | ||||
|     /// </summary> | ||||
|     public Action<SerialCore, ByteBlock> OnReceived { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 接收缓存池(可以设定初始值,运行时的值会根据流速自动调整) | ||||
|     /// </summary> | ||||
|     public int ReceiveBufferSize | ||||
|     { | ||||
|         get => this.m_receiveBufferSize; | ||||
|         set | ||||
|         { | ||||
|             this.m_receiveBufferSize = value; | ||||
|             if (this.MainSerialPort != null && !MainSerialPort.IsOpen) | ||||
|             { | ||||
|                 this.MainSerialPort.ReadBufferSize = value; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 接收计数器 | ||||
|     /// </summary> | ||||
|     public ValueCounter ReceiveCounter { get => this.m_receiveCounter; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 发送缓存池(可以设定初始值,运行时的值会根据流速自动调整) | ||||
|     /// </summary> | ||||
|     public int SendBufferSize | ||||
|     { | ||||
|         get => this.m_sendBufferSize; | ||||
|         set | ||||
|         { | ||||
|             this.m_sendBufferSize = value; | ||||
|             if (this.MainSerialPort != null && !MainSerialPort.IsOpen) | ||||
|             { | ||||
|                 this.MainSerialPort.WriteBufferSize = value; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 发送计数器 | ||||
|     /// </summary> | ||||
|     public ValueCounter SendCounter { get => this.m_sendCounter; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// SerialPort | ||||
|     /// </summary> | ||||
|     public SerialPort MainSerialPort { get; private set; } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 开始以Iocp方式接收 | ||||
|     /// </summary> | ||||
|     public virtual void BeginIocpReceive() | ||||
|     { | ||||
|         var byteBlock = BytePool.Default.GetByteBlock(this.ReceiveBufferSize); | ||||
|         this.UserToken = byteBlock; | ||||
|         byteBlock.SetLength(0); | ||||
|         if (this.MainSerialPort.BytesToRead > 0) | ||||
|         { | ||||
|             this.ProcessReceived(); | ||||
|         } | ||||
|         MainSerialPort.DataReceived += MainSerialPort_DataReceived; | ||||
|     } | ||||
|  | ||||
|     private void MainSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.m_bufferRate = 1; | ||||
|             this.ProcessReceived(); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             this.PrivateBreakOut(false, ex.Message); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 请求关闭 | ||||
|     /// </summary> | ||||
|     /// <param name="msg"></param> | ||||
|     public virtual void Close(string msg) | ||||
|     { | ||||
|         this.PrivateBreakOut(true, msg); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 释放对象 | ||||
|     /// </summary> | ||||
|     public void Dispose() | ||||
|     { | ||||
|         this.Dispose(disposing: true); | ||||
|         GC.SuppressFinalize(this); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 重置环境,并设置新的<see cref="MainSerialPort"/>。 | ||||
|     /// </summary> | ||||
|     /// <param name="socket"></param> | ||||
|     public virtual void Reset(SerialPort socket) | ||||
|     { | ||||
|         if (socket is null) | ||||
|         { | ||||
|             throw new ArgumentNullException(nameof(socket)); | ||||
|         } | ||||
|  | ||||
|         if (!socket.IsOpen) | ||||
|         { | ||||
|             throw new Exception("新的SerialPort必须在连接状态。"); | ||||
|         } | ||||
|         this.Reset(); | ||||
|         this.MainSerialPort = socket; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 重置环境。 | ||||
|     /// </summary> | ||||
|     public virtual void Reset() | ||||
|     { | ||||
|         this.m_receiveCounter.Reset(); | ||||
|         this.m_sendCounter.Reset(); | ||||
|         this.MainSerialPort = null; | ||||
|         this.OnReceived = null; | ||||
|         this.OnBreakOut = null; | ||||
|         this.UserToken = null; | ||||
|         this.m_bufferRate = 1; | ||||
|         this.m_lock = new SpinLock(); | ||||
|         this.m_receiveBufferSize = BufferSize; | ||||
|         this.m_sendBufferSize = BufferSize; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 发送数据。 | ||||
|     /// <para> | ||||
|     /// 内部会根据是否启用Ssl,进行直接发送,还是Ssl发送。 | ||||
|     /// </para> | ||||
|     /// </summary> | ||||
|     /// <param name="buffer"></param> | ||||
|     /// <param name="offset"></param> | ||||
|     /// <param name="length"></param> | ||||
|     public virtual void Send(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         var lockTaken = false; | ||||
|         try | ||||
|         { | ||||
|             this.m_lock.Enter(ref lockTaken); | ||||
|             this.MainSerialPort.Write(buffer, offset, length); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             if (lockTaken) this.m_lock.Exit(false); | ||||
|         } | ||||
|         this.m_sendCounter.Increment(length); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 异步发送数据。 | ||||
|     /// </summary> | ||||
|     /// <param name="buffer"></param> | ||||
|     /// <param name="offset"></param> | ||||
|     /// <param name="length"></param> | ||||
|     /// <returns></returns> | ||||
|     /// <exception cref="Exception"></exception> | ||||
|     public virtual async Task SendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             await this.m_semaphore.WaitAsync(); | ||||
|  | ||||
|             this.MainSerialPort.Write(buffer, offset, length); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             this.m_semaphore.Release(); | ||||
|         } | ||||
|  | ||||
|         this.m_sendCounter.Increment(length); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当中断Tcp时。 | ||||
|     /// </summary> | ||||
|     /// <param name="manual">当为<see langword="true"/>时,意味着是调用<see cref="Close(string)"/>。当为<see langword="false"/>时,则是其他中断。</param> | ||||
|     /// <param name="msg"></param> | ||||
|     protected virtual void BreakOut(bool manual, string msg) | ||||
|     { | ||||
|         this.OnBreakOut?.Invoke(this, manual, msg); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 释放对象 | ||||
|     /// </summary> | ||||
|     /// <param name="disposing"></param> | ||||
|     protected virtual void Dispose(bool disposing) | ||||
|     { | ||||
|         if (!this.m_disposedValue) | ||||
|         { | ||||
|             if (disposing) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             this.m_disposedValue = true; | ||||
|         } | ||||
|         UserToken.SafeDispose(); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当发生异常的时候 | ||||
|     /// </summary> | ||||
|     /// <param name="ex"></param> | ||||
|     protected virtual void Exception(Exception ex) | ||||
|     { | ||||
|         this.OnException?.Invoke(this, ex); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当收到数据的时候 | ||||
|     /// </summary> | ||||
|     /// <param name="byteBlock"></param> | ||||
|     protected virtual void Received(ByteBlock byteBlock) | ||||
|     { | ||||
|         this.OnReceived?.Invoke(this, byteBlock); | ||||
|     } | ||||
|  | ||||
|     private void HandleBuffer(ByteBlock byteBlock) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.m_receiveCounter.Increment(byteBlock.Length); | ||||
|             this.Received(byteBlock); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             this.Exception(ex); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             byteBlock.Dispose(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void OnReceivePeriod(long value) | ||||
|     { | ||||
|         this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value); | ||||
|     } | ||||
|  | ||||
|     private void OnSendPeriod(long value) | ||||
|     { | ||||
|         this.SendBufferSize = TouchSocketUtility.HitBufferLength(value); | ||||
|     } | ||||
|  | ||||
|     private void PrivateBreakOut(bool manual, string msg) | ||||
|     { | ||||
|         lock (this.SyncRoot) | ||||
|         { | ||||
|             if (this.m_online) | ||||
|             { | ||||
|                 this.BreakOut(manual, msg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void ProcessReceived() | ||||
|     { | ||||
|         if (!this.m_online) | ||||
|         { | ||||
|             UserToken?.SafeDispose(); | ||||
|             return; | ||||
|         } | ||||
|         if (MainSerialPort.BytesToRead > 0) | ||||
|         { | ||||
|             var byteBlock = UserToken; | ||||
|             byte[] buffer = BytePool.Default.Rent(MainSerialPort.BytesToRead); | ||||
|             int num = MainSerialPort.Read(buffer, 0, MainSerialPort.BytesToRead); | ||||
|             byteBlock.Write(buffer, 0, num); | ||||
|             byteBlock.SetLength(num); | ||||
|             this.HandleBuffer(byteBlock); | ||||
|             try | ||||
|             { | ||||
|                 var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength)); | ||||
|                 newByteBlock.SetLength(0); | ||||
|                 UserToken = newByteBlock; | ||||
|  | ||||
|                 if (MainSerialPort.BytesToRead > 0) | ||||
|                 { | ||||
|                     this.m_bufferRate += 2; | ||||
|                     this.ProcessReceived(); | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 this.PrivateBreakOut(false, ex.Message); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -14,6 +14,7 @@ using System.IO.Ports; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Serial; | ||||
|  | ||||
|  | ||||
| /// <inheritdoc cref="SerialSessionBase"/> | ||||
| public class SerialSession : SerialSessionBase | ||||
| { | ||||
| @@ -22,15 +23,18 @@ public class SerialSession : SerialSessionBase | ||||
|     /// </summary> | ||||
|     public ReceivedEventHandler<SerialSession> Received { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 接收数据 | ||||
|     /// </summary> | ||||
|     /// <param name="byteBlock"></param> | ||||
|     /// <param name="requestInfo"></param> | ||||
|     protected override bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     /// <inheritdoc/> | ||||
|     protected override async Task ReceivedData(ReceivedDataEventArgs e) | ||||
|     { | ||||
|         this.Received?.Invoke(this, byteBlock, requestInfo); | ||||
|         return false; | ||||
|         if (this.Received != null) | ||||
|         { | ||||
|             await this.Received.Invoke(this, e); | ||||
|             if (e.Handled) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         await base.ReceivedData(e); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -46,33 +50,22 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     public SerialSessionBase() | ||||
|     { | ||||
|         this.Protocol = SerialPort; | ||||
|         this.m_receiveCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
|             OnPeriod = this.OnReceivePeriod | ||||
|         }; | ||||
|         this.m_sendCounter = new ValueCounter | ||||
|         { | ||||
|             Period = TimeSpan.FromSeconds(1), | ||||
|             OnPeriod = this.OnSendPeriod | ||||
|         }; | ||||
|         this.m_serialCore = new InternalSerialCore(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     #region 变量 | ||||
|  | ||||
|     private DelaySender m_delaySender; | ||||
|     private long m_bufferRate = 1; | ||||
|     private bool m_online => MainSerialPort?.IsOpen == true; | ||||
|     private ValueCounter m_receiveCounter; | ||||
|     private ValueCounter m_sendCounter; | ||||
|  | ||||
|     private readonly SemaphoreSlim m_semaphore = new SemaphoreSlim(1, 1); | ||||
|     private readonly InternalSerialCore m_serialCore; | ||||
|     #endregion 变量 | ||||
|  | ||||
|     #region 事件 | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ConnectedEventHandler<ISerialSession> Connected { get; set; } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public SerialConnectingEventHandler<ISerialSession> Connecting { get; set; } | ||||
|  | ||||
| @@ -82,26 +75,28 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     /// <inheritdoc/> | ||||
|     public DisconnectEventHandler<ISerialSessionBase> Disconnecting { get; set; } | ||||
|  | ||||
|     private void PrivateOnConnected(object o) | ||||
|     private Task PrivateOnConnected(object o) | ||||
|     { | ||||
|         var e = (ConnectedEventArgs)o; | ||||
|         this.OnConnected(e); | ||||
|         if (e.Handled) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|         this.PluginsManager.Raise(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e); | ||||
|         return this.OnConnected((ConnectedEventArgs)o); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 已经建立Tcp连接 | ||||
|     /// 已经建立连接 | ||||
|     /// </summary> | ||||
|     /// <param name="e"></param> | ||||
|     protected virtual void OnConnected(ConnectedEventArgs e) | ||||
|     protected virtual async Task OnConnected(ConnectedEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.Connected?.Invoke(this, e); | ||||
|             if (this.Connected != null) | ||||
|             { | ||||
|                 await this.Connected.Invoke(this, e); | ||||
|                 if (e.Handled) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(ITcpConnectedPlugin.OnTcpConnected), this, e); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -109,30 +104,33 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void PrivateOnConnecting(SerialConnectingEventArgs e) | ||||
|     private Task 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); | ||||
|         return this.OnConnecting(e); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 准备连接的时候,此时已初始化Socket,但是并未建立Tcp连接 | ||||
|     /// 准备连接的时候,此时并未建立连接 | ||||
|     /// </summary> | ||||
|     /// <param name="e"></param> | ||||
|     protected virtual void OnConnecting(SerialConnectingEventArgs e) | ||||
|     protected virtual async Task OnConnecting(SerialConnectingEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.Connecting?.Invoke(this, e); | ||||
|             if (this.Connecting != null) | ||||
|             { | ||||
|                 await this.Connecting.Invoke(this, e); | ||||
|                 if (e.Handled) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             await this.PluginsManager.RaiseAsync(nameof(ITcpConnectingPlugin.OnTcpConnecting), this, e); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -140,25 +138,30 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void PrivateOnDisconnected(DisconnectEventArgs e) | ||||
|     private Task PrivateOnDisconnected(object obj) | ||||
|     { | ||||
|         this.OnDisconnected(e); | ||||
|         if (e.Handled) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|         this.PluginsManager.Raise(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e); | ||||
|         this.m_receiver?.TryInputReceive(default, default); | ||||
|         return this.OnDisconnected((DisconnectEventArgs)obj); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 断开连接。在客户端未设置连接状态时,不会触发 | ||||
|     /// </summary> | ||||
|     /// <param name="e"></param> | ||||
|     protected virtual void OnDisconnected(DisconnectEventArgs e) | ||||
|     protected virtual async Task OnDisconnected(DisconnectEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.Disconnected?.Invoke(this, e); | ||||
|             if (this.Disconnected != null) | ||||
|             { | ||||
|                 await this.Disconnected.Invoke(this, e).ConfigureAwait(false); | ||||
|                 if (e.Handled) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectedPlugin.OnTcpDisconnected), this, e).ConfigureAwait(false); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -166,28 +169,29 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void PrivateOnDisconnecting(DisconnectEventArgs e) | ||||
|     private Task PrivateOnDisconnecting(object obj) | ||||
|     { | ||||
|         this.OnDisconnecting(e); | ||||
|         if (e.Handled) | ||||
|         { | ||||
|             return; | ||||
|         } | ||||
|         this.PluginsManager.Raise(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e); | ||||
|         return this.OnDisconnecting((DisconnectEventArgs)obj); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 即将断开连接(仅主动断开时有效)。 | ||||
|     /// <para> | ||||
|     /// 当主动调用Close断开时。 | ||||
|     /// </para> | ||||
|     /// </summary> | ||||
|     /// <param name="e"></param> | ||||
|     protected virtual void OnDisconnecting(DisconnectEventArgs e) | ||||
|     protected virtual async Task OnDisconnecting(DisconnectEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.Disconnecting?.Invoke(this, e); | ||||
|             if (this.Disconnecting != null) | ||||
|             { | ||||
|                 await this.Disconnecting.Invoke(this, e).ConfigureAwait(false); | ||||
|                 if (e.Handled) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             await this.PluginsManager.RaiseAsync(nameof(ITcpDisconnectingPlugin.OnTcpDisconnecting), this, e).ConfigureAwait(false); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -200,16 +204,10 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     #region 属性 | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public DateTime LastReceivedTime => this.m_receiveCounter.LastIncrement; | ||||
|     public DateTime LastReceivedTime => this.GetTcpCore().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; } | ||||
|     public DateTime LastSendTime => this.GetTcpCore().SendCounter.LastIncrement; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public IContainer Container { get; private set; } | ||||
| @@ -223,10 +221,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     /// <inheritdoc/> | ||||
|     public SingleStreamDataHandlingAdapter DataHandlingAdapter { get; private set; } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     public SerialProperty SerialProperty { get; private set; } | ||||
|     /// <inheritdoc/> | ||||
|     public SerialPort MainSerialPort { get; private set; } | ||||
| @@ -241,9 +236,6 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     public IPluginsManager PluginsManager { get; private set; } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public ReceiveType ReceiveType { get; private set; } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public Protocol Protocol { get; set; } | ||||
| @@ -261,32 +253,13 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         { | ||||
|             if (this.m_online) | ||||
|             { | ||||
|                 this.PrivateOnDisconnecting(new DisconnectEventArgs(true, msg)); | ||||
|  | ||||
|                 Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, msg)); | ||||
|                 this.MainSerialPort.TryClose(); | ||||
|  | ||||
|                 this.MainSerialPort.SafeDispose(); | ||||
|                 this.m_delaySender.SafeDispose(); | ||||
|                 this.DataHandlingAdapter.SafeDispose(); | ||||
|                 this.PrivateOnDisconnected(new DisconnectEventArgs(true, msg)); | ||||
|                 this.BreakOut(default, true, msg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void BreakOut(string msg) | ||||
|     { | ||||
|         lock (this.SyncRoot) | ||||
|         { | ||||
|             if (this.m_online) | ||||
|             { | ||||
|  | ||||
|                 this.MainSerialPort.SafeDispose(); | ||||
|                 this.m_delaySender.SafeDispose(); | ||||
|                 this.DataHandlingAdapter.SafeDispose(); | ||||
|                 this.PrivateOnDisconnected(new DisconnectEventArgs(false, msg)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
| @@ -298,15 +271,8 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         { | ||||
|             if (this.m_online) | ||||
|             { | ||||
|  | ||||
|                 this.MainSerialPort.TryClose(); | ||||
|                 this.PrivateOnDisconnecting(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|  | ||||
|                 this.MainSerialPort.SafeDispose(); | ||||
|                 this.m_delaySender.SafeDispose(); | ||||
|                 this.DataHandlingAdapter.SafeDispose(); | ||||
|                 this.PluginsManager.SafeDispose(); | ||||
|                 this.PrivateOnDisconnected(new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                 Task.Factory.StartNew(this.PrivateOnDisconnecting, new DisconnectEventArgs(true, $"{nameof(Dispose)}主动断开")); | ||||
|                 this.BreakOut(default, true, $"{nameof(Dispose)}主动断开"); | ||||
|             } | ||||
|         } | ||||
|         base.Dispose(disposing); | ||||
| @@ -315,6 +281,7 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     #endregion 断开操作 | ||||
|  | ||||
|     #region Connect | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 打开串口 | ||||
|     /// </summary> | ||||
| @@ -332,25 +299,32 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|             } | ||||
|             if (this.Config == null) | ||||
|             { | ||||
|                 throw new ArgumentNullException("配置文件不能为空。"); | ||||
|                 throw new ArgumentNullException(nameof(this.Config), "配置文件不能为空。"); | ||||
|             } | ||||
|             var serialProperty = this.Config.GetValue(SerialConfigExtension.SerialProperty) ?? throw new ArgumentNullException("串口配置不能为空。"); | ||||
|  | ||||
|             this.MainSerialPort.SafeDispose(); | ||||
|             var serialPort = CreateSerial(serialProperty); | ||||
|             var args = new SerialConnectingEventArgs(this.MainSerialPort); | ||||
|             this.PrivateOnConnecting(args); | ||||
|             this.PrivateOnConnecting(new(serialPort)) | ||||
|                 .ConfigureAwait(false) | ||||
|                 .GetAwaiter() | ||||
|                 .GetResult(); | ||||
|  | ||||
|             serialPort.Open(); | ||||
|  | ||||
|  | ||||
|             this.SetSerialPort(serialPort); | ||||
|  | ||||
|  | ||||
|             this.BeginReceive(); | ||||
|             this.PrivateOnConnected(new ConnectedEventArgs()); | ||||
|  | ||||
|             Task.Factory.StartNew(this.PrivateOnConnected, new ConnectedEventArgs()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     private void BeginReceive() | ||||
|     { | ||||
|         this.GetTcpCore().BeginIocpReceive(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public virtual ISerialSession Connect() | ||||
|     { | ||||
| @@ -366,43 +340,66 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|             return this.Connect(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     #endregion Connect | ||||
|  | ||||
|     #region Receiver | ||||
|  | ||||
|     private Receiver m_receiver; | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public IReceiver CreateReceiver() | ||||
|     { | ||||
|         return this.m_receiver ??= new Receiver(this); | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public void ClearReceiver() | ||||
|     { | ||||
|         this.m_receiver = null; | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
|  | ||||
|     private void OnReceivePeriod(long value) | ||||
|     private void BreakOut(SerialCore core, bool manual, string msg) | ||||
|     { | ||||
|         this.ReceiveBufferSize = TouchSocketUtility.HitBufferLength(value); | ||||
|         lock (this.SyncRoot) | ||||
|         { | ||||
|             if (this.m_online) | ||||
|             { | ||||
|                 this.MainSerialPort.SafeDispose(); | ||||
|                 this.m_delaySender.SafeDispose(); | ||||
|                 this.DataHandlingAdapter.SafeDispose(); | ||||
|                 Task.Factory.StartNew(this.PrivateOnDisconnected, new DisconnectEventArgs(manual, msg)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void OnSendPeriod(long value) | ||||
|     private SerialCore GetTcpCore() | ||||
|     { | ||||
|         this.SendBufferSize = TouchSocketUtility.HitBufferLength(value); | ||||
|         this.ThrowIfDisposed(); | ||||
|         return this.m_serialCore ?? throw new ObjectDisposedException(this.GetType().Name); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override int ReceiveBufferSize | ||||
|     { | ||||
|         get => base.ReceiveBufferSize; | ||||
|         get => this.GetTcpCore().ReceiveBufferSize; | ||||
|         set | ||||
|         { | ||||
|             base.ReceiveBufferSize = value; | ||||
|             if (this.MainSerialPort != null && !MainSerialPort.IsOpen) | ||||
|             { | ||||
|                 this.MainSerialPort.ReadBufferSize = base.ReceiveBufferSize; | ||||
|             } | ||||
|             this.GetTcpCore().ReceiveBufferSize = value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <inheritdoc/> | ||||
|     public override int SendBufferSize | ||||
|     { | ||||
|         get => base.SendBufferSize; | ||||
|         get => this.GetTcpCore().SendBufferSize; | ||||
|         set | ||||
|         { | ||||
|             base.SendBufferSize = value; | ||||
|             if (this.MainSerialPort != null && !MainSerialPort.IsOpen) | ||||
|             { | ||||
|                 this.MainSerialPort.WriteBufferSize = base.SendBufferSize; | ||||
|             } | ||||
|             this.GetTcpCore().SendBufferSize = value; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -480,32 +477,24 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|  | ||||
|     private void PrivateHandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     { | ||||
|         if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false) | ||||
|         if (this.m_receiver != null) | ||||
|         { | ||||
|             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); | ||||
|             if (this.m_receiver.TryInputReceive(byteBlock, requestInfo)) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         this.ReceivedData(new ReceivedDataEventArgs(byteBlock, requestInfo)).GetFalseAwaitResult(); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 处理已接收到的数据。 | ||||
|     /// 当收到适配器处理的数据时。 | ||||
|     /// </summary> | ||||
|     /// <param name="byteBlock">以二进制流形式传递</param> | ||||
|     /// <param name="requestInfo">以解析的数据对象传递</param> | ||||
|     /// <param name="e"></param> | ||||
|     /// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns> | ||||
|     protected virtual bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|     protected virtual Task ReceivedData(ReceivedDataEventArgs e) | ||||
|     { | ||||
|         return false; | ||||
|         return this.PluginsManager.RaiseAsync(nameof(ITcpReceivedPlugin.OnTcpReceived), this, e); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -515,12 +504,12 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     /// <param name="offset">偏移</param> | ||||
|     /// <param name="length">长度</param> | ||||
|     /// <returns>返回值表示是否允许发送</returns> | ||||
|     protected virtual bool HandleSendingData(byte[] buffer, int offset, int length) | ||||
|     protected virtual async Task<bool> SendingData(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         if (this.PluginsManager.Enable) | ||||
|         if (this.PluginsManager.GetPluginCount(nameof(ITcpSendingPlugin.OnTcpSending)) > 0) | ||||
|         { | ||||
|             var args = new SendingEventArgs(buffer, offset, length); | ||||
|             this.PluginsManager.Raise(nameof(ITcpSendingPlugin.OnTcpSending), this, args); | ||||
|             await this.PluginsManager.RaiseAsync(nameof(ITcpSendingPlugin.OnTcpSending), this, args).ConfigureAwait(false); | ||||
|             return args.IsPermitOperation; | ||||
|         } | ||||
|         return true; | ||||
| @@ -534,16 +523,6 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     { | ||||
|         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> | ||||
| @@ -567,33 +546,10 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         adapter.OnLoaded(this); | ||||
|         adapter.ReceivedCallBack = this.PrivateHandleReceivedData; | ||||
|         adapter.SendCallBack = this.DefaultSend; | ||||
|         adapter.SendAsyncCallBack = this.DefaultSendAsync; | ||||
|         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(this.BeginBio) | ||||
|             { | ||||
|                 IsBackground = true | ||||
|             } | ||||
|             .Start(); | ||||
|         } | ||||
|     } | ||||
|     private static SerialPort CreateSerial(SerialProperty serialProperty) | ||||
|     { | ||||
|         SerialPort serialPort = new(serialProperty.PortName, serialProperty.BaudRate, serialProperty.Parity, serialProperty.DataBits, serialProperty.StopBits) | ||||
| @@ -604,88 +560,6 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         return serialPort; | ||||
|     } | ||||
|  | ||||
|     private void EventArgs_Completed(object sender, SerialDataReceivedEventArgs e) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.m_bufferRate = 1; | ||||
|             SerialReceivedEventArgs eventArgs = new(); | ||||
|             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) | ||||
|             { | ||||
|                 this.ProcessReceived(eventArgs); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             this.BreakOut(ex.Message); | ||||
|         } | ||||
|     } | ||||
|     private void BeginBio() | ||||
|     { | ||||
|         while (true) | ||||
|         { | ||||
|             var byteBlock = new ByteBlock(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; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 处理数据 | ||||
|     /// </summary> | ||||
|     private void HandleBuffer(ByteBlock byteBlock) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             this.m_receiveCounter.Increment(byteBlock.Length); | ||||
|             if (this.OnHandleRawBuffer?.Invoke(byteBlock) == false) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.DisposedValue) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.PluginsManager.Enable && this.PluginsManager.Raise(nameof(ITcpReceivingPlugin.OnTcpReceiving), this, new ByteBlockEventArgs(byteBlock))) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.DataHandlingAdapter == null) | ||||
|             { | ||||
|                 this.Logger.Error(this, TouchSocketResource.NullDataAdapter.GetDescription()); | ||||
|                 return; | ||||
|             } | ||||
|             this.DataHandlingAdapter.ReceivedInput(byteBlock); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex); | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             byteBlock.Dispose(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #region 发送 | ||||
|  | ||||
|     #region 同步发送 | ||||
| @@ -757,12 +631,14 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|             using var byteBlock = new ByteBlock(length); | ||||
|             foreach (var item in transferBytes) | ||||
|             using (var byteBlock = new ByteBlock(length)) | ||||
|             { | ||||
|                 byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                 foreach (var item in transferBytes) | ||||
|                 { | ||||
|                     byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                 } | ||||
|                 this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|             this.DataHandlingAdapter.SendInput(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -773,18 +649,20 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="buffer"><inheritdoc/></param> | ||||
|     /// <param name="offset"><inheritdoc/></param> | ||||
|     /// <param name="length"><inheritdoc/></param> | ||||
|     /// <exception cref="NotConnectedException"><inheritdoc/></exception> | ||||
|     /// <exception cref="OverlengthException"><inheritdoc/></exception> | ||||
|     /// <exception cref="Exception"><inheritdoc/></exception> | ||||
|     /// <param name="buffer"></param> | ||||
|     /// <param name="offset"></param> | ||||
|     /// <param name="length"></param> | ||||
|     /// <exception cref="NotConnectedException"></exception> | ||||
|     /// <exception cref="OverlengthException"></exception> | ||||
|     /// <exception cref="Exception"></exception> | ||||
|     public virtual Task SendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         return Task.Run(() => | ||||
|         this.ThrowIfDisposed(); | ||||
|         if (this.DataHandlingAdapter == null) | ||||
|         { | ||||
|             this.Send(buffer, offset, length); | ||||
|         }); | ||||
|             throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription()); | ||||
|         } | ||||
|         return this.DataHandlingAdapter.SendInputAsync(buffer, offset, length); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -796,118 +674,78 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|     /// <exception cref="Exception"></exception> | ||||
|     public virtual Task SendAsync(IRequestInfo requestInfo) | ||||
|     { | ||||
|         return Task.Run(() => | ||||
|         this.ThrowIfDisposed(); | ||||
|         if (this.DataHandlingAdapter == null) | ||||
|         { | ||||
|             this.Send(requestInfo); | ||||
|         }); | ||||
|             throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription()); | ||||
|         } | ||||
|         if (!this.DataHandlingAdapter.CanSendRequestInfo) | ||||
|         { | ||||
|             throw new NotSupportedException($"当前适配器不支持对象发送。"); | ||||
|         } | ||||
|         return this.DataHandlingAdapter.SendInputAsync(requestInfo); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="transferBytes"><inheritdoc/></param> | ||||
|     /// <exception cref="NotConnectedException"><inheritdoc/></exception> | ||||
|     /// <exception cref="OverlengthException"><inheritdoc/></exception> | ||||
|     /// <exception cref="Exception"><inheritdoc/></exception> | ||||
|     /// <param name="transferBytes"></param> | ||||
|     /// <returns></returns> | ||||
|     /// <exception cref="ArgumentNullException"></exception> | ||||
|     public virtual Task SendAsync(IList<ArraySegment<byte>> transferBytes) | ||||
|     { | ||||
|         return Task.Run(() => | ||||
|         this.ThrowIfDisposed(); | ||||
|         if (this.DataHandlingAdapter == null) | ||||
|         { | ||||
|             this.Send(transferBytes); | ||||
|         }); | ||||
|             throw new ArgumentNullException(nameof(this.DataHandlingAdapter), TouchSocketResource.NullDataAdapter.GetDescription()); | ||||
|         } | ||||
|         if (this.DataHandlingAdapter.CanSplicingSend) | ||||
|         { | ||||
|             return this.DataHandlingAdapter.SendInputAsync(transferBytes); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             var length = 0; | ||||
|             foreach (var item in transferBytes) | ||||
|             { | ||||
|                 length += item.Count; | ||||
|             } | ||||
|             using (var byteBlock = new ByteBlock(length)) | ||||
|             { | ||||
|                 foreach (var item in transferBytes) | ||||
|                 { | ||||
|                     byteBlock.Write(item.Array, item.Offset, item.Count); | ||||
|                 } | ||||
|                 return this.DataHandlingAdapter.SendInputAsync(byteBlock.Buffer, 0, byteBlock.Len); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #endregion 异步发送 | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="buffer"><inheritdoc/></param> | ||||
|     /// <param name="offset"><inheritdoc/></param> | ||||
|     /// <param name="length"><inheritdoc/></param> | ||||
|     /// <exception cref="NotConnectedException"><inheritdoc/></exception> | ||||
|     /// <exception cref="OverlengthException"><inheritdoc/></exception> | ||||
|     /// <exception cref="Exception"><inheritdoc/></exception> | ||||
|     public void DefaultSend(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         if (!this.m_online) | ||||
|         if (this.SendingData(buffer, offset, length).GetFalseAwaitResult()) | ||||
|         { | ||||
|             throw new NotConnectedException(TouchSocketResource.NotConnected.GetDescription()); | ||||
|         } | ||||
|         if (this.HandleSendingData(buffer, offset, length)) | ||||
|         { | ||||
|             if (this.m_delaySender != null && length < this.m_delaySender.DelayLength) | ||||
|             { | ||||
|                 this.m_delaySender.Send(QueueDataBytes.CreateNew(buffer, offset, length)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 this.MainSerialPort.AbsoluteSend(buffer, offset, length); | ||||
|             } | ||||
|  | ||||
|             this.m_sendCounter.Increment(length); | ||||
|             this.GetTcpCore().Send(buffer, offset, length); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// <inheritdoc/> | ||||
|     /// </summary> | ||||
|     /// <param name="buffer"><inheritdoc/></param> | ||||
|     /// <param name="offset"><inheritdoc/></param> | ||||
|     /// <param name="length"><inheritdoc/></param> | ||||
|     /// <exception cref="NotConnectedException"><inheritdoc/></exception> | ||||
|     /// <exception cref="OverlengthException"><inheritdoc/></exception> | ||||
|     /// <exception cref="Exception"><inheritdoc/></exception> | ||||
|     public Task DefaultSendAsync(byte[] buffer, int offset, int length) | ||||
|     public async Task DefaultSendAsync(byte[] buffer, int offset, int length) | ||||
|     { | ||||
|         return Task.Run(() => | ||||
|         if (await this.SendingData(buffer, offset, length)) | ||||
|         { | ||||
|             this.DefaultSend(buffer, offset, length); | ||||
|         }); | ||||
|             await this.GetTcpCore().SendAsync(buffer, offset, length); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #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, 0, num); | ||||
|             byteBlock.SetLength(num); | ||||
|             this.HandleBuffer(byteBlock); | ||||
|             try | ||||
|             { | ||||
|                 var newByteBlock = BytePool.Default.GetByteBlock((int)Math.Min(this.ReceiveBufferSize * this.m_bufferRate, TouchSocketUtility.MaxBufferLength)); | ||||
|                 newByteBlock.SetLength(0); | ||||
|                 e.UserToken = newByteBlock; | ||||
|     #region 自定义 | ||||
|  | ||||
|                 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) | ||||
|     { | ||||
| @@ -917,15 +755,63 @@ public class SerialSessionBase : BaseSerial, ISerialSession | ||||
|         } | ||||
|  | ||||
|         this.MainSerialPort = serialPort; | ||||
|         this.SerialProperty ??= new(); | ||||
|         this.SerialProperty.Parity = serialPort.Parity; | ||||
|         this.SerialProperty.PortName = serialPort.PortName; | ||||
|         this.SerialProperty.StopBits = serialPort.StopBits; | ||||
|         this.SerialProperty.DataBits = serialPort.DataBits; | ||||
|         this.SerialProperty.BaudRate = serialPort.BaudRate; | ||||
|  | ||||
|         var delaySenderOption = this.Config.GetValue(TouchSocketConfigExtension.DelaySenderProperty); | ||||
|         if (delaySenderOption != null) | ||||
|         { | ||||
|             this.m_delaySender = new DelaySender(delaySenderOption, this.MainSerialPort.AbsoluteSend); | ||||
|         } | ||||
|         this.m_serialCore.Reset(serialPort); | ||||
|         this.m_serialCore.OnReceived = this.HandleReceived; | ||||
|         this.m_serialCore.OnBreakOut = this.BreakOut; | ||||
|  | ||||
|     } | ||||
|     /// <inheritdoc/> | ||||
|     public override string ToString() | ||||
|  | ||||
|     private void HandleReceived(SerialCore core, ByteBlock byteBlock) | ||||
|     { | ||||
|         return SerialProperty?.ToString(); | ||||
|         try | ||||
|         { | ||||
|             if (this.DisposedValue) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|             if (this.ReceivingData(byteBlock).GetFalseAwaitResult()) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this.DataHandlingAdapter == null) | ||||
|             { | ||||
|                 this.Logger.Error(this, TouchSocketResource.NullDataAdapter.GetDescription()); | ||||
|                 return; | ||||
|             } | ||||
|             this.DataHandlingAdapter.ReceivedInput(byteBlock); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             this.Logger.Log(LogLevel.Error, this, "在处理数据时发生错误", ex); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 当收到原始数据 | ||||
|     /// </summary> | ||||
|     /// <param name="byteBlock"></param> | ||||
|     /// <returns>如果返回<see langword="true"/>则表示数据已被处理,且不会再向下传递。</returns> | ||||
|     protected virtual Task<bool> ReceivingData(ByteBlock byteBlock) | ||||
|     { | ||||
|         if (this.PluginsManager.GetPluginCount(nameof(ITcpReceivingPlugin.OnTcpReceiving)) > 0) | ||||
|         { | ||||
|             return this.PluginsManager.RaiseAsync(nameof(ITcpReceivingPlugin.OnTcpReceiving), this, new ByteBlockEventArgs(byteBlock)); | ||||
|         } | ||||
|         return Task.FromResult(false); | ||||
|     } | ||||
|  | ||||
|     #endregion | ||||
| } | ||||
| @@ -34,21 +34,24 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// 同步根。 | ||||
|         /// </summary> | ||||
|         protected readonly object SyncRoot = new object(); | ||||
|         private int m_receiveBufferSize = 1024 * 64; | ||||
|         private int m_sendBufferSize = 1024 * 64; | ||||
|  | ||||
|         private int m_receiveBufferSize = 1024 * 10; | ||||
|         private int m_sendBufferSize = 1024 * 10; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual int SendBufferSize | ||||
|         { | ||||
|             get => m_sendBufferSize; | ||||
|             set => m_sendBufferSize = value < 1024 ? 1024 : value; | ||||
|             get => this.m_sendBufferSize; | ||||
|             set => this.m_sendBufferSize = value < 1024 ? 1024 : value; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public virtual int ReceiveBufferSize | ||||
|         { | ||||
|             get => m_receiveBufferSize; | ||||
|             set => m_receiveBufferSize = value < 1024 ? 1024 : value; | ||||
|             get => this.m_receiveBufferSize; | ||||
|             set => this.m_receiveBufferSize = value < 1024 ? 1024 : value; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public ILog Logger { get; set; } | ||||
|     } | ||||
|   | ||||
| @@ -32,11 +32,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         public int SendTimeout { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 接收类型 | ||||
|         /// </summary> | ||||
|         public ReceiveType ReceiveType { get; set; } = ReceiveType.Iocp; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 是否使用地址复用 | ||||
|         /// </summary> | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -44,23 +44,22 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// 在NAT服务器收到数据时。 | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns>需要转发的数据。</returns> | ||||
|         protected virtual byte[] OnNATReceived(NATSocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected virtual byte[] OnNATReceived(NATSocketClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             return byteBlock?.ToArray(); | ||||
|             return e.ByteBlock?.ToArray(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override sealed void OnReceived(NATSocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed async Task OnReceived(NATSocketClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             var data = this.OnNATReceived(socketClient, byteBlock, requestInfo); | ||||
|             await EasyTask.CompletedTask; | ||||
|             var data = this.OnNATReceived(socketClient, e); | ||||
|             if (data != null) | ||||
|             { | ||||
|                 socketClient.SendToTargetClient(data, 0, data.Length); | ||||
| @@ -82,12 +81,11 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="tcpClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         /// <param name="e"></param> | ||||
|         /// <returns></returns> | ||||
|         protected virtual byte[] OnTargetClientReceived(NATSocketClient socketClient, ITcpClient tcpClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected virtual byte[] OnTargetClientReceived(NATSocketClient socketClient, ITcpClient tcpClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             return byteBlock?.ToArray(); | ||||
|             return e.ByteBlock?.ToArray(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -31,7 +31,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     public class NATSocketClient : SocketClient | ||||
|     { | ||||
|         internal Action<NATSocketClient, ITcpClient, DisconnectEventArgs> m_internalDis; | ||||
|         internal Func<NATSocketClient, ITcpClient, ByteBlock, IRequestInfo, byte[]> m_internalTargetClientRev; | ||||
|         internal Func<NATSocketClient, ITcpClient, ReceivedDataEventArgs, byte[]> m_internalTargetClientRev; | ||||
|         private readonly ConcurrentList<ITcpClient> m_targetClients = new ConcurrentList<ITcpClient>(); | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -100,18 +100,19 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="e"></param> | ||||
|         protected override void OnDisconnected(DisconnectEventArgs e) | ||||
|         protected override async Task OnDisconnected(DisconnectEventArgs e) | ||||
|         { | ||||
|             foreach (var client in this.m_targetClients) | ||||
|             { | ||||
|                 client.TryShutdown(); | ||||
|                 client.SafeDispose(); | ||||
|             } | ||||
|             base.OnDisconnected(e); | ||||
|             await base.OnDisconnected(e); | ||||
|         } | ||||
|  | ||||
|         private void TcpClient_Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|         private async Task TcpClient_Disconnected(ITcpClientBase client, DisconnectEventArgs e) | ||||
|         { | ||||
|             await EasyTask.CompletedTask; | ||||
|             foreach (var item in client.PluginsManager.Plugins) | ||||
|             { | ||||
|                 if (typeof(ReconnectionPlugin<>) == item.GetType().GetGenericTypeDefinition()) | ||||
| @@ -125,8 +126,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             this.m_internalDis?.Invoke(this, (ITcpClient)client, e); | ||||
|         } | ||||
|  | ||||
|         private void TcpClient_Received(TcpClient client, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         private async Task TcpClient_Received(TcpClient client, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             await EasyTask.CompletedTask; | ||||
|             if (this.DisposedValue) | ||||
|             { | ||||
|                 return; | ||||
| @@ -134,7 +136,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 var data = this.m_internalTargetClientRev?.Invoke(this, client, byteBlock, requestInfo); | ||||
|                 var data = this.m_internalTargetClientRev?.Invoke(this, client, e); | ||||
|                 if (data != null) | ||||
|                 { | ||||
|                     if (this.CanSend) | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -27,11 +27,10 @@ using System.Net.Sockets; | ||||
| namespace ThingsGateway.Foundation.Sockets | ||||
| { | ||||
|     /// <summary> | ||||
|     /// TCP泛型服务器,由使用者自己指定<see cref="SocketClient"/>类型。 | ||||
|     /// Tcp泛型服务器,由使用者自己指定<see cref="SocketClient"/>类型。 | ||||
|     /// </summary> | ||||
|     public class TcpService<TClient> : TcpServiceBase, ITcpService<TClient> where TClient : SocketClient, new() | ||||
|     { | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 构造函数 | ||||
|         /// </summary> | ||||
| @@ -102,25 +101,17 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将断开连接(仅主动断开时有效)。 | ||||
|         /// <para> | ||||
|         /// 当主动调用Close断开时,可通过<see cref="MsgPermitEventArgs.IsPermitOperation"/>终止断开行为。 | ||||
|         /// </para> | ||||
|         /// </summary> | ||||
|         public DisconnectEventHandler<TClient> Disconnecting { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当客户端Id被修改时触发。 | ||||
|         /// </summary> | ||||
|         public IdChangedEventHandler<TClient> IdChanged { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed void OnClientConnected(ISocketClient socketClient, ConnectedEventArgs e) | ||||
|         protected override sealed Task OnClientConnected(ISocketClient socketClient, ConnectedEventArgs e) | ||||
|         { | ||||
|             this.OnConnected((TClient)socketClient, e); | ||||
|             return this.OnConnected((TClient)socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -128,9 +119,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed void OnClientConnecting(ISocketClient socketClient, ConnectingEventArgs e) | ||||
|         protected override sealed Task OnClientConnecting(ISocketClient socketClient, ConnectingEventArgs e) | ||||
|         { | ||||
|             this.OnConnecting((TClient)socketClient, e); | ||||
|             return this.OnConnecting((TClient)socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -138,9 +129,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed void OnClientDisconnected(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         protected override sealed Task OnClientDisconnected(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             this.OnDisconnected((TClient)socketClient, e); | ||||
|             return this.OnDisconnected((TClient)socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -148,20 +139,19 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed void OnClientDisconnecting(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         protected override sealed Task OnClientDisconnecting(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             this.OnDisconnecting((TClient)socketClient, e); | ||||
|             return this.OnDisconnecting((TClient)socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override sealed void OnClientReceivedData(ISocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         /// <param name="e"></param> | ||||
|         protected override sealed Task OnClientReceivedData(ISocketClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             this.OnReceived((TClient)socketClient, byteBlock, requestInfo); | ||||
|             return this.OnReceived((TClient)socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -169,9 +159,13 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnConnected(TClient socketClient, ConnectedEventArgs e) | ||||
|         protected virtual Task OnConnected(TClient socketClient, ConnectedEventArgs e) | ||||
|         { | ||||
|             this.Connected?.Invoke(socketClient, e); | ||||
|             if (this.Connected != null) | ||||
|             { | ||||
|                 return this.Connected.Invoke(socketClient, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -179,9 +173,13 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnConnecting(TClient socketClient, ConnectingEventArgs e) | ||||
|         protected virtual Task OnConnecting(TClient socketClient, ConnectingEventArgs e) | ||||
|         { | ||||
|             this.Connecting?.Invoke(socketClient, e); | ||||
|             if (this.Connecting != null) | ||||
|             { | ||||
|                 return this.Connecting.Invoke(socketClient, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -189,32 +187,37 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnDisconnected(TClient socketClient, DisconnectEventArgs e) | ||||
|         protected virtual Task OnDisconnected(TClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             this.Disconnected?.Invoke(socketClient, e); | ||||
|             if (this.Disconnected != null) | ||||
|             { | ||||
|                 return this.Disconnected.Invoke(socketClient, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将断开连接(仅主动断开时有效)。 | ||||
|         /// <para> | ||||
|         /// 当主动调用Close断开时,可通过<see cref="MsgPermitEventArgs.IsPermitOperation"/>终止断开行为。 | ||||
|         /// </para> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual void OnDisconnecting(TClient socketClient, DisconnectEventArgs e) | ||||
|         protected virtual Task OnDisconnecting(TClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             this.Disconnecting?.Invoke(socketClient, e); | ||||
|             if (this.Disconnected != null) | ||||
|             { | ||||
|                 return this.Disconnecting.Invoke(socketClient, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 当收到适配器数据。 | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected virtual void OnReceived(TClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         /// <param name="e"></param> | ||||
|         protected virtual Task OnReceived(TClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|  | ||||
|         #endregion 事件 | ||||
| @@ -224,7 +227,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             return Interlocked.Increment(ref this.m_nextId).ToString(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 获取下一个新Id | ||||
|         /// </summary> | ||||
| @@ -363,7 +365,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <inheritdoc/> | ||||
|         public override IService Setup(TouchSocketConfig config) | ||||
|         { | ||||
|  | ||||
|             if (config == null) | ||||
|             { | ||||
|                 throw new ArgumentNullException(nameof(config)); | ||||
| @@ -434,7 +435,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                             ReuseAddress = this.Config.GetValue(TouchSocketConfigExtension.ReuseAddressProperty), | ||||
|                             NoDelay = this.Config.GetValue(TouchSocketConfigExtension.NoDelayProperty), | ||||
|                             Adapter = this.Config.GetValue(TouchSocketConfigExtension.TcpDataHandlingAdapterProperty), | ||||
|                             ReceiveType = this.Config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty) | ||||
|                         }; | ||||
|                         option.Backlog = this.Config.GetValue(TouchSocketConfigExtension.BacklogProperty) ?? option.Backlog; | ||||
|                         option.SendTimeout = this.Config.GetValue(TouchSocketConfigExtension.SendTimeoutProperty); | ||||
| @@ -540,11 +540,11 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 this.Clear(); | ||||
|  | ||||
|                 this.m_serverState = ServerState.Disposed; | ||||
|                 if (this.PluginsManager?.Enable == true) | ||||
|                 if (this.PluginsManager.Enable) | ||||
|                 { | ||||
|                     this.m_pluginsManager.Raise(nameof(IServerStopedPlugin.OnServerStoped), this, new ServiceStateEventArgs(this.m_serverState, default)); | ||||
|                 } | ||||
|                 this.PluginsManager?.SafeDispose(); | ||||
|                 this.PluginsManager.SafeDispose(); | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
| @@ -691,7 +691,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             return new NormalDataHandlingAdapter(); | ||||
|         } | ||||
|  | ||||
|         private void OnClientSocketInit(object obj) | ||||
|         private async Task OnClientSocketInit(object obj) | ||||
|         { | ||||
|             var tuple = (Tuple<Socket, TcpNetworkMonitor>)obj; | ||||
|             var socket = tuple.Item1; | ||||
| @@ -717,30 +717,35 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 { | ||||
|                     client.SetDataHandlingAdapter(this.GetAdapter(monitor)); | ||||
|                 } | ||||
|                 client.InternalInitialized(); | ||||
|  | ||||
|                 await client.InternalInitialized(); | ||||
|  | ||||
|                 var args = new ConnectingEventArgs(socket) | ||||
|                 { | ||||
|                     Id = this.GetNextNewId() | ||||
|                 }; | ||||
|                 client.InternalConnecting(args);//Connecting | ||||
|                 await client.InternalConnecting(args);//Connecting | ||||
|                 if (args.IsPermitOperation) | ||||
|                 { | ||||
|                     client.InternalSetId(args.Id); | ||||
|                     if (!client.MainSocket.Connected) | ||||
|                     if (!socket.Connected) | ||||
|                     { | ||||
|                         client.MainSocket.SafeDispose(); | ||||
|                         socket.SafeDispose(); | ||||
|                         return; | ||||
|                     } | ||||
|                     if (this.m_socketClients.TryAdd(client)) | ||||
|                     { | ||||
|                         client.InternalConnected(new ConnectedEventArgs()); | ||||
|  | ||||
|                         _ = client.InternalConnected(new ConnectedEventArgs()); | ||||
|                         if (!socket.Connected) | ||||
|                         { | ||||
|                             return; | ||||
|                         } | ||||
|                         if (monitor.Option.UseSsl) | ||||
|                         { | ||||
|                             try | ||||
|                             { | ||||
|                                 client.BeginReceiveSsl(monitor.Option.ServiceSslOption); | ||||
|                                 await client.AuthenticateAsync(monitor.Option.ServiceSslOption); | ||||
|                                 _ = client.BeginReceiveSsl(); | ||||
|                             } | ||||
|                             catch (Exception ex) | ||||
|                             { | ||||
| @@ -772,7 +777,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// TCP服务器 | ||||
|     /// Tcp服务器 | ||||
|     /// </summary> | ||||
|     public class TcpService : TcpService<SocketClient> | ||||
|     { | ||||
| @@ -781,16 +786,14 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         public ReceivedEventHandler<SocketClient> Received { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override void OnReceived(SocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override Task OnReceived(SocketClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             this.Received?.Invoke(socketClient, byteBlock, requestInfo); | ||||
|             base.OnReceived(socketClient, byteBlock, requestInfo); | ||||
|             if (this.Received != null) | ||||
|             { | ||||
|                 return this.Received.Invoke(socketClient, e); | ||||
|             } | ||||
|             return EasyTask.CompletedTask; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -22,6 +22,7 @@ | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
| using System.Collections.Concurrent; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Sockets | ||||
| { | ||||
| @@ -122,29 +123,64 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <returns></returns> | ||||
|         public abstract IService Stop(); | ||||
|  | ||||
|         internal void OnInternalConnected(ISocketClient socketClient, ConnectedEventArgs e) | ||||
|         private ConcurrentStack<TcpCore> m_tcpCores = new ConcurrentStack<TcpCore>(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 租用TcpCore | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         public TcpCore RentTcpCore() | ||||
|         { | ||||
|             this.OnClientConnected(socketClient, e); | ||||
|             if (this.m_tcpCores.TryPop(out var tcpCore)) | ||||
|             { | ||||
|                 return tcpCore; | ||||
|             } | ||||
|  | ||||
|             return new InternalTcpCore(); | ||||
|         } | ||||
|  | ||||
|         internal void OnInternalConnecting(ISocketClient socketClient, ConnectingEventArgs e) | ||||
|         /// <inheritdoc/> | ||||
|         protected override void Dispose(bool disposing) | ||||
|         { | ||||
|             this.OnClientConnecting(socketClient, e); | ||||
|             while (this.m_tcpCores.TryPop(out var tcpCore)) | ||||
|             { | ||||
|                 tcpCore.SafeDispose(); | ||||
|             } | ||||
|             base.Dispose(disposing); | ||||
|         } | ||||
|  | ||||
|         internal void OnInternalDisconnected(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         /// <summary> | ||||
|         /// 归还TcpCore | ||||
|         /// </summary> | ||||
|         /// <param name="tcpCore"></param> | ||||
|         public void ReturnTcpCore(TcpCore tcpCore) | ||||
|         { | ||||
|             this.OnClientDisconnected(socketClient, e); | ||||
|             this.m_tcpCores.Push(tcpCore); | ||||
|         } | ||||
|  | ||||
|         internal void OnInternalDisconnecting(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         internal Task OnInternalConnected(ISocketClient socketClient, ConnectedEventArgs e) | ||||
|         { | ||||
|             this.OnClientDisconnecting(socketClient, e); | ||||
|             return this.OnClientConnected(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         internal void OnInternalReceivedData(ISocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         internal Task OnInternalConnecting(ISocketClient socketClient, ConnectingEventArgs e) | ||||
|         { | ||||
|             this.OnClientReceivedData(socketClient, byteBlock, requestInfo); | ||||
|             return this.OnClientConnecting(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         internal Task OnInternalDisconnected(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             return this.OnClientDisconnected(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         internal Task OnInternalDisconnecting(ISocketClient socketClient, DisconnectEventArgs e) | ||||
|         { | ||||
|             return this.OnClientDisconnecting(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         internal Task OnInternalReceivedData(ISocketClient socketClient, ReceivedDataEventArgs e) | ||||
|         { | ||||
|             return this.OnClientReceivedData(socketClient, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -152,39 +188,35 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected abstract void OnClientConnected(ISocketClient socketClient, ConnectedEventArgs e); | ||||
|         protected abstract Task OnClientConnected(ISocketClient socketClient, ConnectedEventArgs e); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 客户端请求连接 | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected abstract void OnClientConnecting(ISocketClient socketClient, ConnectingEventArgs e); | ||||
|         protected abstract Task OnClientConnecting(ISocketClient socketClient, ConnectingEventArgs e); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 客户端断开连接 | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected abstract void OnClientDisconnected(ISocketClient socketClient, DisconnectEventArgs e); | ||||
|         protected abstract Task OnClientDisconnected(ISocketClient socketClient, DisconnectEventArgs e); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 即将断开连接(仅主动断开时有效)。 | ||||
|         /// <para> | ||||
|         /// 当主动调用Close断开时,可通过<see cref="MsgPermitEventArgs.IsPermitOperation"/>终止断开行为。 | ||||
|         /// </para> | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="e"></param> | ||||
|         protected abstract void OnClientDisconnecting(ISocketClient socketClient, DisconnectEventArgs e); | ||||
|         protected abstract Task OnClientDisconnecting(ISocketClient socketClient, DisconnectEventArgs e); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 收到数据时 | ||||
|         /// </summary> | ||||
|         /// <param name="socketClient"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected abstract void OnClientReceivedData(ISocketClient socketClient, ByteBlock byteBlock, IRequestInfo requestInfo); | ||||
|         /// <param name="e"></param> | ||||
|         protected abstract Task OnClientReceivedData(ISocketClient socketClient, ReceivedDataEventArgs e); | ||||
|  | ||||
|         #region Id发送 | ||||
|  | ||||
|   | ||||
| @@ -36,17 +36,20 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <summary> | ||||
|         /// 当收到数据时 | ||||
|         /// </summary> | ||||
|         public UdpReceivedEventHandler Received { get; set; } | ||||
|         public UdpReceivedEventHandler<UdpSession> Received { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="remoteEndPoint"></param> | ||||
|         /// <param name="byteBlock"></param> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected override async Task ReceivedData(UdpReceivedDataEventArgs e) | ||||
|         { | ||||
|             this.Received?.Invoke(remoteEndPoint, byteBlock, requestInfo); | ||||
|             if (this.Received != null) | ||||
|             { | ||||
|                 await this.Received.Invoke(this, e); | ||||
|                 if (e.Handled) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             await base.ReceivedData(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -70,16 +73,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             this.SendBufferSize = 1024 * 64; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 处理未经过适配器的数据。返回值表示是否继续向下传递。 | ||||
|         /// </summary> | ||||
|         public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 处理经过适配器后的数据。返回值表示是否继续向下传递。 | ||||
|         /// </summary> | ||||
|         public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
| @@ -342,7 +335,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|                 this.PluginsManager.Raise(nameof(IServerStartedPlugin.OnServerStarted), this, new ServiceStateEventArgs(this.ServerState, ex) { Message = ex.Message }); | ||||
|                 throw; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -391,11 +383,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <summary> | ||||
|         /// 处理已接收到的数据。 | ||||
|         /// </summary> | ||||
|         /// <param name="remoteEndPoint"></param> | ||||
|         /// <param name="byteBlock">以二进制流形式传递</param> | ||||
|         /// <param name="requestInfo">以解析的数据对象传递</param> | ||||
|         protected virtual void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         protected virtual Task ReceivedData(UdpReceivedDataEventArgs e) | ||||
|         { | ||||
|             return this.PluginsManager.RaiseAsync(nameof(IUdpReceivedPlugin.OnUdpReceived), this, e); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -492,7 +482,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|             #endregion | ||||
|             #endregion Windows下UDP连接被重置错误10054 | ||||
|  | ||||
|             this.PreviewBind(socket); | ||||
|  | ||||
| @@ -500,55 +490,48 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|  | ||||
|             this.Monitor = new UdpNetworkMonitor(iPHost, socket); | ||||
|  | ||||
|             switch (this.Config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty)) | ||||
|  | ||||
| #if NET45_OR_GREATER || NET6_0_OR_GREATER | ||||
|             for (var i = 0; i < threadCount; i++) | ||||
|             { | ||||
|                 case ReceiveType.Iocp: | ||||
|                     { | ||||
| #if NET45_OR_GREATER||NET6_0_OR_GREATER | ||||
|                         for (var i = 0; i < threadCount; i++) | ||||
|                         { | ||||
|                             var eventArg = new SocketAsyncEventArgs(); | ||||
|                             this.m_socketAsyncs.Add(eventArg); | ||||
|                             eventArg.Completed += this.IO_Completed; | ||||
|                             var byteBlock = new ByteBlock(this.ReceiveBufferSize); | ||||
|                             eventArg.UserToken = byteBlock; | ||||
|                             eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity); | ||||
|                             eventArg.RemoteEndPoint = iPHost.EndPoint; | ||||
|                             if (!socket.ReceiveFromAsync(eventArg)) | ||||
|                             { | ||||
|                                 this.ProcessReceive(socket, eventArg); | ||||
|                             } | ||||
|                         } | ||||
| #else | ||||
|                         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||||
|                         { | ||||
|                             for (var i = 0; i < threadCount; i++) | ||||
|                             { | ||||
|                                 var eventArg = new SocketAsyncEventArgs(); | ||||
|                                 this.m_socketAsyncs.Add(eventArg); | ||||
|                                 eventArg.Completed += this.IO_Completed; | ||||
|                                 var byteBlock = new ByteBlock(this.ReceiveBufferSize); | ||||
|                                 eventArg.UserToken = byteBlock; | ||||
|                                 eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity); | ||||
|                                 eventArg.RemoteEndPoint = iPHost.EndPoint; | ||||
|                                 if (!socket.ReceiveFromAsync(eventArg)) | ||||
|                                 { | ||||
|                                     this.ProcessReceive(socket, eventArg); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             var thread = new Thread(this.Received); | ||||
|                             thread.IsBackground = true; | ||||
|                             thread.Start(); | ||||
|                         } | ||||
| #endif | ||||
|                         break; | ||||
|                     } | ||||
|                 default: | ||||
|                     throw new Exception("UDP中只支持Auto模式"); | ||||
|                 var eventArg = new SocketAsyncEventArgs(); | ||||
|                 this.m_socketAsyncs.Add(eventArg); | ||||
|                 eventArg.Completed += this.IO_Completed; | ||||
|                 var byteBlock = new ByteBlock(this.ReceiveBufferSize); | ||||
|                 eventArg.UserToken = byteBlock; | ||||
|                 eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity); | ||||
|                 eventArg.RemoteEndPoint = iPHost.EndPoint; | ||||
|                 if (!socket.ReceiveFromAsync(eventArg)) | ||||
|                 { | ||||
|                     this.ProcessReceive(socket, eventArg); | ||||
|                 } | ||||
|             } | ||||
| #else | ||||
|             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) | ||||
|             { | ||||
|                 for (var i = 0; i < threadCount; i++) | ||||
|                 { | ||||
|                     var eventArg = new SocketAsyncEventArgs(); | ||||
|                     this.m_socketAsyncs.Add(eventArg); | ||||
|                     eventArg.Completed += this.IO_Completed; | ||||
|                     var byteBlock = new ByteBlock(this.ReceiveBufferSize); | ||||
|                     eventArg.UserToken = byteBlock; | ||||
|                     eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity); | ||||
|                     eventArg.RemoteEndPoint = iPHost.EndPoint; | ||||
|                     if (!socket.ReceiveFromAsync(eventArg)) | ||||
|                     { | ||||
|                         this.ProcessReceive(socket, eventArg); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var thread = new Thread(this.Received); | ||||
|                 thread.IsBackground = true; | ||||
|                 thread.Start(); | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private void Received() | ||||
| @@ -577,10 +560,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             try | ||||
|             { | ||||
|                 this.LastReceivedTime = DateTime.Now; | ||||
|                 if (this.OnHandleRawBuffer?.Invoke(byteBlock) == false) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|                 if (this.DisposedValue) | ||||
|                 { | ||||
|                     return; | ||||
| @@ -609,21 +588,14 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|  | ||||
|         private void PrivateHandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo) | ||||
|         { | ||||
|             if (this.OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false) | ||||
|             if (this.m_receiver != null) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this.PluginsManager.Enable) | ||||
|             { | ||||
|                 var args = new UdpReceivedDataEventArgs(remoteEndPoint, byteBlock, requestInfo); | ||||
|                 this.PluginsManager.Raise(nameof(IUdpReceivedPlugin.OnUdpReceived), this, args); | ||||
|                 if (args.Handled) | ||||
|                 if (this.m_receiver.TryInputReceive(byteBlock, requestInfo)) | ||||
|                 { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             this.HandleReceivedData(remoteEndPoint, byteBlock, requestInfo); | ||||
|             this.ReceivedData(new UdpReceivedDataEventArgs(remoteEndPoint, byteBlock, requestInfo)).GetFalseAwaitResult(); | ||||
|         } | ||||
|  | ||||
|         #region 向默认远程同步发送 | ||||
| @@ -663,7 +635,7 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             { | ||||
|                 throw new NotSupportedException($"当前适配器不支持对象发送。"); | ||||
|             } | ||||
|             this.DataHandlingAdapter.SendInput(requestInfo); | ||||
|             //this.DataHandlingAdapter.SendInput(requestInfo); | ||||
|         } | ||||
|  | ||||
|         #endregion 向默认远程同步发送 | ||||
| @@ -682,9 +654,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         public virtual Task SendAsync(byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return Task.Run(() => | ||||
|               { | ||||
|                   this.Send(buffer, offset, length); | ||||
|               }); | ||||
|             { | ||||
|                 this.Send(buffer, offset, length); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
| @@ -737,9 +709,9 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         public virtual Task SendAsync(EndPoint remoteEP, byte[] buffer, int offset, int length) | ||||
|         { | ||||
|             return Task.Run(() => | ||||
|              { | ||||
|                  this.Send(remoteEP, buffer, offset, length); | ||||
|              }); | ||||
|             { | ||||
|                 this.Send(remoteEP, buffer, offset, length); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         #endregion 向设置的远程异步发送 | ||||
| @@ -906,5 +878,23 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         } | ||||
|  | ||||
|         #endregion 组合发送 | ||||
|  | ||||
|         #region Receiver | ||||
|  | ||||
|         private Receiver m_receiver; | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public IReceiver CreateReceiver() | ||||
|         { | ||||
|             return this.m_receiver ??= new Receiver(this); | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc/> | ||||
|         public void ClearReceiver() | ||||
|         { | ||||
|             this.m_receiver = null; | ||||
|         } | ||||
|  | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
| @@ -91,15 +91,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override void PreviewSend(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new System.NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -365,15 +365,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|         /// <param name="requestInfo"></param> | ||||
|         protected override void PreviewSend(IRequestInfo requestInfo) | ||||
|         { | ||||
|             throw new NotImplementedException(); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// <inheritdoc/> | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -22,67 +22,57 @@ | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
| using System.Net; | ||||
|  | ||||
| /// <summary> | ||||
| /// 显示信息 | ||||
| /// </summary> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void MessageEventHandler<TClient>(TClient client, MsgPermitEventArgs e); | ||||
| namespace ThingsGateway.Foundation.Sockets | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Connected | ||||
|     /// </summary> | ||||
|     /// <typeparam name="TClient"></typeparam> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate Task ConnectedEventHandler<TClient>(TClient client, ConnectedEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// 普通通知 | ||||
| /// </summary> | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void TouchSocketEventHandler<TClient>(TClient client, PluginEventArgs e); | ||||
|     /// <summary> | ||||
|     /// Connecting | ||||
|     /// </summary> | ||||
|     /// <typeparam name="TClient"></typeparam> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate Task ConnectingEventHandler<TClient>(TClient client, ConnectingEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// Id修改通知 | ||||
| /// </summary> | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void IdChangedEventHandler<TClient>(TClient client, IdChangedEventArgs e); | ||||
|     /// <summary> | ||||
|     /// 客户端断开连接 | ||||
|     /// </summary> | ||||
|     /// <typeparam name="TClient"></typeparam> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate Task DisconnectEventHandler<TClient>(TClient client, DisconnectEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// Connecting | ||||
| /// </summary> | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void ConnectingEventHandler<TClient>(TClient client, ConnectingEventArgs e); | ||||
|     /// <summary> | ||||
|     /// 显示信息 | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate void MessageEventHandler<TClient>(TClient client, MsgPermitEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// Connected | ||||
| /// </summary> | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void ConnectedEventHandler<TClient>(TClient client, ConnectedEventArgs e); | ||||
|     /// <summary> | ||||
|     /// 接收数据 | ||||
|     /// </summary> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate Task ReceivedEventHandler<TClient>(TClient client, ReceivedDataEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// 客户端断开连接 | ||||
| /// </summary> | ||||
| /// <typeparam name="TClient"></typeparam> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="e"></param> | ||||
| public delegate void DisconnectEventHandler<TClient>(TClient client, DisconnectEventArgs e); | ||||
|     /// <summary> | ||||
|     /// 普通通知 | ||||
|     /// </summary> | ||||
|     /// <typeparam name="TClient"></typeparam> | ||||
|     /// <param name="client"></param> | ||||
|     /// <param name="e"></param> | ||||
|     public delegate void TouchSocketEventHandler<TClient>(TClient client, PluginEventArgs e); | ||||
|  | ||||
| /// <summary> | ||||
| /// 接收数据 | ||||
| /// </summary> | ||||
| /// <param name="client"></param> | ||||
| /// <param name="byteBlock"></param> | ||||
| /// <param name="requestInfo"></param> | ||||
| public delegate void ReceivedEventHandler<TClient>(TClient client, ByteBlock byteBlock, IRequestInfo requestInfo); | ||||
|  | ||||
| /// <summary> | ||||
| /// UDP接收 | ||||
| /// </summary> | ||||
| /// <param name="endpoint"></param> | ||||
| /// <param name="byteBlock"></param> | ||||
| /// <param name="requestInfo"></param> | ||||
| public delegate void UdpReceivedEventHandler(EndPoint endpoint, ByteBlock byteBlock, IRequestInfo requestInfo); | ||||
|     /// <summary> | ||||
|     /// Udp接收 | ||||
|     /// </summary> | ||||
|     public delegate Task UdpReceivedEventHandler<TClient>(TClient client, UdpReceivedDataEventArgs e); | ||||
| } | ||||
| @@ -1,48 +0,0 @@ | ||||
| #region copyright | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| //  Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway | ||||
| //  Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway | ||||
| //  使用文档:https://diego2098.gitee.io/thingsgateway-docs/ | ||||
| //  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 | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
| namespace ThingsGateway.Foundation.Sockets | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 接收类型 | ||||
|     /// </summary> | ||||
|     public enum ReceiveType : byte | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 在该模式下,不会投递接收申请,用户可通过<see cref="ITcpClientBase.GetStream"/>,获取到流以后,自己处理接收。 | ||||
|         /// <para>注意:连接端不会感知主动断开</para> | ||||
|         /// </summary> | ||||
|         None, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 该模式下会使用Iocp自动接收数据,然后主动触发。 | ||||
|         /// </summary> | ||||
|         Iocp, | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 该模式下,会使用同步阻塞模式接收数据。注意:使用该模式时,每个回话连接会独占一个线程。 | ||||
|         /// </summary> | ||||
|         Bio | ||||
|     } | ||||
| } | ||||
| @@ -122,18 +122,39 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <inheritdoc cref="ITcpClient.Connect(int)"/> | ||||
|         public static TClient Connect<TClient>(this TClient client, string ipHost, int timeout = 5000) where TClient : ITcpClient | ||||
|         { | ||||
|             client.Setup(ipHost); | ||||
|             TouchSocketConfig config; | ||||
|             if (client.Config == null) | ||||
|             { | ||||
|                 config = new TouchSocketConfig(); | ||||
|                 config.SetRemoteIPHost(ipHost); | ||||
|                 client.Setup(config); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 config = client.Config; | ||||
|                 config.SetRemoteIPHost(ipHost); | ||||
|             } | ||||
|             client.Connect(timeout); | ||||
|             return client; | ||||
|         } | ||||
|  | ||||
|         /// <inheritdoc cref="ITcpClient.ConnectAsync(int)"/> | ||||
|         public static Task<TClient> ConnectAsync<TClient>(this TClient client, string ipHost, int timeout = 5000) where TClient : ITcpClient | ||||
|         public static async Task<TClient> ConnectAsync<TClient>(this TClient client, string ipHost, int timeout = 5000) where TClient : ITcpClient | ||||
|         { | ||||
|             return Task.Run(() => | ||||
|             TouchSocketConfig config; | ||||
|             if (client.Config == null) | ||||
|             { | ||||
|                 return Connect(client, ipHost, timeout); | ||||
|             }); | ||||
|                 config = new TouchSocketConfig(); | ||||
|                 config.SetRemoteIPHost(ipHost); | ||||
|                 client.Setup(config); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 config = client.Config; | ||||
|                 config.SetRemoteIPHost(ipHost); | ||||
|             } | ||||
|             await client.ConnectAsync(timeout); | ||||
|             return client; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|   | ||||
| @@ -22,8 +22,18 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <inheritdoc cref="IService.Start"/> | ||||
|         public static TService Start<TService>(this TService service, params IPHost[] iPHosts) where TService : ITcpService | ||||
|         { | ||||
|             service.Setup(new TouchSocketConfig() | ||||
|                 .SetListenIPHosts(iPHosts)); | ||||
|             TouchSocketConfig config; | ||||
|             if (service.Config == null) | ||||
|             { | ||||
|                 config = new TouchSocketConfig(); | ||||
|                 config.SetListenIPHosts(iPHosts); | ||||
|                 service.Setup(config); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 config = service.Config; | ||||
|                 config.SetListenIPHosts(iPHosts); | ||||
|             } | ||||
|             service.Start(); | ||||
|             return service; | ||||
|         } | ||||
| @@ -35,8 +45,18 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// <inheritdoc cref="IService.Start"/> | ||||
|         public static TService Start<TService>(this TService service, IPHost iPHost) where TService : IUdpSession | ||||
|         { | ||||
|             service.Setup(new TouchSocketConfig() | ||||
|                 .SetBindIPHost(iPHost)); | ||||
|             TouchSocketConfig config; | ||||
|             if (service.Config == null) | ||||
|             { | ||||
|                 config = new TouchSocketConfig(); | ||||
|                 config.SetBindIPHost(iPHost); | ||||
|                 service.Setup(config); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 config = service.Config; | ||||
|                 config.SetBindIPHost(iPHost); | ||||
|             } | ||||
|             service.Start(); | ||||
|             return service; | ||||
|         } | ||||
|   | ||||
| @@ -44,14 +44,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|         /// </summary> | ||||
|         public static readonly DependencyProperty<Func<SingleStreamDataHandlingAdapter>> TcpDataHandlingAdapterProperty = DependencyProperty<Func<SingleStreamDataHandlingAdapter>>.Register("TcpDataHandlingAdapter", () => { return new NormalDataHandlingAdapter(); }); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 接收类型,默认为<see cref="ReceiveType.Iocp"/> | ||||
|         /// <para><see cref="ReceiveType.Iocp"/>为自动接收数据,然后主动触发。</para> | ||||
|         /// <para><see cref="ReceiveType.None"/>为不投递IO接收申请,用户可通过<see cref="ITcpClientBase.GetStream"/>,获取到流以后,自己处理接收。注意:连接端不会感知主动断开</para> | ||||
|         /// 所需类型<see cref="ThingsGateway.Foundation.Sockets. ReceiveType"/> | ||||
|         /// </summary> | ||||
|         public static readonly DependencyProperty<ReceiveType> ReceiveTypeProperty = DependencyProperty<ReceiveType>.Register("ReceiveType", ReceiveType.Iocp); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 数据处理适配器,默认为获取<see cref="UdpDataHandlingAdapter"/> | ||||
|         /// 所需类型<see cref="Func{TResult}"/> | ||||
| @@ -83,20 +75,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|             return config; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 接收类型,默认为<see cref="ReceiveType.Iocp"/> | ||||
|         /// <para><see cref="ReceiveType.Iocp"/>为自动接收数据,然后主动触发。</para> | ||||
|         /// <para><see cref="ReceiveType.None"/>为不投递IO接收申请,用户可通过<see cref="ITcpClientBase.GetStream"/>,获取到流以后,自己处理接收。注意:连接端不会感知主动断开</para> | ||||
|         /// </summary> | ||||
|         /// <param name="config"></param> | ||||
|         /// <param name="value"></param> | ||||
|         /// <returns></returns> | ||||
|         public static TouchSocketConfig SetReceiveType(this TouchSocketConfig config, ReceiveType value) | ||||
|         { | ||||
|             config.SetValue(ReceiveTypeProperty, value); | ||||
|             return config; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 设置(Udp系)数据处理适配器。 | ||||
|         /// </summary> | ||||
|   | ||||
| @@ -30,16 +30,16 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|     /// </summary> | ||||
|     public interface IClient : IDependencyObject, IDisposable, ISocket | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 获取一个同步数据接收器 | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         IReceiver CreateReceiver(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 处理未经过适配器的数据。返回值表示是否继续向下传递。 | ||||
|         /// 移除同步数据接收器 | ||||
|         /// </summary> | ||||
|         Func<ByteBlock, bool> OnHandleRawBuffer { get; set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 处理经过适配器后的数据。返回值表示是否继续向下传递。 | ||||
|         /// </summary> | ||||
|         Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; } | ||||
|         void ClearReceiver(); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 终端协议 | ||||
|   | ||||
| @@ -22,7 +22,6 @@ | ||||
| //  感谢您的下载和使用 | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
| using System.Net.Sockets; | ||||
|  | ||||
| namespace ThingsGateway.Foundation.Sockets | ||||
| { | ||||
| @@ -46,8 +45,6 @@ namespace ThingsGateway.Foundation.Sockets | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 异步发送数据。 | ||||
|         /// <para>在<see cref="ITcpClient"/>时,如果使用独立线程发送,则不会触发异常。</para> | ||||
|         /// <para>在<see cref="ITcpClientBase"/>时,相当于<see cref="Socket.BeginSend(byte[], int, int, SocketFlags, out SocketError, System.AsyncCallback, object)"/>。</para> | ||||
|         /// <para>该发送会经过适配器封装,具体封装内容由适配器决定。</para> | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">数据缓存区</param> | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user