跳到主要内容

v4.2.2(3)

更新日期: 2026.4.11

更新描述:

  • DMTP Relay 注册与重连机制重构:TouchSocketPro.Dmtp 的 Relay 功能引入 RelayId 作为稳定标识,服务端新增 RelayRegistration 注册模型统一管理监听器与 Actor 绑定;Relay 客户端在 DMTP 重连后可自动等待上线并续约端口映射,IRelayService 接口同步升级为基于 RelayId/地址的签名。⚠️ 破坏性变更
  • PLC Operator 类型桥接新增:TouchSocketPro.PlcBridges 新增 IPlcOperator.As<TValueSource, TValueTarget> 系列扩展和 PlcOperatorAsWrapper,支持在不同 PLC 值类型之间按字节级别复用同一个操作器,并可控制统一或分别指定源/目标字节序。
  • PLC 同步写入扩展移除IPlcOperatorExtension.Write<TValue, TWritableValue> 同步扩展方法已删除,公共 API 仅保留异步写入路径。⚠️ 破坏性变更
  • Modbus 输入寄存器读取修复ModbusInputRegistersDrive 读取输入寄存器时改用正确的 StartingAddress 字段构造请求,修复错误地址字段导致的读输入寄存器异常。

更新详情:

TouchSocketPro.Dmtp

  •   DmtpRelayPackageRelayClientOptionRelayResponse 全面引入 RelayIdDmtpRelayActor 改为同时维护 RelayId -> InternalRelayClientRemoteIPHost -> RelayId 双索引;所有注册、建链、数据、断链包统一携带 RelayIdLocalIPHostRemoteIPHost,中继路由不再仅依赖 RemoteIPHost
  •   RelayService 引入 RelayRegistration 注册对象统一管理监听器、IDmtpActor 绑定和连接状态;RegisterPortAsyncUnregisterPortAsyncHandleReceivedDataAsyncHandleConnectionClosedAsync 全部升级为 RelayId 感知接口,并新增 HandleDmtpClosed。⚠️ 破坏性变更
  •   DmtpRelayFeature 新增 IDmtpConnectedPluginIDmtpClosedPlugin 生命周期处理;DmtpRelayActor 在连接建立后自动续约已有中继,在连接关闭时重置在线等待状态并通知 RelayService 解绑 Actor。
  •   InternalRelayClient 引入注册信号量、关闭令牌、一次性注销状态控制和 EnsureRegisteredAsync 流程;RelayConnection 在本地连接关闭时会主动同步远端关闭事件,在服务端主动关闭时通过 CloseFromServerAsync 避免重复回流,提升端口映射长连接场景的稳定性。
  •   DmtpRelayActor 现在对未配置 IRelayService、未提供注册回调、重复添加中继客户端、注册失败回滚等场景具备完整保护,避免异常时残留无效中继状态。

TouchSocketPro.PlcBridges

  •   IPlcOperatorExtension 新增 As<TValueSource, TValueTarget> 三个扩展重载,支持默认字节序、统一字节序或分别指定源/目标字节序。
  •   PlcOperatorAsWrapper<TValueSource, TValueTarget> 适配器,可将 IPlcOperator<TValueSource> 包装为 IPlcOperator<TValueTarget>;读取时按长度换算并完成类型转换,写入时反向转换后透传到底层 Operator,实现不同 PLC 值类型之间的无缝桥接。
  •   IPlcOperatorExtension.Write<TValue, TWritableValue> 同步扩展方法已删除,公共 API 仅保留异步写入路径。⚠️ 破坏性变更

TouchSocketPro.Modbus

  •   ModbusInputRegistersDrive.ExecuteReadAsync 构造 ModbusRequest 时将输入寄存器读取地址字段从 ReadStartAddress 更正为 StartingAddress,修复读取输入寄存器时请求地址写入错误的问题。

v4.2.1

更新日期: 2026.4.4

