Skip to content

feat: 增加会话感知的发送确认与消息上下文 #39

Description

@CSJ608

背景

StreamConnection<TMessage>.SendAsync 当前在消息写入连接级发送队列后完成;发送失败时,尚未发送的消息会保留在队列中,并由重连后的新会话继续发送。这个语义适合允许重放的普通业务协议,但部分有严格会话边界的协议需要更强的保证。

以 HSMS-SS 为例:

  • TCP 重连后是一个全新的 HSMS 会话,必须重新完成 Select;
  • 旧会话中的数据消息不能自动在新会话重放;
  • T3/T6 等协议计时器应从整帧实际写完 Socket 后开始,而不是从成功入队时开始;
  • 接收侧需要识别消息所属会话,避免旧解码任务的迟到消息被归入新会话。

该需求来自基于 StreamFrame 开发的 CSJ608/SecsFrame,但能力本身不应包含任何 SECS/HSMS 专用概念。

期望能力

希望增加一个向后兼容的高级会话 API;具体命名可以在实现时调整,关键语义如下:

  1. 每次成功建立 TCP 会话后产生单调递增、不可复用的 SessionId
  2. 提供绑定当前会话的发送方法,例如 SendInSessionAsync(sessionId, message)
  3. 返回任务只在整帧全部写入 Socket 后完成。
  4. 若指定会话在发送完成前终止,任务以明确的会话失效异常或取消结束。
  5. 会话失败后的消息不得自动转移到新会话重放。
  6. 高级接收 API 能携带消息对应的 SessionId
  7. 保留现有 SendAsync 和跨重连消息流的兼容行为。

建议测试

  • 整帧写完之前,发送任务不完成。
  • 部分写入后 Socket 失败,发送任务失败且消息不在新会话重放。
  • 消息排队期间会话切换,旧 SessionId 的发送失败。
  • 重连后新 SessionId 可以正常发送。
  • 旧会话解码任务迟到退出时,消息仍带旧 SessionId
  • 并发发送继续保持帧级串行化。

验收标准

  • 新能力有清晰的 XML 文档和生命周期说明。
  • 不改变现有 API 的行为。
  • net8.0、net10.0、net48 测试矩阵全部通过。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions