Table of Contents

Interface ISubscriptionTransport

Namespace
Typhon.Engine
Assembly
Typhon.Engine.dll

A listener that turns connections into links: the built-in TCP transport, the ASP.NET Core adapter, or a test fake.

public interface ISubscriptionTransport

Remarks

A transport owns bytes on a wire; the engine owns the protocol and the session. That split is the whole point of this seam (design/Subscriptions/04-transport.md § 1). A transport accepts, negotiates TLS, frames messages, checks the origin and runs the receive loop. It never decodes a HELLO, never decides who is admitted, never tracks a session and never writes a byte the engine did not hand it.

What a transport must do. Call Accept(ISubscriptionLink, in LinkInfo) once per connection, with a link that is already usable; deliver each complete client-to-server message to OnMessage(ReadOnlySpan<byte>), one at a time and in order; deliver exactly one OnClosed(ushort, Exception) when the link ends, whoever ended it. Message boundaries are the transport's: WebSocket has them natively, TCP adds a length prefix inside its own link, and the engine never parses a byte stream.

What a transport must not do. It must not reorder messages, coalesce two into one, split one into two, hold a ReadOnlySpan<T> handed to OnMessage(ReadOnlySpan<byte>) past that call, or call into one connection from two threads at once. It must not interpret a message's contents: a version mismatch is settled by the subprotocol or the preamble it owns (design/Subscriptions/03-wire-protocol.md § 10), never by reading a message body.

This interface is not IDisposable on purpose: stopping a listener drains connections, which is asynchronous, and a synchronous Dispose would either block a shutdown path or lie about having finished.

Methods

Start(ISubscriptionAcceptor)

Begins listening, handing every connection to acceptor.

void Start(ISubscriptionAcceptor acceptor)

Parameters

acceptor ISubscriptionAcceptor

The engine's acceptor. It is the only engine surface a transport ever calls into to create a connection.

Remarks

Called once, from the runtime's start path. A transport that cannot bind throws here, where the failure reaches the host as a start failure rather than as a server that is running and unreachable.

StopAsync()

Stops listening and closes what is still connected.

ValueTask StopAsync()

Returns

ValueTask

A task that completes when no link remains and no receive loop is running.

Remarks

Every live link is closed with GoingAway and each connection is told through OnClosed(ushort, Exception), so a transport that returns without doing so leaves session rows the engine will never reclaim.