StreamFrame 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package StreamFrame --version 1.2.0
                    
NuGet\Install-Package StreamFrame -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StreamFrame" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="StreamFrame" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="StreamFrame" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add StreamFrame --version 1.2.0
                    
#r "nuget: StreamFrame, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package StreamFrame@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=StreamFrame&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=StreamFrame&version=1.2.0
                    
Install as a Cake Tool

StreamFrame

NuGet NuGet Downloads

通用 socket 通讯框架:把"帧边界判定"与"帧内数据编解码"插件化,适用于通过 socket 进行数据互换的场景(设备通讯、物流 WMS 对接等)。把场景间的共性(连接管理、重连、读写、粘包/半包、消息分发)收敛到框架核心,把差异性(framing、codec)抽象成可插拔的驱动。

为什么用它

传统手写 StreamFrame
接一种新设备/协议 重写连接、切帧、编解码 只写一个 ICodec<T> 驱动
帧边界(长度前缀 / STX-ETX / 自定义) 各写各的 内置两种 + 可插拔
粘包/半包 手写缓冲拼接 Pipelines 自动处理
重连 / 状态机 手写 内置自动重连
发送性能 多次拷贝 可选流式零拷贝

安装

dotnet add package StreamFrame

XML 报文驱动(可选):

dotnet add package StreamFrame.Protocols.Xml

快速上手

一条连接 = 一个帧定界策略(framing)+ 一个编解码器(codec)+ 地址/端口/模式。framing 与 codec 均连接级固定,一条连接只流通一种消息类型、一种帧格式。

using System.Net;
using System.Xml.Linq;
using StreamFrame;
using StreamFrame.Abstractions;
using StreamFrame.Protocols.Xml;

// 服务端(被动监听)
var server = new StreamConnection<XDocument>(
    new LengthPrefixFrameCodec(),          // 4 字节大端长度头;也可用 StxEtxFrameCodec
    new XmlDocumentCodec(),                // 换成自己的 ICodec<T> 即可支持自定义协议
    IPAddress.Any, 5100, isActive: false);
server.Start(ct);

await foreach (var doc in server.GetMessages(ct))
{
    var id = doc.Root?.Element("Id")?.Value;
    await server.SendAsync(XDocument.Parse($"<Reply><Echo>{id}</Echo></Reply>"), ct);
}

// 客户端(主动连接)
var client = new StreamConnection<XDocument>(
    new LengthPrefixFrameCodec(),
    new XmlDocumentCodec(),
    IPAddress.Parse("127.0.0.1"), 5100, isActive: true);
client.Start(ct);
await client.SendAsync(XDocument.Parse("<Message><Id>1</Id></Message>"), ct);

概念

帧定界(IFrameCodec)— 怎么从字节流里切出一帧

实现 定界方式 适用
LengthPrefixFrameCodec 4 字节大端长度头 + 负载 通用,二进制安全
StxEtxFrameCodec STX 0x02 … ETX 0x03 包裹 XML / 纯文本等已知安全的负载

两种默认实现都支持流式单缓冲编码(可选,消除发送侧 memcpy)。想自定义帧格式时实现 IFrameCodec 即可。

编解码(ICodec<T>)— 怎么解析/写入帧内数据

public interface ICodec<TMessage>
{
    TMessage Decode(in ReadOnlySequence<byte> frame, CancellationToken ct = default);
    void Encode(TMessage message, IBufferWriter<byte> writer, CancellationToken ct = default);
}

接新设备 = 写一个驱动:实现 ICodec<TMessage> + 定义业务消息类,选一个帧策略,其余全部复用。官方示例见 StreamFrame.Protocols.Xml

连接(IStreamConnection<T>)— 传输层

  • 客户端/服务端双模式isActive: true 主动连远端,false 被动监听
  • 自动重连Connecting → Connected → Retry 状态机;GetMessages 是跨重连的稳定消息流——断线重连后已收消息不丢、枚举不中断
  • 健壮性:帧内容解码失败、未完成帧超限、发送失败、接收空闲超时都会判定会话失效并自动重建(不再产生"连接看似存活、消息静默消失"的假活)
  • 活性探测(可选):TCP KeepAlive 与接收空闲超时,兜底半开连接(对端断电/拔线)
  • 事件ConnectionChanged 状态变化、FrameError 帧层诊断、RawBytesReceived/Sent 原始字节(HEX 调试)
  • 发送背压:有界发送队列,队列满时 SendAsync 自动等待

诊断与调试

FrameError — 帧层诊断事件

对端发来坏数据时,FrameError 事件把出问题的字节原因直接交给上层,不用再拿 HEX 流人工对齐:

client.FrameError += (_, e) =>
{
    // e.Kind: DecodeFailed(帧完整但内容解析失败)
    //         DiscardedByResync(被定界器当作噪声丢弃的字节)
    //         IncompleteFrameOverflow(未完成帧缓冲超限)
    // e.Bytes: 已拷贝,可安全长期留存
    // e.Exception: DecodeFailed 时的原始异常
    Console.WriteLine($"[{e.Kind}] {Convert.ToHexString(e.Bytes.Span)} {e.Exception?.Message}");
};

帧内容解码失败的策略由 StreamConnectionOptions.DecodeErrorPolicy 决定:

策略 行为
Disconnect(默认) 断线重连——协议内容错乱后流状态通常不可信
SkipFrame 丢弃坏帧继续,适合噪声多的线路

RawBytesReceived / RawBytesSent — 原始字节流

socket 层全量输出(含被丢弃的噪声字节),发送侧按实际写出的分片回调(部分发送失败时已上线字节也可见)。内存契约:回调参数是内部缓冲的切片,仅在回调同步执行期间有效,需要留存必须自行拷贝;回调抛异常会被隔离,不影响会话。

未完成帧防护

对端声明一个超长帧却永远不补齐(或 STX/ETX 流中只有 STX 没有闭合),会无限占用缓冲。MaxIncompleteFrameBufferBytes(默认 = 帧上限 + 4KB)给"等不齐的半帧"设了硬上限,超限即断线并通过 FrameError 上报。

活性探测建议

生产环境建议开启 TcpKeepAlive = true;有周期性报文的协议可再加 ReceiveIdleTimeoutMs(如心跳周期的 3 倍),双保险兜底半开连接。

依赖

测试与示例

dotnet build StreamFrame.slnx
dotnet test
dotnet run --project samples/StreamFrame.Demo

项目结构

src/StreamFrame/                  # 核心库(无业务依赖)
src/StreamFrame.Protocols.Xml/    # XML 报文驱动(示例 codec)
test/StreamFrame.Tests/           # xUnit 单测
samples/StreamFrame.Demo/         # 控制台端到端 demo

许可

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on StreamFrame:

Package Downloads
StreamFrame.Protocols.Xml

StreamFrame 的 XML 报文示例驱动:XmlDocumentCodec(XmlSerializer / XmlWriter 编解码)。

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.6.0 83 8/29/2026
2.5.0 119 8/29/2026
2.4.0 88 8/29/2026
2.3.1 102 8/28/2026
2.3.0 59 8/28/2026
2.2.1 52 8/27/2026
2.2.0 143 8/27/2026
2.1.0 59 8/27/2026
2.0.0 54 8/27/2026
1.2.0 53 8/27/2026
1.1.0 117 8/4/2026
1.0.1 103 8/3/2026
1.0.0 112 8/3/2026