Transports & Hosting
Two doors into the same sessions: TCP in the engine, WebSocket through ASP.NET Core.
Status: ✅ Implemented · Visibility: Public · Level: 🔵 Core · Category: Subscriptions
🎯 What it solves
Browsers need WebSocket, TLS and origin checks; native clients, bots and server links want a plain socket with no HTTP stack. The engine must not depend on ASP.NET Core, and no transport may block or be called by the tick.
⚙️ How it works (in brief)
- Links are thin. A transport accepts connections and moves bytes; handshake, admission, caps and close codes are the engine's, behind
ISubscriptionAcceptor. Send pumps owned by the engine walk only the sessions that produced a frame, hand it to the session's link (at most one send in flight), and chain the next; the tick never awaits a send. - TCP (
TcpSubscriptionTransport, in the engine): aTYP2preamble,u32length framing, optional TLS (ServerCertificate),TCP_NOTSENT_LOWATwhere the OS has it. Binds loopback unlessAddressis set. - WebSocket (
Typhon.Subscriptions.AspNetCore): thetyphon.2subprotocol, an allowed-origin list (empty refuses to start;AllowAnyOrigin()is explicit), explicit keep-alive, a bounded receive loop. Nopermessage-deflate: quantized payloads barely compress and per-connection zlib defeats encode-once. - Catalog endpoint:
MapTyphonCatalogserves exactly the bytesWELCOMEcarries, for code generation and tools.
💻 Usage
// TCP — after runtime.Start():
var tcp = new TcpSubscriptionTransport(new TcpSubscriptionOptions { Port = 9100 });
runtime.StartSubscriptionTransport(tcp);
// … before runtime.Shutdown():
await tcp.StopAsync();
// WebSocket — ASP.NET Core:
builder.Services.AddSingleton(runtime);
builder.Services.AddTyphonSubscriptions(o => o.AllowOrigin("https://play.example.com"));
app.UseWebSockets();
app.MapTyphonSubscriptions("/ws");
app.MapTyphonCatalog("/typhon/catalog.json");
| Option | Default | Effect |
|---|---|---|
TcpSubscriptionOptions.Address / Port |
loopback / required | Where TCP listens (Port = 0: ephemeral, read BoundEndPoint) |
TcpSubscriptionOptions.ServerCertificate |
none | TLS on TCP |
TyphonSubscriptionsOptions.AllowedOrigins |
empty (refuses) | Browser origins allowed |
TyphonSubscriptionsOptions.KeepAliveInterval / KeepAliveTimeout |
15 s / 15 s | WebSocket ping frames (the framework's defaults are 2 min / infinite) |
⚠️ Guarantees & limits
Typhon.Enginereferences no ASP.NET Core assembly (AC-19).- Neither transport authenticates: the
HELLOtoken reaches the admission hook unexamined. - The WebSocket adapter does not cap kernel send buffering (
TCP_NOTSENT_LOWATon the upgraded socket), so the acknowledgement-based lag skip is what bounds a slow browser. WebTransport is not built. - A transport can be written against
ISubscriptionTransport/ISubscriptionLinkand started withStartSubscriptionTransport.
🧪 Tests
- TcpTransportTests — framing, preamble, random framing never stops the listener
- LiveClientTests — a real client over TCP end to end