Documentation
¶
Overview ¶
Package websocket adapts realtime.Coordinator to an HTTP WebSocket upgrade, wrapping github.com/coder/websocket. No coder/websocket type appears in this package's own public API: the third-party dependency stays behind a translated contract.
Index ¶
Constants ¶
const DefaultMaxMessageSize = 32 * 1024
DefaultMaxMessageSize bounds one inbound WebSocket message. It matches coder/websocket's own default, so View's behavior is explicit rather than an unstated inherited default.
Variables ¶
This section is empty.
Functions ¶
func View ¶
func View(coordinator realtime.Coordinator, authenticate Authenticate, roomID func(*tango.Context) (string, error), opts ...ViewOption) tango.View
View upgrades an authenticated request to a WebSocket connection and runs it against coordinator until the connection ends. Mount it as an ordinary route, e.g. tango.Path("GET", "/rooms/{id}/ws", View(hub, authenticate, roomIDFromPath)).
authenticate runs before the upgrade is attempted: a failure responds with a plain JSON 401 and never touches the WebSocket handshake. roomID is resolved the same way, before upgrading, so a bad room reference fails as an ordinary HTTP 400 rather than an upgraded connection that immediately closes.
Join is called, and must return successfully, before View starts reading any client message — a message sent immediately after the socket opens must never race ahead of the room loop's own membership-apply. This is exactly why realtime.Hub.Join is synchronous.
By default, the upgrade is rejected with 403 for any request whose Origin header doesn't match this route's own Host — coder/websocket's own same-origin protection. Pass WithOriginPatterns (or, if there's truly no origin to check, WithInsecureSkipVerify) to allow a connecting page served from a different origin, such as a frontend dev server on another port or a separate production domain.
Types ¶
type Authenticate ¶
Authenticate resolves the requesting Principal from a plain HTTP request, before any WebSocket upgrade is attempted. It may use auth/jwt (see jwt.Service.Verify, called directly — not via jwt.Service.Middleware, since that targets ordinary HTTP routes), a cookie session, or anything else; this package never imports auth, auth/jwt, or accounts.
type ViewOption ¶ added in v0.1.0
type ViewOption func(*viewConfig)
ViewOption configures View.
func WithInsecureSkipVerify ¶ added in v0.1.0
func WithInsecureSkipVerify() ViewOption
WithInsecureSkipVerify disables Accept's origin verification entirely — every origin is accepted. Prefer WithOriginPatterns; this exists for the same reason coder/websocket exposes InsecureSkipVerify directly: some deployments (e.g. serving to native clients, or behind infrastructure that already enforces origin) have no real origin to check.
func WithOriginPatterns ¶ added in v0.1.0
func WithOriginPatterns(patterns ...string) ViewOption
WithOriginPatterns configures the host patterns coder/websocket's Accept treats as authorized origins for the upgrade's Origin header check — required whenever the connecting page's origin differs from this route's own Host (a separate frontend dev server on another port, a different subdomain in production, etc.). Without this, Accept applies its default same-origin check and responds 403 to any cross-origin handshake, regardless of whether authenticate would have accepted the request.
Patterns follow ws.AcceptOptions.OriginPatterns's own syntax (a bare host, optionally with a scheme, "*" wildcards allowed within a segment). Do not pass "*" alone as a pattern — that authorizes any origin unconditionally; use WithInsecureSkipVerify instead so that intent is explicit at the call site rather than hidden behind a pattern that reads like a real host.