WebSocket Support
Real-time applications often rely on persistent WebSocket connections (ws:// and wss://) for live notifications, chat, streaming data, and collaborative tools. Diverge natively supports WebSocket routing across both header-based (x-diverge-env / diverge_env cookie) and subdomain preview environments.
1. Configuring WebSocket Routes (spec.serviceConfig.websocket)
Section titled “1. Configuring WebSocket Routes (spec.serviceConfig.websocket)”To prevent Gateway API proxies from prematurely closing long-lived WebSocket streams, enable spec.serviceConfig.websocket on your Environment Custom Resource:
apiVersion: divergedev.com/v1alpha1kind: Environmentmetadata: name: chat-pr-123spec: serviceConfig: serviceName: chat-service image: ghcr.io/acme/chat-service:pr-123 port: 8080 websocket: enabled: true # Optional: restrict WebSocket timeout rules to a specific path prefix path: /ws # Optional: Gateway API request timeout ("0s" disables the timeout for long-lived streams) timeout: 0sFields
Section titled “Fields”| Field | Default | Description |
|---|---|---|
enabled |
false |
Enables dedicated Gateway API HTTPRoute timeout rules for WebSocket streams |
path |
"" |
Optional path prefix (e.g. /ws). When set, generates a dedicated high-priority HTTPRoute rule for that path |
timeout |
"0s" |
Gateway API timeouts.request duration ("0s" disables request timeout for persistent connections) |
2. How It Works
Section titled “2. How It Works”When websocket.enabled: true is set:
- Gateway API
HTTPRouteRules:GatewayRoutergenerates anHTTPRouterule matching your preview header (x-diverge-env: pr-123) or preview subdomain (pr-123.preview.example.com) withtimeouts: { request: 0s }(or your configuredtimeout). - Browser Cookie & Magic Link Support (
?_diverge_env=): Because browsernew WebSocket(url)constructors cannot set custom HTTP headers directly, opening your preview via a Magic Link (?_diverge_env=pr-123) sets thediverge_env=pr-123session cookie, whichdiverge-proxytranslates intox-diverge-env: pr-123on the initial HTTPUpgrade: websockethandshake. Note that cookie-based WebSocket routing requiresproxy.enabled: truein your Helm values (it isfalseby default); withoutdiverge-proxy, thediverge_envcookie is not translated intox-diverge-envand the handshake will reach the baseline service unless you use subdomain routing (pr-123.preview.example.com). - Baseline Fallback: If a preview environment does not modify the WebSocket service, connections route transparently to the shared baseline deployment.
sequenceDiagram
actor Client as Browser / Client
participant Gateway as diverge-proxy / Envoy Gateway
participant PreviewPod as Preview Pod (pr-123)
Client->>Gateway: GET /ws (Upgrade: websocket, Cookie: diverge_env=pr-123)
Gateway->>PreviewPod: GET /ws (Upgrade: websocket, x-diverge-env: pr-123)
PreviewPod-->>Gateway: HTTP 101 Switching Protocols
Gateway-->>Client: HTTP 101 Switching Protocols
Note over Client, PreviewPod: Persistent Bidirectional WebSocket Stream (timeout: 0s)
