Skip to main content
moqt.Server manages server-side operations for the MoQ protocol. It listens for incoming QUIC connections, dispatches them based on ALPN negotiation, and manages their lifecycle. The server uses ALPN (Application-Layer Protocol Negotiation) to determine the transport:
  • moq-lite-05 (moqt.NextProtoMOQ) — Native QUIC, dispatched to Server.Handler
  • h3 (moqt.NextProtoH3) — WebTransport via HTTP/3, dispatched to Server.WebTransportServer

Initialize a Server

There is no dedicated function (such as a constructor) for initializing a server. Users define the struct directly and assign values to its fields as needed.

Configuration

The following table describes the public fields of the Server struct:
quic-go/quic-go is used internally as the default QUIC implementation when relevant fields which is set for customization are not set or nil.quic-go/quic-go
okdaichi/webtransport-go — a fork of quic-go/webtransport-go carrying a custom upgrader — is used internally as the default WebTransport implementation when WebTransportServer is nil.okdaichi/webtransport-go

Handle Sessions

ALPN-Based Dispatch

ServeQUICConn detects the negotiated ALPN protocol and dispatches the connection accordingly:

Native QUIC Handler

For native QUIC connections (ALPN moq-lite-05), the Handler field receives a *moqt.Session directly:

WebTransport Handler

For WebTransport connections, use moqt.WebTransportHandler to handle HTTP upgrade and session setup:
WebTransportHandler implements http.Handler and can be used with any HTTP server. It upgrades the HTTP/3 connection to WebTransport, creates a session, and invokes the configured Handler.

WebSocket Handler

WebTransport does not work in every browser: on WebKit, which is every browser on iOS, a session stalls after about 7,600 streams or 16 MB (WebKit bug 319818). moqt.WebSocketHandler serves such clients over QMux on WebSocket. It is an http.Handler for an HTTP/1.1 server with TLS:
  • Set CheckOrigin. Browsers do not apply CORS to WebSocket, so this is the only origin check. Without it only same-origin requests are accepted.
  • Server ties the sessions to a moqt.Server: its Shutdown (GOAWAY) and Close reach them, its ConnContext derives their context from the upgrade request’s, and its QUICConfig configures them: stream limits, receive windows, keep-alive, and idle and handshake timeouts are set once for every transport.
  • The subprotocol is the version negotiation. A client offers moqt.NextProtoQMux (qmux-02.moq-lite-05); a request that does not is refused with 400.
  • Serve it on the TCP port of the same number as the QUIC listener. @qumo/moq dials wss: at the host and port of the https: URL it was given, so one URL then reaches the server over either transport.
  • A session behaves as a WebTransport one: the request URI is its path. Everything shares one TCP connection, so a lost segment delays every stream, and there are no unreliable datagrams.

Run the Server

Server.ListenAndServe starts the server listening for incoming connections.
For more advanced use cases:
  • ListenAndServeTLS(certFile, keyFile string): Starts the server with TLS certificates loaded from files.
  • ServeQUICListener(ln QUICListener): Serves on an existing QUIC listener.
  • ServeQUICConn(conn StreamConn): Handles a single QUIC connection directly.

Shutting Down a Server

Servers also support immediate and graceful shutdowns.

Immediate Shutdown

Server.Close method terminates all sessions and closes listeners forcefully.

Graceful Shutdown

Server.Shutdown method notifies all active sessions with NextSessionURI as the redirect and waits for them to close gracefully before forcing termination.
If the context expires before all sessions close, remaining connections are closed with a GoAwayTimeoutErrorCode.