WebSocket & realtime
Changes reach open browsers over a WebSocket. Without it the app still works, but other people's changes require manual refreshing.
The endpoint
The socket runs on the same host and port as the app, at /trpc. The server
prints it at startup:
WS: ws://0.0.0.0:3000/trpc
Reverse proxies
nginx
nginx only forwards WebSocket upgrades when you tell it to:
location / {
proxy_pass http://norish:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 60s;
}
The server pings every 20 seconds, so keep proxy_read_timeout above 25 seconds.
A lower value closes the socket between pings and the app keeps reconnecting.
Caddy
reverse_proxy passes WebSocket upgrades through as is:
norish.example.com {
reverse_proxy norish:3000
}
Traefik
Traefik forwards upgrades on any HTTP router. If you set
respondingTimeouts.readTimeout on the entrypoint, keep it above 25 seconds.
Origin check
WebSocket connections from untrusted origins receive 403 Forbidden. Trusted
origins are:
- the origin of
AUTH_URL - every entry in
TRUSTED_ORIGINS - the host the request arrived on, over
httporhttps
If your proxy rewrites or strips the Host header and people use an address
other than AUTH_URL, add that address to
TRUSTED_ORIGINS:
AUTH_URL=https://norish.example.com
TRUSTED_ORIGINS=https://norish.example.com,https://recipes.example.com