Skip to content

C# — Transport

Transport types are in the Nnrp.Transport namespace. The current stable implementation provides TCP framed transport; QUIC support is planned for Preview3.

Import

csharp
using Nnrp.Transport;
using Nnrp.Core;

Transport Interfaces

INnrpMessageTransport

Unified transport interface for both client and server.

csharp
public interface INnrpMessageTransport : IAsyncDisposable
{
    TransportId TransportId { get; }
    bool IsConnected { get; }
    Task<NnrpFramedMessage> ReceiveAsync(CancellationToken ct = default);
    Task SendAsync(NnrpFramedMessage message, CancellationToken ct = default);
    Task CloseAsync(CancellationToken ct = default);
}

INnrpMessageSender

Write-only view of a transport (for sending only).

csharp
public interface INnrpMessageSender
{
    Task SendAsync(NnrpFramedMessage message, CancellationToken ct = default);
}

INnrpMessageReceiver

Read-only view of a transport (for receiving only).

csharp
public interface INnrpMessageReceiver
{
    Task<NnrpFramedMessage> ReceiveAsync(CancellationToken ct = default);
}

TCP Transport

NnrpTcpMessageTransport implements INnrpMessageTransport over a System.Net.Sockets.TcpClient or TcpListener. Uses length-prefixed framing (4-byte big-endian frame length prefix).

Bind Server

csharp
public static Task<NnrpTcpMessageTransport> BindServerAsync(
    string host,
    int port,
    NnrpTcpServerOptions? options = null,
    CancellationToken ct = default);

Connect Client

csharp
public static Task<NnrpTcpMessageTransport> ConnectClientAsync(
    string host,
    int port,
    NnrpTcpClientOptions? options = null,
    CancellationToken ct = default);

TCP Configuration

NnrpTcpClientOptions

PropertyTypeDefaultDescription
ConnectTimeoutMsint10000Connection timeout (ms)
IdleTimeoutMsint30000Idle timeout (ms)
MaxFrameBytesint33554432Max frame size (32 MB)
SendBufferSizeint65536TCP send buffer size
ReceiveBufferSizeint65536TCP receive buffer size

NnrpTcpServerOptions

PropertyTypeDefaultDescription
IdleTimeoutMsint30000Idle timeout (ms)
MaxFrameBytesint33554432Max frame size (32 MB)
SendBufferSizeint65536TCP send buffer size
ReceiveBufferSizeint65536TCP receive buffer size
Backlogint128Connection backlog

QUIC Transport (Preview3)

Note: QUIC transport support is planned for Preview3. The interface will match INnrpMessageTransport exactly; existing code will require only a transport factory change.


Custom Transport

Implement INnrpMessageTransport to plug in any custom transport layer:

csharp
public class MyCustomTransport : INnrpMessageTransport
{
    public TransportId TransportId => TransportId.Unspecified;
    public bool IsConnected { get; private set; }

    public async Task<NnrpFramedMessage> ReceiveAsync(CancellationToken ct)
    {
        // Your receive logic here
    }

    public async Task SendAsync(NnrpFramedMessage message, CancellationToken ct)
    {
        // Your send logic here
    }

    public Task CloseAsync(CancellationToken ct)
    {
        IsConnected = false;
        return Task.CompletedTask;
    }

    public ValueTask DisposeAsync()
    {
        // Cleanup
        return ValueTask.CompletedTask;
    }
}

Typical Use Cases

QUIC Client

csharp
var quicConfig = new NnrpQuicClientConfiguration
{
    CertificateAuthority = X509Certificate2.CreateFromPemFile("ca.pem"),
    IdleTimeout          = TimeSpan.FromSeconds(30),
};
var transport = new NnrpQuicTransport(quicConfig);
await using var client = await NnrpClient.ConnectAsync(host, port, profile,
                                                         transport: transport);

TCP Fallback

csharp
var tcpConfig = new NnrpTcpClientConfiguration
{
    ConnectTimeout = TimeSpan.FromSeconds(5),
    IdleTimeout    = TimeSpan.FromSeconds(60),
};
var transport = new NnrpTcpTransport(tcpConfig);

Common Pitfalls

WARNING

  1. QUIC requires the correct ALPN. Use NnrpQuicClientConfiguration.DefaultAlpn; do not hardcode the string.

  2. SkipCertificateValidation = true is for local dev only. CI/staging must use a CA certificate.

  3. TCP does not support Datagram operations (e.g., transport probes). These throw NnrpUnsupportedOperationException.

  4. await using var transportNnrpQuicTransport / NnrpTcpTransport implement IAsyncDisposable. Forgetting to dispose leaks the underlying socket.

NNRP Documentation