NetConduit 3.1.2
dotnet add package NetConduit --version 3.1.2
NuGet\Install-Package NetConduit -Version 3.1.2
<PackageReference Include="NetConduit" Version="3.1.2" />
<PackageVersion Include="NetConduit" Version="3.1.2" />
<PackageReference Include="NetConduit" />
paket add NetConduit --version 3.1.2
#r "nuget: NetConduit, 3.1.2"
#:package NetConduit@3.1.2
#addin nuget:?package=NetConduit&version=3.1.2
#tool nuget:?package=NetConduit&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
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (9)
Showing the top 5 NuGet packages that depend on NetConduit:
| Package | Downloads |
|---|---|
|
NetConduit.Transport.WebSocket
WebSocket transport helper for NetConduit stream multiplexer. Provides easy WebSocket client/server connection handling with automatic multiplexer setup. |
|
|
NetConduit.Transport.Ipc
Local IPC transport helper for NetConduit (named pipes on Windows, Unix domain sockets elsewhere). |
|
|
NetConduit.Transit.DeltaMessage
Delta message transit for NetConduit. Synchronizes state by sending only changed fields after an initial full sync, minimizing bandwidth. |
|
|
NetConduit.Transit.DuplexStream
Duplex stream transit for NetConduit. Wraps a write/read channel pair as a bidirectional System.IO.Stream. |
|
|
NetConduit.Transport.Tcp
TCP transport helper for NetConduit stream multiplexer. Provides easy TCP client/server connection handling with automatic multiplexer setup. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.1.2 | 214 | 6/18/2026 |
| 3.1.1 | 42 | 5/22/2026 |
| 3.1.0 | 3,044 | 5/20/2026 |
| 3.0.1 | 1,834 | 5/14/2026 |
| 2.3.3 | 545 | 5/8/2026 |
| 2.3.2 | 125 | 5/7/2026 |
| 2.3.1 | 32 | 5/6/2026 |
| 2.2.3 | 159 | 5/6/2026 |
| 2.2.1 | 97 | 5/5/2026 |
| 2.1.4 | 55 | 4/27/2026 |
| 2.1.3 | 44 | 4/25/2026 |
| 2.1.2 | 50 | 4/22/2026 |
| 2.1.1 | 564 | 4/22/2026 |
| 2.1.0 | 39 | 4/22/2026 |
| 2.0.3 | 45 | 4/15/2026 |
| 2.0.2 | 453 | 4/14/2026 |
| 2.0.0 | 906 | 3/11/2026 |
| 1.2.6 | 26,227 | 12/6/2025 |
| 1.2.4 | 208 | 12/6/2025 |
| 1.2.3 | 178 | 12/5/2025 |
## New Version
* Bump `net_conduit` from `3.1.1` to `3.1.2`. See [changelog](https://github.com/Kiryuumaru/NetConduit/compare/net_conduit/3.1.1...net_conduit/3.1.2)
## What's Changed
* 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
**Full Changelog**: https://github.com/Kiryuumaru/NetConduit/compare/build.20260522181957.2c9c9bd...build.20260618115201.b6f80b3