Skip to content

Commit

Permalink
add doc for websocket (#385)
Browse files Browse the repository at this point in the history
* add doc for websocket

* update websocket doc, thanks a lot for Samu advice

* add example for websocket.md

* fix typo
  • Loading branch information
suchen-sci committed Nov 29, 2021
1 parent 6394a0f commit 0b9e2d1
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ The following examples show how to use Easegress for different scenarios.
- [Security](./doc/cookbook/security.md) - How to do authentication by Header, JWT, HMAC, OAuth2, etc.
- [Service Proxy](./doc/cookbook/service_proxy.md) - Supporting the Microservice registries - Zookeeper, Eureka, Consul, Nacos, etc.
- [WebAssembly](./doc/cookbook/wasm.md) - Using AssemblyScript to extend the Easegress
- [WebSocket](./doc/cookbook/websocket.md) - WebSocket proxy for Easegress
- [Workflow](./doc/cookbook/workflow.md) - An Example to make a workflow for a number of APIs.

For full list, see [Cookbook](./doc/cookbook/README.md).
Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
- [安全](./doc/cookbook/security.md) - 如何通过标头、JWT、HMAC、OAuth2 等进行认证。
- [服务网关](./doc/cookbook/service_proxy.md) - 使用 Zookeeper、Eureka、Consul、Nacos 等进行服务注册。
- [WebAssembly](./doc/cookbook/wasm.md) - 使用 AssemblyScript 来扩展 Easegress。
- [WebSocket](./doc/cookbook/websocket.md) - Easegress 的 WebSocket 代理。
- [工作流](./doc/cookbook/workflow.md) - 将若干 API 进行组合,定制为工作流。

完整的列表请参见 [Cookbook](./doc/cookbook/README.md)
Expand Down
1 change: 1 addition & 0 deletions doc/cookbook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ The following examples show how to use Easegress for different scenarios.
- [Security](./security.md) - How to do authenication by Header, JWT, HMAC, OAuth2, etc.
- [Service Proxy](./service_proxy.md) - Supporting the Microservice registries - Zookeeper, Eureka, Consul, Nacos, etc.
- [WebAssembly](./wasm.md) - Using AssemblyScript to extend the Easegress
- [WebSocket](./websocket.md) - WebSocket proxy for Easegress
- [Workflow](./workflow.md) - An Example to make a workflow for a number of APIs.
98 changes: 98 additions & 0 deletions doc/cookbook/websocket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# WebSocket

- [WebSocket](#websocket)
- [Background](#background)
- [Design](#design)
- [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

- WebSocket server of Easegress is called `WebSocketServer` and it belongs to the group of BusinessControllers.

- Easegress uses `github.com/gorilla/websocket` to implement `WebSocket` client since it has rich features supported and a quite active community (15k star/2.5k fork). Gorilla supports some useful features (`receive fragmented message` and `send close message`) that do not exist in Go's standard WebSocket library `golang.org/x/net/websocket` [3], which make it a natural choice for Easegress WebSocketServer.

1. Spec

Example1: `http` and `ws`

```yaml
kind: WebSocketServer
name: websocketSvr
https: false # client need to use http/https firstly for connection upgrade
certBase64:
keyBase64:
port: 10020 # proxy servers listening port

backend: ws:https://localhost:3001 # the reserved proxy target
# Easegress will exame the backend URL's scheme, If it starts with `wss`,
# then `wssCerBase64` and `wssKeyBase64` must not be empty

wssCertBase64: # wss backend certificate in base64 format
wssKeyBase64: # wss backend key in base64 format
```

Example2: `https` and `wss`

```yaml
kind: WebSocketServer
name: websocketSvr
https: true
certBase64: your-cert-base64
keyBase64: your-key-base64
port: 10020
backend: wss:https://localhost:3001
wssCertBase64: your-cert-wss-base64
wssKeyBase64: your-key-wss-base64
```

2. Request sequence

```none
+--------------+ +--------------+ +--------------+
| | 1 | | 2 | |
| client +--------------->| Easegress +--------------->| websocket |
| |<---------------+(WebSocketSvr)|<---------------+ backend |
| | 4 | | 3 | |
+--------------+ +--------------+ +--------------+
```

3. Headers

We copy all headers from your HTTP request to websocket backend, except ones used by `gorilla` package to build connection. Based on [4], we also add `X-Forwarded-For`, `X-Forwarded-Host`, `X-Forwarded-Proto` to http headers that send to websocket backend.

> note: `gorilla` use `Upgrade`, `Connection`, `Sec-Websocket-Key`, `Sec-Websocket-Version`, `Sec-Websocket-Extensions` and `Sec-Websocket-Protocol` in http headers to set connection.
## Example

1. Create a WebSocket proxy for Easegress: `egctl object create -f websocket.yaml`. Here we use `Example1` as example, which will transfer requests from `easegress-ip:10020` to `ws:https://localhost:3001`.

2. 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:https://127.0.0.1:10081/
```

3. This request to `WebSocketServer` `easegress-ip:10081` will be transferred to websocket backend `ws:https://localhost:3001`.

## References

1. <https://datatracker.ietf.org/doc/html/rfc6455>
2. <https://www.nginx.com/blog/websocket-nginx/>
3. <https://github.com/gorilla/websocket>
4. <https://docs.oracle.com/en-us/iaas/Content/Balance/Reference/httpheaders.htm>

0 comments on commit 0b9e2d1

Please sign in to comment.