You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在java.net.http.WebSocket中使用permessage-deflate压缩?

Java 19内置WebSocket客户端启用permessage-deflate压缩的方案

Java 19的java.net.http.WebSocket确实没有提供公开API来配置permessage-deflate扩展,且WebSocket Builder会禁止手动设置Sec-WebSocket-Extensions这类协议专属头,直接调用header()方法必然抛出异常。不过可以通过自定义HttpClient过滤器,在握手请求发送前插入扩展头来绕过限制:

// 构建带请求拦截逻辑的HttpClient
HttpClient httpClient = HttpClient.newBuilder()
        .filter((request, next) -> {
            // 仅针对WebSocket握手请求修改头信息
            if (HttpMethod.GET.equals(request.method()) && 
                "websocket".equalsIgnoreCase(request.headers().firstValue("Upgrade").orElse(""))) {
                HttpRequest modifiedRequest = request.newBuilder()
                        .header("Sec-WebSocket-Extensions", "permessage-deflate")
                        .build();
                return next.sendAsync(modifiedRequest, responseInfo -> BodyHandlers.discarding());
            }
            return next.sendAsync(request, responseInfo -> BodyHandlers.discarding());
        })
        .build();

// 使用该HttpClient创建WebSocket连接
WebSocket ws = httpClient.newWebSocketBuilder()
        .subprotocols(protocol)
        .buildAsync(uri, new WebSocket.Listener() {
            // 实现自定义消息监听逻辑
            @Override
            public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
                webSocket.request(1);
                return CompletableFuture.completedFuture(null);
            }
        })
        .join();

需要注意的细节:

  • 这种方式属于非官方的临时解决方案,依赖HttpClient的过滤器拦截能力,后续Java版本的内部逻辑调整可能导致失效。
  • 必须确保目标WebSocket服务器支持permessage-deflate扩展,否则握手可能失败,或者服务器会忽略该扩展头,压缩功能不会生效。
  • 握手成功后,客户端与服务器会协商具体压缩参数,实际压缩效果取决于双方的配置匹配度。

内容的提问来源于stack exchange,提问作者Krisz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 03:23:19