更新描述:

  • Modbus 功能码处理器注册表架构重构:引入 ModbusFunctionHandlerRegistry 可扩展功能码处理器注册机制,彻底替代原有的 if-else 功能码分支逻辑;所有 Modbus 主站组件均暴露 FunctionHandlerRegistry 属性,支持自定义扩展功能码;适配器与请求/响应对象统一通过注册表委派 PDU 构建与解析;ModbusRtuAdapter/ModbusUdpRtuAdapter 使用 ArrayPool<byte>.Shared 避免解析时堆内存分配。
  • 发送逻辑代码注入统一化TcpClientBase 新增 ProtectedSendAsync<TRequestInfoBuilder> 泛型方法,通过 CodeInject.RegionInject 将发送逻辑统一注入 TcpSessionClientBaseNamedPipeClientBaseNamedPipeSessionClientBaseSerialPortClientBase,消除各客户端组件中大量重复发送代码。
  • HTTP Header 重复写入修复HttpBaseContentLength/ContentType/TransferEncoding 属性赋值改用索引器替代 Add/AddInternal,防止重复设置时产生重复 Header 条目;新增 Content-Type 快路径解析分支。
  • DmtpRpcActor 内存分配优化:移除临时 ValueByteBlock 分配,直接调用 DmtpActor.SendAsync(token, IPackage) 重载,降低内存分配和代码复杂度。
  • ReconnectionOptionsExtension 参数语义调整UseDmtpCheckAction 参数 pingTimeout 重命名为 pingInterval,语义变更为"相邻两次 Ping 之间的最小间隔"。⚠️ 破坏性变更
  • WebApi ContentType 设置行为修正WebApiParserPlugin 仅在用户未显式设置 ContentType 时才应用框架默认值,允许 Action 方法自定义响应 Content-Type
  • 并发 RPC 调度修复ConcurrencyRpcDispatcherEasyTask.SafeRun 改为 EasyTask.SafeNewRun,修复高并发下 RPC 调用的线程调度问题。

更新详情:

TouchSocket

  •   TcpClientBase 新增 ProtectedSendAsync<TRequestInfoBuilder> 泛型方法,通过 CodeInject.RegionInject 机制将统一的发送逻辑注入到 TcpSessionClientBaseNamedPipeClientBaseNamedPipeSessionClientBaseSerialPortClientBase,消除各组件中大量重复的 #region 发送#region Throw 代码块。

TouchSocket.Http

  •   HttpBaseContentLengthContentTypeTransferEncoding 属性赋值改用索引器(m_headers[key] = value)替代 Add/AddInternal,修复对同一 Header 多次赋值时产生重复条目的问题。
  •   HttpBase.OnParsingHeader 新增 Content-Type 请求头的专项快路径解析分支,提高高频请求场景下的 Header 解析效率。

TouchSocket.Dmtp

  •   DmtpRpcActor.InvokeThisAsync 移除两处临时 ValueByteBlock 分配,直接调用 DmtpActor.SendAsync(token, IPackage) 重载完成 RPC 响应包的打包与发送,降低 GC 压力并简化代码路径。
  •   ReconnectionOptionsExtension.UseDmtpCheckAction 参数 pingTimeout 重命名为 pingInterval,语义由"单次 Ping 操作超时"变更为"相邻两次 Ping 之间的最小间隔时间";内部 Ping 操作超时保持固定 5s。⚠️ 破坏性变更

TouchSocket.Rpc

  •   ConcurrencyRpcDispatcherEasyTask.SafeRun 改为 EasyTask.SafeNewRun,修复高并发场景下多个 RPC 并发调用时可能出现的线程调度竞争问题。

TouchSocket.WebApi

  •   WebApiParserPluginContentType 赋值由无条件覆盖改为判断 httpResponse.ContentType.IsEmpty 后才写入框架默认值,允许 Action 方法在返回前显式设置自定义 Content-Type 不被框架覆盖。

TouchSocket.Modbus

  •   引入 ModbusFunctionHandlerRegistry 可扩展功能码处理器注册表,彻底替代 ModbusRtuAdapterModbusUdpRtuAdapterModbusTcpAdapterForPollModbusUdpAdapterModbusRtuRequestModbusTcpRequestModbusTcpResponse 中原有的 if-else 功能码硬编码分支。
  •   所有 Modbus 主站组件(ModbusRtuMasterModbusRtuOverTcpMasterModbusRtuOverUdpMasterModbusTcpMasterModbusUdpMaster)新增 FunctionHandlerRegistry 属性(默认使用 ModbusFunctionHandlerRegistry.Default),支持注册自定义功能码处理器实现协议扩展。
  •   ModbusRtuAdapterModbusUdpRtuAdapter 解析响应时改用 ArrayPool<byte>.Shared 租借临时缓冲区,避免频繁的堆内存分配。
  •   ModbusTcpRequest.MaxLength 从 1024 扩展至 2048,以支持更大负载的 Modbus TCP 请求帧。
  •   ModbusTcpMaster 移除冗余的 m_semaphoreForConnect 字段。

