Skip to content

C# Server API

The production server path owns a Rust-backed listener and accepted runtime sessions:

  1. Listen on an application-facing NNRP endpoint.
  2. Accept a session through any listener in the owned provider listener set.
  3. Receive an NnrpServerOperation.
  4. Send progress, partial, terminal, drop, and trace output.
  5. Close the accepted session and listener.

NnrpServer.ListenAsync

csharp
public static ValueTask<NnrpServer> ListenAsync(
    NnrpServerOptions options,
    CancellationToken cancellationToken = default);

The method resolves every registered provider allowed by policy, atomically binds their listener set, and transfers each listener to its native server runtime. It never creates a managed loopback server.

NnrpServerOptions

PropertyTypeRequiredDescription
EndpointNnrpEndpointYesnnrp:// or nnrps:// application endpoint.
ProviderRoutesIReadOnlyDictionary<TransportId, NnrpServerProviderRoute>?NoPer-carrier bind locator and server-security configuration.
TransportPolicyTransportPolicyNoDefaults to Auto.
SessionDefaultsNnrpServerSessionOptions?NoDefaults applied to every accepted session.

TCP and QUIC may derive their bind host and port from Endpoint. IPC and WebSocket require matching provider-local locators. Auto/Prefer requires every allowed installed provider route to resolve and opens the complete listener set atomically; Force restricts the set without fallback.

NnrpServerSessionOptions

PropertyTypeDefaultDescription
SupportedProfilesIReadOnlyList<ushort>Standard token profileSupported profile ids.
SupportedCacheObjectsIReadOnlyList<CacheObjectKind>EmptySupported cache object kinds.
MaxCacheObjectsulong0Cache object-count limit; zero means no advertised limit.
MaxCacheObjectBytesuint0Per-object byte limit; zero means no advertised limit.
SchemaRegistryNnrpSchemaRegistryStandardApplication-facing schema registry.
ResumeTokenBytesuint24Runtime-issued recovery-token size.
MaxInFlightOperationsushort4Negotiated in-flight operation limit.
GrantedOperationCreditushort2Initial operation credit.
LeaseTtlMillisecondsuint30000Cache lease lifetime.
ResumeWindowMillisecondsuint120000Recovery-ticket validity window.
ApplicationPolicyINnrpServerSessionPolicyAccept valid sessionsAsynchronous admission policy.
csharp
public interface INnrpServerSessionPolicy
{
    ValueTask<NnrpServerSessionPolicyDecision> EvaluateAsync(SessionOpenMetadata open);
}

NnrpServerSessionPolicyDecision contains Accepted, SessionErrorCode, and optional Diagnostic. The policy runs exactly once for each SESSION_OPEN. It executes away from the native callback thread, and the host reports its decision through the Rust ABI completion boundary. Rejections must use a valid non-zero session error code; exceptions become deterministic policy failures.

NnrpServer.AcceptAsync

csharp
public ValueTask<NnrpServerSession> AcceptAsync(
    NnrpServerAcceptOptions? options = null,
    CancellationToken cancellationToken = default);

NnrpServerAcceptOptions contains only TimeoutMilliseconds, which defaults to 0. Native accept tickets, session handles, and generations are internal. The accepted session owns its native session handle and preserves the selected provider identity.

NnrpServerSession.ActiveTransportId is the TransportId of the listener that accepted the carrier. It matches the negotiated active transport and is not inferred from listener preference order.

NnrpServer.BoundProviderEndpoints is an IReadOnlyDictionary<TransportId, NnrpProviderEndpoint> containing the actual endpoint of every opened listener. A terminal provider-listener failure fails the logical server and closes the remaining listener set; a rejected peer handshake affects only that accepted carrier.

NnrpServerSession.ReceiveSubmitAsync

csharp
public ValueTask<NnrpServerOperation> ReceiveSubmitAsync(
    CancellationToken cancellationToken = default);

The returned operation exposes owned application values, not FFI buffers:

