Quarkus Websocket Client握手遇308永久重定向,如何配置升级?
Quarkus WebSocket客户端308重定向问题解决思路
问题背景
离开Quarkus多年后重新配置WebSocket客户端,使用Quarkus BOM 3.7.1(包含quarkus-websockets-client依赖),通过ContainerProvider.getWebSocketContainer().connectToServer(RomanWebsocketClient::class.java, URI)启动客户端时出现异常:
- 测试地址
wss://socketsbay.com/wss/v2/1/demo/可正常连接; - 目标地址
https://myserverdomain/await/some-url-encoded-token返回308永久重定向,但相同URI在Ktor后端可正常工作。
已尝试无效方案:
- 声明
ClientEndpointConfig.Configurator注入Connection、Upgrade等请求头; - 调整Quarkus application.properties中的followRedirects配置。
问题解答
1. 若问题在于升级,如何正确配置?
核心问题是JSR-356标准的ContainerProvider实现(Quarkus基于Undertow)对WebSocket握手阶段的308重定向处理不完善,尤其是不会自动完成HTTPS到WSS的协议转换。正确配置思路如下:
- 改用Quarkus原生WebSocketClient API:放弃标准API,使用Quarkus提供的注入式客户端,它对重定向和协议转换的支持更适配Quarkus生态。示例代码:
@Inject WebSocketClient webSocketClient; public void connectToTarget() { URI targetUri = URI.create("https://myserverdomain/await/some-url-encoded-token"); webSocketClient.connect(RomanWebsocketClient.class, targetUri); }
同时在application.properties中开启重定向支持:
quarkus.websockets-client.follow-redirects=true
- 手动处理重定向:如果坚持用标准API,先通过HTTP请求获取重定向地址,手动替换协议后再发起WebSocket连接,示例代码见下文第3点。
2. Undertow/Netty是否不支持HTTPS协议上的WebSocket?
Undertow和Netty完全支持HTTPS之上的WebSocket(即WSS协议),你的测试地址能正常连接已经验证了这一点。问题并非协议支持缺失,而是标准WebSocket客户端对308重定向的协议转换处理逻辑不足——当重定向地址仍返回HTTPS协议时,客户端不会自动替换为WSS,导致后续握手请求用HTTP协议发起,最终失败。
3. 其他可行的解决办法
- 手动处理重定向流程:先通过HTTP客户端获取重定向后的Location头,替换协议后再发起WebSocket连接:
WebSocketContainer container = ContainerProvider.getWebSocketContainer(); // 1. 先发送HTTP请求获取重定向地址 URI originalUri = URI.create("https://myserverdomain/await/some-url-encoded-token"); HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder(originalUri).build(); HttpResponse<Void> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding()); String redirectLocation = response.headers().firstValue("Location").orElseThrow(() -> new RuntimeException("无重定向地址")); // 2. 替换协议为WSS URI wssUri = URI.create(redirectLocation.replace("https://", "wss://")); // 3. 发起WebSocket连接 container.connectToServer(RomanWebsocketClient.class, wssUri);
- 调整目标服务器重定向规则:联系运维修改服务器配置,让重定向直接返回WSS协议的地址,跳过客户端的协议转换步骤;
- 自定义WebSocketContainer配置:为标准客户端配置自定义Configurator,强制指定协议转换逻辑,同时确保请求头符合WebSocket握手要求。
内容的提问来源于stack exchange,提问作者yamilmedina
相关产品推荐
相关产品推荐

