-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reuses some of the Spring Framework websockets classes and a custom Proxy WebSocketHandler. fixes gh-6
- Loading branch information
1 parent
1d59ab5
commit 924c484
Showing
4 changed files
with
125 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
...y-core/src/main/java/org/springframework/cloud/gateway/filter/WebsocketRoutingFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package org.springframework.cloud.gateway.filter; | ||
|
||
import java.net.URI; | ||
import java.util.logging.Level; | ||
|
||
import org.springframework.core.Ordered; | ||
import org.springframework.web.reactive.socket.WebSocketHandler; | ||
import org.springframework.web.reactive.socket.WebSocketMessage; | ||
import org.springframework.web.reactive.socket.WebSocketSession; | ||
import org.springframework.web.reactive.socket.client.WebSocketClient; | ||
import org.springframework.web.reactive.socket.server.WebSocketService; | ||
import org.springframework.web.reactive.socket.server.support.HandshakeWebSocketService; | ||
import org.springframework.web.server.ServerWebExchange; | ||
import org.springframework.web.server.WebFilterChain; | ||
|
||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; | ||
|
||
import reactor.core.publisher.Mono; | ||
|
||
/** | ||
* @author Spencer Gibb | ||
*/ | ||
public class WebsocketRoutingFilter implements GlobalFilter, Ordered { | ||
private final WebSocketClient webSocketClient; | ||
private final WebSocketService webSocketService; | ||
|
||
public WebsocketRoutingFilter(WebSocketClient webSocketClient) { | ||
this(webSocketClient, new HandshakeWebSocketService()); | ||
} | ||
|
||
public WebsocketRoutingFilter(WebSocketClient webSocketClient, | ||
WebSocketService webSocketService) { | ||
this.webSocketClient = webSocketClient; | ||
this.webSocketService = webSocketService; | ||
} | ||
|
||
@Override | ||
public int getOrder() { | ||
return 2000000; | ||
} | ||
|
||
@Override | ||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { | ||
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); | ||
|
||
String scheme = requestUrl.getScheme(); | ||
if (!scheme.equals("ws") && !scheme.equals("wss")) { | ||
return chain.filter(exchange); | ||
} | ||
|
||
return this.webSocketService.handleRequest(exchange, new ProxyWebSocketHandler(requestUrl, this.webSocketClient)); | ||
} | ||
|
||
private static class ProxyWebSocketHandler implements WebSocketHandler { | ||
|
||
private final WebSocketClient client; | ||
private final URI url; | ||
|
||
public ProxyWebSocketHandler(URI url, WebSocketClient client) { | ||
this.client = client; | ||
this.url = url; | ||
} | ||
|
||
@Override | ||
public Mono<Void> handle(WebSocketSession session) { | ||
return client.execute(url, proxySession -> { | ||
// Use retain() for Reactor Netty | ||
Mono<Void> proxySessionSend = proxySession | ||
.send(session.receive().doOnNext(WebSocketMessage::retain)) | ||
.log("proxySessionSend", Level.FINE); | ||
Mono<Void> serverSessionSend = session | ||
.send(proxySession.receive().doOnNext(WebSocketMessage::retain)) | ||
.log("sessionSend", Level.FINE); | ||
return Mono.when(proxySessionSend, serverSessionSend).then(); | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters