Reputation: 1032
I'm running cloud gateway service in front of chat service which handles websocket connection. Do we have some convenient way to log interaction which happens between socket client & chat service on gateway side?
I've noticed that cloud gateway utilizes org.springframework.cloud.gateway.filter.WebsocketRoutingFilter
to proxy websockets but not sure how to join its party & if it right place to go
Upvotes: 1
Views: 2829
Reputation: 31
Spring Cloud Gateway is a powerful API gateway that provides a simple, yet effective way to route and filter incoming HTTP requests. While it's not specifically designed for WebSocket usage, it can be used to route WebSocket traffic by configuring custom filters.
To use filters to get WebSocket content in Spring Cloud Gateway, you can create a custom filter that extracts the WebSocket payload using the DataBuffer and DataBufferUtils classes. Here's an example:
@Component
public class WebSocketFilter implements GatewayFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
String payload = new String(bytes, StandardCharsets.UTF_8);
// Do something with the WebSocket payload here
return chain.filter(exchange);
});
}
}
In this example, the WebSocketFilter class implements the GatewayFilter interface and overrides its filter method. The method first uses DataBufferUtils.join to read the entire WebSocket payload into a single DataBuffer. Then, it extracts the bytes from the DataBuffer, converts them to a String using the UTF-8 charset, and finally applies some custom logic on the payload. Finally, the filter passes the exchange along the filter chain by invoking chain.filter(exchange).
To use the WebSocketFilter in your Spring Cloud Gateway configuration, you need to add it to the filter chain. Here's an example application.yml file that demonstrates how to do this:
spring:
cloud:
gateway:
routes:
- id: websocket_route
uri: ws://localhost:8080/echo
predicates:
- Path=/websocket
filters:
- WebSocketFilter
In this example, we define a route with the ID websocket_route that forwards incoming WebSocket requests to the ws://localhost:8080/echo endpoint. We use a Path predicate to match incoming requests on the /websocket path, and we add our custom WebSocketFilter to the filter chain to extract the WebSocket payload.
Note that this example only extracts the payload from the WebSocket message, but you can modify the WebSocketFilter class to extract whatever information you need from the message.
Upvotes: 0
Reputation: 1032
At the moment I haven't found a way to attach own interceptors with instruments provided by framework. So I've decided to copy pasted WebsocketRoutingFilter implementation, with @Primary annotation & inject own logic this way.
Original WebsocketRoutingFilter
creates instance of ProxyWebSocketHandler
internally to handle socket session and there is a method handle
which could be augmented.
Also be careful with DataBuffer
which represents each message. It'controls the amount of data which had been already read. So I've decided to read messages this way:
private String readBufferedMessage(DataBuffer dataBuffer) {
DataBuffer slice = dataBuffer.slice(0, dataBuffer.capacity());
byte[] bytes = new byte[slice.readableByteCount()];
slice.read(bytes);
return new String(bytes, StandardCharsets.UTF_8);
}
Upvotes: 1