代理 WebSocket 连接
WebSocket 通过单个 TCP 连接提供持久的双向通信。它通常用于实时数据流、聊天、协作应用以及其他实时交换数据的工作负载。
APISIX 可以代理初始 HTTP 升级请求,并保持由此建立的 WebSocket 连接。本指南会配置一条指向 WebSocket 上游的路由,并验证通过 APISIX 传输的双向流量。
前置条件
- 安装 Docker。
- 安装 cURL,以通过 Admin API 配置 APISIX。
- 安装 websocat,以建立 WebSocket 连接。
- 按照入门教程在 Docker 中启动 APISIX 实例。
启动 WebSocket 上游
将 GATEWAY_CONTAINER 设置为正在运行的 APISIX 容器。创建专用网络,并将网关连接到该网络:
export GATEWAY_CONTAINER=replace-with-apisix-container-name
docker network create gateway-websocket-net
docker network connect gateway-websocket-net "$GATEWAY_CONTAINER"
在共享网络上启动已固定版本的 WebSocket 示例服务器:
docker run -d \
--name websocket-server \
--network gateway-websocket-net \
jmalloc/echo-server:v0.3.7
该服务器公开了 /.ws 端点,并会回显收到的每条消息。
创建路由
创建一条指向 WebSocket 端点并启用 WebSocket 代理的路由:
- Admin API
- ADC
curl "http://127.0.0.1:9180/apisix/admin/routes/websocket-proxy" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/.ws",
"enable_websocket": true,
"upstream": {
"type": "roundrobin",
"nodes": {
"websocket-server:8080": 1
}
}
}'
services:
- name: websocket-proxy
labels:
docs-example: proxy-websocket
routes:
- name: websocket-proxy
uris:
- /.ws
enable_websocket: true
upstream:
type: roundrobin
nodes:
- host: websocket-server
port: 8080
weight: 1
ADC 会将服务作为期望状态进行对账。预览由此示例管理的更改,并确认差异中不包含意外的更新或删除:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=proxy-websocket
同步经审查的服务配置:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=proxy-websocket
验证连接
通过 APISIX 打开连接:
websocat "ws://127.0.0.1:9080/.ws"
发送 hello。服务器应回显该消息:
Request served by <container-id>
hello
hello
连接保持打开且消息被回显,证明 APISIX 已完成协议升级,并能够双向代理流量。
代理 WebSocket 帧
APISIX 可以解析 WebSocket 帧,使插件能够检查或修改消息。使用 ws 或 wss 上游以及 websocket-proxy 插件来配置此行为。相比之下,enable_websocket 只执行协议升级,之后直接转发字节,不会向插件公开各个帧。
要让插件处理上述示例服务器的消息,请创建另一条上游 scheme 为 ws 的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes/ws-frames" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"uri": "/ws-frames",
"plugins": {
"proxy-rewrite": {
"uri": "/.ws"
},
"websocket-proxy": {
"client_max_payload_len": 1048576,
"upstream_max_payload_len": 1048576
}
},
"upstream": {
"type": "roundrobin",
"scheme": "ws",
"nodes": {
"websocket-server:8080": 1
}
}
}'
❶ client_max_payload_len 和 upstream_max_payload_len 将两个方向的默认 65,535 字节限制提高到 1 MiB。限制分别作用于每个方向的完整消息,包括拆分到多个帧中的消息。
❷ scheme 使用 ws 启用帧处理。安全上游请使用 wss。enable_websocket 路由选项不会影响 ws 或 wss 上游。
像之前一样连接并发送消息:
websocat "ws://127.0.0.1:9080/ws-frames"
身份认证以及其他重写和访问阶段插件仍会在 HTTP 握手期间运行。HTTP 响应转换插件不会转换 WebSocket 消息。连接关闭后才会执行日志记录。
对于安全上游,请使用 wss,启用 upstream.tls.verify,并通过 config.yaml 中的 apisix.ssl.ssl_trusted_certificate 配置可信 CA 证书。ws 和 wss scheme 不支持各上游的 tls.ca_certs。请将上游主机设置为证书覆盖的名称。有关信任链和主机名配置,请参阅配置上游 HTTPS。
后续步骤
你已配置 APISIX 代理 WebSocket 连接。如需控制并发连接数,请参阅限制 WebSocket 连接速率。