NetConduit.Transit.DeltaMessage
3.1.2
dotnet add package NetConduit.Transit.DeltaMessage --version 3.1.2
NuGet\Install-Package NetConduit.Transit.DeltaMessage -Version 3.1.2
<PackageReference Include="NetConduit.Transit.DeltaMessage" Version="3.1.2" />
<PackageVersion Include="NetConduit.Transit.DeltaMessage" Version="3.1.2" />
<PackageReference Include="NetConduit.Transit.DeltaMessage" />
paket add NetConduit.Transit.DeltaMessage --version 3.1.2
#r "nuget: NetConduit.Transit.DeltaMessage, 3.1.2"
#:package NetConduit.Transit.DeltaMessage@3.1.2
#addin nuget:?package=NetConduit.Transit.DeltaMessage&version=3.1.2
#tool nuget:?package=NetConduit.Transit.DeltaMessage&version=3.1.2
NetConduit
Transport-agnostic stream multiplexer for .NET. Run many independent virtual channels over a single bidirectional stream — TCP, WebSocket, UDP, IPC, or QUIC — with credit-based backpressure, priority queuing, keepalive, graceful shutdown, and automatic reconnection with replay.
| Core | NuGet | Description |
|---|---|---|
NetConduit |
Multiplexer, channels, framing, reconnection |
| Transits | NuGet | Description |
|---|---|---|
NetConduit.Transit.Stream |
Simplex Stream over one channel |
|
NetConduit.Transit.DuplexStream |
Bidirectional Stream over a channel pair |
|
NetConduit.Transit.Message |
Length-prefixed typed JSON messages | |
NetConduit.Transit.DeltaMessage |
State sync via JSON deltas |
| Transports | NuGet | Description |
|---|---|---|
NetConduit.Transport.Tcp |
TCP sockets | |
NetConduit.Transport.WebSocket |
WebSocket (ClientWebSocket + ASP.NET) |
|
NetConduit.Transport.Udp |
UDP with a reliability shim | |
NetConduit.Transport.Ipc |
TCP loopback (Windows) / Unix domain sockets (Linux/macOS) | |
NetConduit.Transport.Quic |
QUIC over TLS 1.3 |
Each transport and transit package depends on NetConduit, so installing one pulls in the core.
At a glance
+-----------------------------------------+
| Application |
+-----------------------------------------+
| Transits (optional, layered) |
| Stream DuplexStream Message Delta |
+-----------------------------------------+
| NetConduit (core) |
| framing | channels | flow control | |
| priority | keepalive | reconnect |
+-----------------------------------------+
| Transport (single bidirectional |
| IStreamPair) |
| TCP WS UDP IPC QUIC |
+-----------------------------------------+
One physical stream carries any number of independent virtual channels. Each channel has its own buffer, priority, and lifecycle.
Install
Pick one transport and any transits you need:
dotnet add package NetConduit.Transport.Tcp
dotnet add package NetConduit.Transit.Message
Target frameworks: net8.0, net9.0, net10.0. AOT-compatible.
Quick start
A TCP server and client exchanging typed JSON messages.
using System.Text.Json.Serialization;
using NetConduit;
using NetConduit.Models;
using NetConduit.Transit.Message;
using NetConduit.Transport.Tcp;
public record Hello(string Name, int Count);
[JsonSerializable(typeof(Hello))]
internal partial class AppJson : JsonSerializerContext;
// Server
using var listener = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Loopback, 5000);
listener.Start();
await using var server = StreamMultiplexer.Create(TcpMultiplexer.CreateServerOptions(listener));
server.Start();
await server.WaitForReadyAsync();
await using var inbox = await server.AcceptMessageTransitAsync<Hello>("hello", AppJson.Default.Hello);
await foreach (var msg in inbox.ReceiveAllAsync())
Console.WriteLine($"got: {msg!.Name} x{msg.Count}");
// Client
await using var client = StreamMultiplexer.Create(TcpMultiplexer.CreateOptions("127.0.0.1", 5000));
client.Start();
await client.WaitForReadyAsync();
await using var outbox = await client.OpenMessageTransitAsync<Hello>("hello", AppJson.Default.Hello);
await outbox.SendAsync(new Hello("Alice", 1));
await outbox.SendAsync(new Hello("Alice", 2));
That's it. The server can open additional channels for file transfers, control plane, state sync, etc. — all over the same TCP connection.
What you get
- Many channels per stream. Open and accept named channels at will. Each is independently flow-controlled and prioritized.
- Pluggable transport. Swap TCP for WebSocket, UDP, IPC, or QUIC by changing one factory call.
- Transits. Optional layers that turn a channel pair into a
Stream, a typed message queue, or a state-sync delta channel. - Backpressure. Per-channel slab buffers with credit-based flow control. Slow consumers slow down their producer without blocking other channels.
- Priority queuing. Five priority levels (
Lowest…Highest) control writer ordering when channels compete for the wire. - Heartbeats. Configurable ping/pong with a missed-ping threshold detects dead connections quickly.
- Graceful shutdown.
GoAwayAsyncdrains in-flight data before tearing down. - Reconnection with replay. When configured, the multiplexer rebuilds the connection on transport failure and replays buffered frames so open channels survive.
- AOT and trim safe. Core uses no reflection. Message and delta transits accept source-generated
JsonTypeInfo<T>.
Documentation
- Getting started
- Concepts — multiplexer, channels, transports, transits, backpressure, reconnection, events
- Transports — TCP, WebSocket, UDP, IPC, QUIC
- Transits — Stream, DuplexStream, Message, DeltaMessage
- API reference
- Samples
- Benchmarks
Samples
Each sample is a runnable console app. See its README for usage.
| Sample | Demonstrates |
|---|---|
| SimpleTcpTunnel | Port forwarding through a relay over TCP or WebSocket |
| GroupChatSample | Multi-client chat broker (TCP or WebSocket) |
| PongGame | Real-time game state sync via DeltaMessageTransit |
| FileTransferSample | Parallel file streaming with one channel per file |
| RemoteShellSample | SSH-like shell over a single TCP connection |
| RpcFrameworkSample | Async RPC over a typed message transit |
| ScoreboardSample | Persistent leaderboard with client reconnection |
License
MIT — see LICENSE.
| Product | Versions 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 is compatible. 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 is compatible. 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. |
-
net10.0
- NetConduit (>= 3.1.2)
-
net8.0
- NetConduit (>= 3.1.2)
-
net9.0
- NetConduit (>= 3.1.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
## New Apps
* Bump `net_conduit_transit_stream` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transit_stream/3.0.1...net_conduit_transit_stream/3.1.2)
* Bump `net_conduit_transit_duplex_stream` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transit_duplex_stream/3.0.1...net_conduit_transit_duplex_stream/3.1.2)
* Bump `net_conduit_transit_message` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transit_message/3.0.1...net_conduit_transit_message/3.1.2)
* Bump `net_conduit_transit_delta_message` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transit_delta_message/3.0.1...net_conduit_transit_delta_message/3.1.2)
* Bump `net_conduit_transport_tcp` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transport_tcp/3.0.1...net_conduit_transport_tcp/3.1.2)
* Bump `net_conduit_transport_websocket` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transport_websocket/3.0.1...net_conduit_transport_websocket/3.1.2)
* Bump `net_conduit_transport_udp` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transport_udp/3.0.1...net_conduit_transport_udp/3.1.2)
* Bump `net_conduit_transport_ipc` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transport_ipc/3.0.1...net_conduit_transport_ipc/3.1.2)
* Bump `net_conduit_transport_quic` from `3.0.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit_transport_quic/3.0.1...net_conduit_transport_quic/3.1.2)
## What's Changed
* Remove PLAN_MODULAR.md by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/87
* docs: rewrite documentation from scratch by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/89
* Bump NukeBuildHelpers from 9.0.25 to 9.0.26 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/91
* Update .gitignore by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/92
* refactor: standardize -1 as unlimited sentinel for MaxAutoReconnectAttempts by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/93
* Bump coverlet.collector from 10.0.0 to 10.0.1 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/94
* fix(core): handshake retry budget + position-based ACK protocol by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/95
* fix(core): widen ACK position wire field to 64 bits by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/96
* Fix lifecycle heartbeat and reconnect handling by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/98
* Reset one-shot server factory state on cancellation by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/118
* Fix DeltaMessage array delta correctness by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/119
* Validate channel IDs and apply open defaults by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/120
* fix(events,stats): defer ChannelOpened until ready and fix Uptime unit by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/121
* Bump NukeBuildHelpers from 9.0.26 to 9.0.27 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/128
* Add benchmark performance gate to NUKE CI by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/129
* fix(protocol): validate frame length and enforce receiver slab capacity by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/127
* fix(udp): throw TimeoutException when NC_HELLO_ACK is not received by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/126
* fix(goaway): drain channels and abort on timeout by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/124
* fix(channel): raise Ready/ChannelOpened before completing readyTcs by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/130
* fix(transit): deliver EOF on sync Dispose and clean up on async cancellation by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/123
* feat(core): prefix-filtered AcceptChannelsAsync overload by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/97
* fix(channel): harden WriteChannel lifecycle and validate peer ACK by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/131
* docs(mux): correct StreamMultiplexer class summary by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/136
* docs(api): document AcceptChannelsAsync 3-tier dispatch order + contract test by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/137
* fix(transit): reject reserved ">>" "<<" substrings in transit base channel IDs by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/141
* chore(build): centralize NetConduit package version into src/Directory.Build.props by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/144
* docs: add scope page (mux responsibilities, trust model, out-of-scope concerns) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/145
* docs(transports): document reconnectable server-side factories per transport by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/146
* docs(stats): correct MultiplexerStats counters as wire bytes (not payload) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/149
* docs(events): clarify ChannelClosed vs Closed event asymmetry by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/148
* feat(api): validate ChannelOptions.SlabSize against documented bounds by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/150
* refactor(api): remove misplaced `IMessageTransit<,>` interface from core [arch-013] by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/154
* refactor(api): remove dead `MultiplexerOptions.DefaultSlabSize` property [arch-011] by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/151
* feat(api): validate timing/multiplier options at `MultiplexerOptions` boundary [arch-012] by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/153
* feat(api): add atomic TryRegisterChannels primitive (toward #138) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/155
* fix(transit): migrate composite transits to atomic TryRegisterChannels (fixes #138) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/157
* fix(transport/udp): reset one-shot guard on failed accept by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/158
* fix(channels): release prefix subscription when enumerable is discarded by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/159
* fix(channels): prevent pending-accept resurrection on peer INIT by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/160
* fix(ReadChannel): unregister CancellationTokenRegistration on completion (fixes #162) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/170
* fix(WriteChannel): return slab unconditionally on terminal close (fixes #169) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/171
* refactor(NetConduit): extract MuxConnection field container by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/167
* refactor(NetConduit): move transport state into MuxConnection by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/174
* refactor(NetConduit): pass MuxConnection into loop methods as parameter by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/184
* fix(transit/message): parenthesize IsConnected disjunction (fixes #166) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/181
* fix(transit/message): use explicit EOF flag in ReceiveAllAsync so value-type streams terminate by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/188
* fix(streampair): run every dispose step unconditionally and aggregate errors (fixes #218) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/224
* fix(websocket): dispose wrapped WebSocket and send Close frame (fixes #204) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/235
* fix(transport): dispose TcpClient/ClientWebSocket on failed connect in StreamFactory (fixes #216) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/243
* fix(delta): emit Set op when property added with JSON null value (fixes #211) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/246
* fix(transport/udp): drop datagrams whose declared length mismatches payload (fixes #187) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/221
* fix(transport/websocket): reject non-Binary data frames in ReadAsync (fixes #217) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/227
* fix(websocket): dispose orphan pair when HandleAsync fails before mux ownership (fixes #225) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/238
* fix(websocket): preserve baseUri query params on reconnect (fixes #178) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/244
* fix(core): WriteAsync unwinds promptly with ChannelClosedException when closed under back-pressure (fixes #230) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/247
* fix(core): remote-initiated GoAway aborts local channels (fixes #234) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/248
* fix(NetConduit): make event raise multicast-safe and observable by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/249
* fix(transit/message): preserve receive framing across cancellation (fixes #240) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/254
* fix(transit/duplex-stream): IsConnected requires both directions (fixes #210) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/259
* fix(transport/ipc): refuse to overwrite non-socket endpoint path (fixes #189) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/190
* fix(core): ReadChannel.SetClosed returns slab to pool on all close paths (fixes #199) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/245
* fix(transit/message): yield legit JSON null payload in ReceiveAllAsync (fixes #220) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/263
* fix(core): prevent WriteChannel slab use-after-free on close (fixes #258) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/270
* test(transport/websocket): fix shutdown-ordering race in CreateOptions_ConnectsAndTransfersData by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/283
* refactor(core): extract ControlFrameBuilder (arch-011 Option B PR-A) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/284
* fix(transport/tcp): dispose accepted client on post-accept setup failure (fixes #267) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/275
* fix(core): rollback per-index entry when ChannelRegistry id-uniqueness check loses race (fixes #268) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/280
* fix(transit/message): drain over-max payload before throw to preserve framing (fixes #278) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/287
* refactor(core): extract MuxHandshake protocol module (arch-011 Option B PR-B) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/290
* fix(core): route channel-level events through SafeEventRaiser (fixes #286) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/296
* test(core): add missing NotifyEventHandlerException stub to ChannelRegistryTests.NoopOwner by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/307
* fix(transport/websocket): aggregate per-session dispose failures in WebSocketMuxListener (fixes #295) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/301
* fix(transport/udp): discard non-HELLO packets in CreateServerOptions to prevent listener hijack (fixes #303) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/306
* fix(transit/duplexstream): aggregate inner-channel dispose failures (fixes #305) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/308
* refactor(core): split DispatchToChannel into init/dispatch helpers (arch-011 Option C) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/309
* refactor(mux): extract MuxKeepalive subsystem from StreamMultiplexer by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/310
* refactor(mux): extract MuxTransportWriter (writer + flusher loops) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/311
* refactor(mux): extract MuxConnectRetry (connection-attempt loop) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/312
* refactor(mux): extract ChannelBatchRegistrar (TryRegisterChannels guts) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/313
* fix(transport/ipc): dispose client/socket on post-connect and post-accept setup failure (fixes #304) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/314
* fix(transport/udp): filter stale ACKs by current send seq to prevent infinite resend loop (fixes #302) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/316
* fix(channel): make MarkOpen state transition atomic with SetClosed (fixes #163) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/317
* fix(transit/delta-message): defer peer resync to send lock to prevent lost-resync race (fixes #300) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/318
* fix(mux): exchange replay base in reconnect handshake (fixes #161) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/315
* fix(extensions): dispose channel when WaitForReadyAsync throws (fixes #250) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/320
* fix(transit/delta-message): stage SendBatchAsync mutations and only commit _lastSentState after successful send by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/319
* fix(transit/delta-message): clone JsonObject/JsonArray on receive (fixes #241) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/321
* fix(transit): aggregate dispose errors in MessageTransit and DeltaMessageTransit (fixes #292) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/322
* fix(keepalive): correlate Pong to Ping by 8-byte token (fixes #293) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/323
* fix(mux): drain local writes before tearing down on remote GoAway (fixes #165) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/324
* fix(mux): account ReadChannel close exactly once across FIN and Dispose paths (fixes #172) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/325
* fix(transport/websocket): reject unknown sessionId on HandleAsync (fixes #236) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/327
* fix(transport/quic): validate NetConduit preface byte on server (fixes #255) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/328
* fix(transit): make Ready event latching so subscribers added after channels are ready still observe it (fixes #266) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/329
* fix(mux): route channel to accept queue when pending TCS already cancelled (fixes #269) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/330
* fix(transit/delta-message): ReceiveAllAsync survives transient transport disconnects via _receiveEof by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/331
* fix(transit/delta-message): clone-and-swap _lastReceivedState on ApplyDelta failure (fixes #223) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/332
* fix(transit/duplexstream): dedupe Connected and Disconnected events by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/349
* fix(transport/udp): drain duplicate NC_HELLO retransmits and reject non-ACK datagrams in handshake by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/347
* fix(transport/ipc): use ephemeral TCP port + endpoint registry on Windows (fixes #233) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/345
* fix(transit): dispose transit when WaitForReadyAsync throws in *Async extensions (fixes #289) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/340
* fix(mux): make CoalescingSignal dispose race-safe (fixes #281) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/339
* fix(transit/message): drain in-flight Send/Receive before disposing semaphores (fixes #219) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/346
* fix(mux): scope ChannelRegistry.UnregisterChannel _idToIndex removal to (channelId, index) pair (fixes #228) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/344
* fix(transit/delta-message): drain over-max payload before throw, parse length as UInt32 by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/333
* fix(transport/websocket): auto-evict listener sessions on mux Disconnected (fixes #279) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/341
* fix(mux): reassign pre-handshake channel indices to handshake-decided parity (fixes #237) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/326
* fix(backpressure): non-throwing ACK send + retry on control-slab pressure by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/336
* fix(mux): route AcceptChannelAsync delivery through TCS to prevent double-delivery (fixes #179, #229) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/338
* fix(transport/websocket): reject zero-length Binary frames to stop CPU spin by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/350
* fix(mux): advertise per-peer max-recv-payload in handshake (fixes #180) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/335
* fix(transit/delta-message): serialize outgoing resync request under _sendLock (fixes #193) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/352
* fix(transport/websocket): always signal completion in CompletionStreamPair.DisposeAsync (fixes #353) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/359
* fix(transport/websocket): refuse reconnect on evicted session instead of silently spawning new mux (fixes #354) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/360
* fix(mux/keepalive): use TryWriteRawFrame for PING to avoid faulting the keepalive loop under control-slab pressure (fixes #355) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/361
* fix(mux): dispose freshly-connected transport on non-transport handshake failure (fixes #356) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/362
* fix(channel): make MarkConnected idempotent per connect transition (fixes #357) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/363
* fix(channel): clamp WriteAsync to MinSlabSize before first handshake (fixes #358) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/364
* Structural fixes: S1 control-slab backpressure, S7 fatal-connect classifier, S8 consumed-position ACK by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/413
* Structural fixes: transit event coalescing, framing, keepalive, resource ownership by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/414
* fix(mux): evict stale closed read channel at peer-reopen INIT (fixes #367) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/416
* fix(mux): dispose constructor-allocated handles on never-started mux (fixes #376) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/417
* fix(mux): complete _readyTcs on all shutdown paths (fixes #395, #401) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/418
* fix(mux): reset _disconnectedFired on every Connected edge (fixes #383, #400) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/419
* fix(channels): centralize teardown discipline — slabs returned + Disconnected fires (fixes #384, #385, #390, #391) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/421
* fix(mux): symmetric lifecycle event emission on local-GoAway and batch-registration (fixes #378, #399) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/422
* fix(mux): route MainLoopAsync handshake-retry through MuxConnectRetry (fixes #393) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/423
* fix(mux): two-phase shutdown teardown to prevent slab use-after-free (fixes #368) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/424
* fix(channels): validate SendTimeout at boundary (fixes #387) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/425
* fix(mux): wire INIT-ACK back-pressure retry mechanism into production path by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/438
* fix(mux): include pending-accept channels in lifecycle event sweeps by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/441
* fix(options): enforce Task.Delay int.MaxValue-ms cap on timing fields by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/444
* docs(heartbeat): align with actual MuxKeepalive behavior by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/449
* docs(graceful-shutdown,events): align with actual GoAwayAsync behavior by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/451
* docs(statistics,priority): distinguish control-typed frames from control-channel traffic by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/452
* docs(public surface): align Ack wire size, ReadChannel close path, and reconnect event order with implementation by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/453
* fix(StreamMultiplexer): guard HandleInitFrame with shutdown latch and atomic pending-accept cancel by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/454
* Bump Microsoft.NET.Test.Sdk from 18.5.1 to 18.6.0 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/461
* Bump NukeBuildHelpers from 9.0.27 to 9.0.28 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/462
* fix(StreamMultiplexer): honor documented teardown event-emission contracts by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/458
* fix(WriteChannel): bound WriteAsync admission by peer slab cap, not local slab by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/459
* fix(StreamMultiplexer): dispose freshly-connected transport when reconnect handshake is cancelled by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/460
* fix(StreamMultiplexer): atomically gate shutdown and Disconnected emission by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/465
* fix: validate UDP option bounds at configuration boundary by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/500
* fix: reject user frame types on control channel by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/501
* fix: reject malformed frame headers by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/502
* fix: validate established-session control subframes by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/503
* fix: validate inbound init frames by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/504
* fix: validate write-side inbound frames by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/505
* fix: validate transport helper options by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/507
* fix: validate read-channel frames by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/506
* fix: make write-channel slab operations progress by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/508
* fix: align public documentation contracts by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/510
* test: remove documentation contract unit tests by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/511
* fix: align framing protocol unknown-channel contract by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/509
* fix: recycle retired channel indices at allocator exhaustion by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/514
* fix: stabilize MemoryLeakTests for CI runners by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/516
* fix(test): revert in-loop memory sampler to forceFullCollection:false to prevent STW pauses by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/519
* fix(channels): prevent transport crash during rapid sequential open/close cycles by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/523
* fix(ReadChannel): prevent silent data loss when close races with data delivery by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/522
* fix(test): cap concurrent handler tasks in MemoryLeakTests at 50 by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/524
* fix(api): make TryRegisterChannels return false for invalid input, not throw by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/526
* Bump System.Security.Cryptography.Xml from 10.0.8 to 10.0.9 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/527
* fix(ReadChannel): CanRead returns true while buffered data remains after close by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/531
* fix(validation): reject Infinity for AutoReconnectBackoffMultiplier by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/532
* Bump NukeBuildHelpers from 9.0.28 to 9.0.29 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/537
* Bump NukeBuildHelpers from 9.0.29 to 9.0.30 by @dependabot[bot] in https://github.com/Kiryuumaru/NetConduit/pull/538
* fix: add lifecycle state guards in StreamMultiplexer (#534, #528) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/539
* fix: force ACK from AccountInboundFrame to prevent INIT-ACK backpressure deadlock (#533) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/540
* fix: check CancellationToken on ReadAsync fast path (#535) by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/541
* chore: bump NetConduitPackageVersion to 3.1.2 by @Kiryuumaru in https://github.com/Kiryuumaru/NetConduit/pull/542
**Full Changelog**: https://github.com/Kiryuumaru/NetConduit/compare/build.20260514145717.faa65b8...build.20260618070732.be52d13