Proxy WebSocket Connections
WebSocket is a protocol that provides a bidirectional channel between a client and a server over a single TCP connection. It revolutionizes real-time communication on the web where data can be sent and received in real-time. The protocol is widely used in a variety of interactive applications, including chat applications, collaborative editing tools, multiplayer gaming, and more.
This guide will show you how you can use APISIX to proxy WebSocket connections.
Prerequisite(s)
- Install Docker.
- Install cURL to send requests to the services for validation.
- Install websocat to establish WebSocket connections with a WebSocket server.
- Follow the Getting Started tutorial to start a new APISIX instance in Docker.
Start WebSocket Sample Server
Start a sample upstream server with WebSocket support:
- Docker
- Kubernetes
docker run -d \
-p 8080:8080 \
--name websocket-server \
--network=apisix-quickstart-net \
jmalloc/echo-server
Create a Kubernetes manifest file for the deployment of WebSocket server:
apiVersion: apps/v1
kind: Deployment
metadata:
name: websocket-server
spec:
replicas: 1
selector:
matchLabels:
app: websocket-server
template:
metadata:
labels:
app: websocket-server
spec:
containers:
- name: echo-server
image: jmalloc/echo-server
ports:
- containerPort: 8080
Create another Kubernetes manifest file for the WebSocket service:
apiVersion: v1
kind: Service
metadata:
name: websocket-server
spec:
selector:
app: websocket-server
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
Apply the configuration to your cluster:
kubectl apply -f ws-deployment.yaml -f ws-service.yaml
The server has a WebSocket endpoint at /.ws
that echoes back any message received.
Create Route in APISIX
Create a route to the sample upstream server and enable WebSocket:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "ws-route",
"uri": "/.ws",
"enable_websocket": true,
"upstream": {
"type": "roundrobin",
"nodes": {
"websocket-server:8080": 1
}
}
}'
services:
- name: websocket Service
routes:
- uris:
- /.ws
name: ws-route
enable_websocket: true
upstream:
type: roundrobin
nodes:
- host: websocket-server:8080
port: 8080
weight: 1
Synchronize the configuration to APISIX:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ws-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /.ws
backendRefs:
- name: websocket-server
port: 8080
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: ws-route
spec:
ingressClassName: apisix
http:
- name: ws-route
match:
paths:
- /.ws
backends:
- serviceName: websocket-server
servicePort: 8080
Apply the configuration to your cluster:
kubectl apply -f ws-route.yaml
Verify Connections
Establish a connection with the WebSocket server through the route:
websocat "ws://127.0.0.1:9080/.ws"
Send a "hello" message in the terminal. You should see the WebSocket server echoes back the same message:
Request served by 1cd244052136
hello
hello
You can continue to send more messages and the WebSocket server will echo back any message you sent. This shows the bidirectional connection is successful and persistent.
Next Steps
You have now learned how to proxy WebSocket connections with APISIX. If you would like to rate limit the number of WebSocket connections, see the limit-conn
plugin doc for more information.