PropertyTypeDescription
OperationIdulongNon-zero wire operation identity.
FrameIduintWire frame identity.
MetadataFrameSubmitMetadataDecoded submit metadata.
BodyReadOnlyMemory<byte>Owned submit body.
TraceIdulongEnd-to-end trace identity.

Operation Results

MethodMessageDescription
SendResultAsync(ResultPushMetadata, ReadOnlyMemory<byte>, CancellationToken)ResultPushSends the terminal success/error payload for this operation.
SendResultDropAsync(ResultDropReasonMetadata, ReadOnlyMemory<byte>, CancellationToken)ResultDropReasonSends typed terminal drop evidence.
SendProgressAsync(ProgressMetadata, ReadOnlyMemory<byte>, CancellationToken)ProgressSends non-terminal progress for this operation.
SendPartialResultAsync(PartialResultMetadata, ReadOnlyMemory<byte>, CancellationToken)PartialResultSends an incremental result for this operation.

An operation accepts exactly one terminal send. Sending after terminal state or after session close throws NnrpNativeInvalidStateException. Every method validates operation identity, and the session does not expose parallel operation-reply methods.

Receiving a terminal lifecycle event does not invalidate the operation before its terminal reply succeeds. It remains reply-capable until that reply or session shutdown, independently of later event reads.

Server Runtime Methods

The session sends typed Preview4 frames through one coarse native call per method.

MethodMessageTail
SendBackpressureAsync(PressureMetadata, CancellationToken)BackpressureNone
SendCreditUpdateAsync(PressureMetadata, CancellationToken)CreditUpdateNone
NegotiateCapabilitiesAsync(CapabilityMetadata, ReadOnlyMemory<byte>, CancellationToken)CapabilityNegotiationCapability entries
DegradeProfileAsync(CapabilityMetadata, ReadOnlyMemory<byte>, CancellationToken)DegradeProfileCapability entries
SendTraceContextAsync(TraceContextMetadata, ReadOnlyMemory<byte>, ulong?, CancellationToken)TraceContextTrace attributes; null operation is session scope
SendRecoverableErrorAsync(RecoverableErrorMetadata, ReadOnlyMemory<byte>, CancellationToken)ErrorRecoverableDiagnostic bytes
SendRetryAfterAsync(RetryAfterMetadata, ReadOnlyMemory<byte>, CancellationToken)RetryAfterDiagnostic bytes
SendControlAsync(MessageType, IRuntimeControlMetadata, ReadOnlyMemory<byte>, CancellationToken)Any non-operation server-sendable runtime controlDeclared tail

Server Object And Cache Methods

MethodMessage
DeclareObjectAsyncObjectDeclare
ReferenceObjectAsyncObjectRef
ReleaseObjectAsyncObjectRelease
PatchObjectAsyncObjectPatch
SendObjectDeltaAsyncObjectDelta
ReferenceCacheAsyncCacheReference
ReportCacheMissAsyncCacheMiss
InvalidateCacheAsyncCacheInvalidate

The method parameters and tail rules are the same typed metadata contracts documented for the client object and cache methods.

Incoming Server Events

NextEventAsync(CancellationToken) returns ValueTask<NnrpServerEvent> and preserves order for one session. NnrpServerEvent.Kind is Submit, Runtime, or Lifecycle; its Match<TResult>(...) method requires all three callbacks and exposes exactly one NnrpServerOperation, non-submit NnrpRuntimeEvent, or headerless NnrpOperationLifecycleEvent. No application-facing method accepts a raw control code.

Shutdown

NnrpServerOperation, NnrpServerSession, and NnrpServer enforce ownership in that order. Sessions and listeners implement IAsyncDisposable; listener shutdown cancels pending accepts, closes accepted sessions, and releases the provider runtime.

Managed INnrpMessageTransport server helpers remain diagnostic/custom-carrier surfaces and are not production fallbacks.

NNRP Documentation