# WebSocket - [Background](#background) - [Design](#design) - [Health Check](#health-check) - [Health Check](#health-check-1) - [Example](#example) - [References](#references) ## Background - Reverse proxy is one of most popular features of Easegress and it's suitable for many production and development scenarios. - In reversed proxy use cases, `WebSocket` is a widely used protocol for a full-duplex communication solution between client and server. WebSocket relies on TCP.[1] - Many reverse proxy support `WebSocket`,e.g., NGINX[2], Traefik, and so on. ## Design - The `WebSocketProxy` is a filter of Easegress, and can be put into a pipeline. - Easegress uses `nhooyr.io/websocket` to implement `WebSocketProxy` filter. 1. Spec * Pipeline with a `WebSocketProxy` filter: ```yaml name: websocket-pipeline kind: Pipeline flow: - filter: wsproxy filters: - kind: WebSocketProxy name: wsproxy defaultOrigin: http://127.0.0.1/hello pools: - servers: - url: ws://127.0.0.1:12345 # keepHost: true, the `Host` will be the same as the original request # If the backend is a load balancer, it would prove to be highly beneficial keepHost: true - url: ws://127.0.0.1:9095 - url: ws://127.0.0.1:9096 - url: ws://127.0.0.1:9097 loadBalance: policy: roundRobin # the max number of bytes to read for a single message in # client/server connection. # default is 32769, set -1 to disable limit. clientMaxMsgSize: 32769 serverMaxMsgSize: 32769 ``` * HTTPServer to route traffic to the websocket-pipeline: ```yaml name: demo-server kind: HTTPServer port: 8080 rules: - paths: - path: /ws clientMaxBodySize: -1 # REQUIRED! backend: websocket-pipeline ``` Note: `clientMaxBodySize` must be `-1`. 2. Request sequence ```none +--------------+ +--------------+ +--------------+ | | 1 | | 2 | | | client +--------------->| Easegress +--------------->| websocket | | |<---------------+ |<---------------+ backend | | | 4 | | 3 | | +--------------+ +--------------+ +--------------+ ``` 3. Headers We copy all headers from your HTTP request to websocket backend, except ones used by websocket package to build connection. Based on [3], we also add `X-Forwarded-For`, `X-Forwarded-Host`, `X-Forwarded-Proto` to http headers that send to websocket backend. > note: websocket use `Upgrade`, `Connection`, `Sec-Websocket-Key`, `Sec-Websocket-Version`, `Sec-Websocket-Extensions` and `Sec-Websocket-Protocol` in http headers to set connection. ## Health Check ### Health Check Perform a health check on the servers in the pool. If a server fails the check, it will be marked as unhealthy, and requests will be rerouted to other healthy servers until it regains health. Health check for websocket proxy contains both http way or websocket way. The HTTP check involves a request-response evaluation similar to a Proxy filter. In the WebSocket method, a successful connection yields a 101 status code. Additional headers can be set and evaluated in both methods. If you send both two ways of health check, then a server passes both HTTP and WebSocket health checks, it will be considered healthy. More details in [WebSocketProxy](../07.Reference/7.02.Filters.md#health-check-1). ```yaml kind: WebSocketProxy name: proxy-example-1 pools: - servers: - url: ws://127.0.0.1:9095 - url: ws://127.0.0.1:9096 - url: ws://127.0.0.1:9097 healthCheck: # interval between health checks (default: 60s) interval: 60s # timeout for health check response (default: 3s) timeout: 3s # fail threshold to mark server as unhealthy (default: 1) fails: 1 # success threshold to mark server as healthy (default: 1) pass: 1 ws: # health check request port (defaults to server's port, e.g., 9095) port: 10080 # uri for health check uri: /health/ws # http request headers for health check headers: X-Health-Check: easegress # response validation criteria (default: 101 Switching Protocols) match: # acceptable status code ranges statusCodes: - [101, 101] # 101 # response header validation # name is header key. # value is header value, can be empty. # type is type of value, can be "exact" or "regexp". headers: - name: X-Status value: healthy type: exact http: uri: /health ``` ## Example 1. Send request ```bash curl --include \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Host: 127.0.0.1:10020" \ --header "Sec-WebSocket-Key: your-key-here" \ --header "Sec-WebSocket-Version: 13" \ http://127.0.0.1:8080/ ``` 2. This request to Easegress will be forwarded to websocket backend `ws://127.0.0.1:12345`. ## References 1. 2. 3.