Socket Connection
On this page
- Source Mapping#
- Architectural Receive & Send Pipeline#
- Key Technical Responsibilities#
- 1. Multi-Mode Transport Framing (TransportFraming)#
- 2. Layer 1 Per-Connection Throttle & OverflowPolicy (Connection.OnFrameReceived)#
- 3. Automatic Fragmentation & Reassembly (FragmentAssembler)#
- 4. Pre-Read Buffer Injection (InjectPreReadBytes)#
- Related APIs#
Namespace: Nalix.Network.Internal.Transport
Assembly: Nalix.Network
SocketConnection (internal sealed partial class SocketConnection : IDisposable, IPoolable) is the internal framed TCP transport engine backing Connection.TCP (SocketTcpTransport). It uses pooled PooledSocketReceiveContext (SocketAsyncEventArgs) instances, BufferLease byte-array pools, and multi-mode framing to sustain 10,000+ concurrent connections with zero per-packet heap allocations.
Source Mapping
src/Nalix.Network/Internal/Transport/SocketConnection.cssrc/Nalix.Network/Internal/Transport/SocketConnection.Framing.cssrc/Nalix.Network/Internal/Transport/SocketConnection.Receive.VarInt.cssrc/Nalix.Network/Internal/Transport/SocketConnection.Send.cssrc/Nalix.Network/Internal/Transport/SocketConnection.Send.VarInt.cssrc/Nalix.Network/Internal/Transport/SocketTcpTransport.cssrc/Nalix.Network/Options/NetworkCallbackOptions.cssrc/Nalix.Network/Options/VarIntFramingOptions.cs
Architectural Receive & Send Pipeline
flowchart TD
subgraph RxPipeline["Inbound Receive Loop (PooledSocketReceiveContext)"]
Sock["TCP Socket"] --> Framing{"TransportFraming Mode?"}
Framing -->|UInt16LengthPrefixed| Len16["Read 2-Byte LE Length Header"]
Framing -->|VarIntLengthPrefixed| VarInt["Read 1-to-5-Byte VarInt Length (MaxPayloadSize = 128 KB)"]
Framing -->|None| Raw["Deliver Raw Chunk"]
Len16 --> Frag
VarInt --> Frag
Raw --> Frag
Frag{"FragmentHeader Present?"}
Frag -->|Yes| Assem["FragmentAssembler (<= MaxPerConnectionOpenFragmentStreams)"]
Frag -->|No| Owner["Connection.OnFrameReceived(lease)"]
Assem -->|Reassembled| Owner
Owner --> Inline{"AsyncCallback.CanRunInline(MessageProcessing)?"}
Inline -->|Yes| RunInline["AsyncCallback.InvokeInline (Zero-Queue Fast Path)"]
Inline -->|No| Gate{"PendingProcessCallbacks <= MaxPerConnectionPendingPackets?"}
Gate -->|"No (Overflow)"| Overflow{"OverflowPolicy?"}
Overflow -->|DropPacket| Drop["IncrementPacketsDropped + Drop Frame"]
Overflow -->|Disconnect| Disc["Disconnect Connection"]
Gate -->|Yes| Dispatch["AsyncCallback.Invoke(CallbackLane.Process)"]
endKey Technical Responsibilities
1. Multi-Mode Transport Framing (TransportFraming)
Configured via connection.TCP.UseFraming(this.Framing) during Protocol.OnAccept (locked once BeginReceive starts):
| Mode | Wire Prefix | Max Frame Size | Source File |
|---|---|---|---|
TransportFraming.UInt16LengthPrefixed (default) | 2-byte little-endian ushort total frame length | 65,535 bytes (larger payloads use FragmentStream) | SocketConnection.Framing.cs |
TransportFraming.VarIntLengthPrefixed | 1-to-5-byte LEB128 VarInt payload length | VarIntFramingOptions.MaxPayloadSize (131,072 bytes / 128 KB) | SocketConnection.Receive.VarInt.cs, SocketConnection.Send.VarInt.cs |
TransportFraming.None | Unframed stream chunks | Bounded by receive buffer | SocketConnection.cs |
2. Layer 1 Per-Connection Throttle & OverflowPolicy (Connection.OnFrameReceived)
When SocketConnection.PROCESS_FRAME_FROM_BUFFER completes a frame (or reassembles all chunks via FragmentAssembler), it calls _connectionOwner?.OnFrameReceived(lease) on the owning Connection:
- Inline Fast Path (
AsyncCallback.CanRunInline): IfMessageProcessinghas a single subscriber bound to anIFrameProcessorwithSupportsInlineProcessing == true,Connection.OnFrameReceivedexecutesAsyncCallback.InvokeInline(...)synchronously on the receive completion thread without queuing. - Per-Connection Throttle: Otherwise,
Connection.OnFrameReceivedincrementsbacking.PendingProcessCallbacksand checksNetworkCallbackOptions.MaxPerConnectionPendingPackets(default16):- When
OverflowPolicy == NetworkOverflowPolicy.DropPacket(default): incrementsPacketsDropped, rolls backPendingProcessCallbacks, disposes the lease, and discards the frame before it touches theThreadPool. - When
OverflowPolicy == NetworkOverflowPolicy.Disconnect: rolls back the counter, disposes the lease, and immediately callsDisconnect()on the flooding peer. - When within budget: acquires a pooled
ConnectionEventArgsand dispatches viaAsyncCallback.Invoke(..., CallbackLane.Process, releasePendingPacketOnCompletion: true).
- When
3. Automatic Fragmentation & Reassembly (FragmentAssembler)
- Outbound: Payloads exceeding
FragmentOptions.MaxChunkSizeare split across multiple frames prefixed with aFragmentHeader. - Inbound:
SocketConnectionreassembles fragmented streams viaFragmentAssembler, enforcingNetworkCallbackOptions.MaxPerConnectionOpenFragmentStreams(default4) and evicting expired partial streams on each receive cycle.
4. Pre-Read Buffer Injection (InjectPreReadBytes)
When TcpListenerBase or WebSocketListenerBase reads initial bytes during PROXY Protocol v1/v2 or HTTP Upgrade parsing, any trailing payload bytes already read from the socket are injected into SocketConnection via InjectPreReadBytes(ReadOnlySpan<byte>) so they are processed before the next OS socket read.