v4.2.0

更新日期: 2026.3.29

更新描述:

  • ClosedEventArgs 重构:移除 Manual(bool)属性,新增 Exception 属性(携带导致连接关闭的异常对象);构造函数从 ClosedEventArgs(bool manual, string mes) 拆分为 ClosedEventArgs(string mes)ClosedEventArgs(string mes, Exception exception) 两个重载,TcpTransportBaseTransportStreamTransport 同步适配。⚠️ 破坏性变更
  • TcpTransport 发送管道完善:接收循环退出时额外调用 m_pipeSend.Writer.Complete(),确保连接关闭后任何挂起或后续的写入操作立即抛出异常,而非静默"成功"。
  • StaticFilesPool 按需加载(On-Demand Loading)TryFindEntry 缓存未命中时,自动在受监控的文件夹中按 URL 键反向解析物理路径并即时加载入缓存;内置路径安全校验,防止路径遍历攻击。
  • AOT 支持增强ClassCodeGenerator.AddTypeString 补充 [RequiresDynamicCode] 特性;SwaggerPlugin 多处反射/动态代码方法添加 [UnconditionalSuppressMessage] 抑制 AOT 警告;源生成器项目统一配置 <NoWarn> 消除编译器警告。
  • 全局代码规范化:大规模清理 XML 文档中冗余的 <param>/<returns> 标签,补全缺失的文件末尾换行符;移除 TcpClientBase 中遗留的临时调试日志语句。
  • DMTP不兼容更新:Dmtp协议包中新增Version属性,标识协议版本号;协议解析器适配新版本格式,旧版本协议将无法被新解析器识别。⚠️ 破坏性变更

更新详情:

TouchSocket

  •   ClosedEventArgs 构造函数重构:移除 ClosedEventArgs(bool manual, string mes) 重载,改为 ClosedEventArgs(string mes)(正常关闭)与 ClosedEventArgs(string mes, Exception exception)(异常关闭,携带原始异常对象);同步移除 Manual(bool)属性,新增 Exception 属性。⚠️ 破坏性变更
  •   TcpTransport.RunReceive 接收循环退出的 finally 块中,在 pipeReader.Complete() 之后额外调用 m_pipeSend.Writer.Complete(),确保连接关闭后任何对写入管道的 FlushAsync 操作立即失败,防止调用方误认为发送成功。
  •   TcpClientBase 移除 RunSessionAsyncCloseAsyncReceiveLoopAsync 等方法中遗留的临时调试日志([TcpDebug] 系列 Logger.Debug 输出),减少运行时日志噪声。

TouchSocket.Http

  •   StaticFilesPool.TryFindEntry 在缓存未命中时,调用内部方法 TryLoadOnDemand 遍历受监控的文件夹,根据 URL 键反向解析物理文件路径并按需加载入缓存;TryResolvePhysicalPath 包含完整的路径安全校验(Root 边界检查),防止路径遍历攻击。
  •   FolderEntry.AddKeyToDirectory 方法,支持在 StaticFilesPool 写锁保护下向指定目录的跟踪集合追加单个 URL 键。
  •   TryFindEntry 对 URL 键统一规范化处理,确保以 / 开头,提高路径匹配一致性。

TouchSocket.Rpc

  •   ClassCodeGenerator.AddTypeString 及相关私有方法补充 [RequiresDynamicCode] 特性,与已有的 [RequiresUnreferencedCode] 配合,完善 AOT 兼容性标注。

TouchSocket.WebApi.Swagger

  •   SwaggerPluginAddSchemaTypeCreateSchemaGetComponents 方法添加 [UnconditionalSuppressMessage] 特性,抑制裁剪/AOT 分析器警告;csproj 新增 <NoWarn>SYSLIB1034</NoWarn> 消除编译器诊断。

TouchSocket.Dmtp

  •   Dmtp协议包中新增 Version 属性,标识协议版本号;协议解析器适配新版本格式,旧版本协议将无法被新解析器识别。⚠️ 破坏性变更
  •   经过中间服务支持路由包的元数据获取

TouchSocket.Mqtt

  •   客户端在批量发送MQTT消息的时候偶尔会提示:Insufficient space to get memory。

All

  •   大规模清理全库 XML 文档注释中冗余的 <param>/<returns> 标签,补全缺失的文件末尾换行符,统一代码风格。