|
This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Cloud Gateway 5.0.4! |
WebSockets
Spring Cloud Gateway Server Web MVC can proxy WebSocket connections. To enable it, add spring-boot-starter-websocket:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
With WebSocket support on the classpath, a route can proxy WebSockets in either of two ways:
-
Use a
wsorwssURI. -
Use an
http,httpsorlbURI. A request with anUpgrade: websocketheader is proxied as a WebSocket, andhttpandhttpsbecomewsandwss.
spring:
cloud:
gateway:
server:
webmvc:
routes:
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**
The following example configures the same route with the Java DSL:
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.websocket;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> websocketRoute() {
return route("websocket_route")
.GET("/websocket/**", websocket())
.before(uri("ws://localhost:3001"))
.build();
}
}
The gateway connects to the backend before it completes the client’s handshake. The client is offered the subprotocol the backend accepted, and gets 502 Bad Gateway if the backend cannot be reached.
Text, binary and pong messages are relayed in both directions. Ping messages are not relayed: the servlet WebSocket API does not deliver them to applications, and the container answers each ping with a pong itself. A client that pings the gateway gets a reply even if the backend is slow or unresponsive. To check that the backend itself is alive, use application-level heartbeat messages.
Request filters such as StripPrefix, AddRequestHeader and TokenRelay apply to the handshake. Headers added by response filters are set on the handshake response. Once the connection is established, messages are relayed as they are. Filters that act on a response body, as well as retry and circuit breaker filters, do not apply.
Allowed Origins
Browsers do not enforce CORS on WebSocket handshakes, so the gateway checks the Origin header itself. By default, it accepts only same-origin handshakes and handshakes without an Origin header (such as those from non-browser clients). Cross-origin handshakes are rejected with 403 Forbidden.
To accept handshakes from other origins, set spring.cloud.gateway.server.webmvc.websocket.allowed-origins. Patterns such as https://.example.com are supported, and allows all origins:
spring:
cloud:
gateway:
server:
webmvc:
websocket:
allowed-origins:
- https://*.example.com
Configuration Properties
All properties are under spring.cloud.gateway.server.webmvc.websocket.
| Property | Default | Description |
|---|---|---|
|
|
Whether WebSocket proxying is enabled. |
|
(same origin only) |
Additional origins allowed to open a connection. |
|
|
Time allowed to connect to the backend. |
|
|
Time allowed to send a single message to either side before the session is closed. |
|
|
Outbound data buffered per session before the session is closed. |
|
|
Largest message accepted from either side. Larger messages close the connection with status |
Servlet WebSocket has no backpressure. When one side reads more slowly than the other sends, outbound messages are buffered up to send-buffer-size-limit, and then the connection is closed.
Each open connection holds container resources for its lifetime. For gateways with many long-lived connections, consider enabling virtual threads with spring.threads.virtual.enabled=true.