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

Java 11 java.net.http.WebSocket分段发送超16k数据失败求助

Java 11 WebSocket分段发送超16k数据失败问题解决

问题背景

使用Java 11原生java.net.http.WebSocket向Tomcat WebSocket服务器发送分段二进制数据时,遇到如下问题:

  • 当分段总大小超过16k时,第二个(最后一个)分段发送失败,触发关闭码1009的错误:
SEVERE: WebSocketClientPeer#onClose statusCode [1009], reason [No async message support and buffer too small. Buffer size: [16,384], Message size: [1,656]]
  • 测试验证:若两个分段总大小≤16k则发送成功,仅超出1字节就失败;服务器端支持分段处理,且已有C++客户端可正常发送大分段数据,Java客户端能接收服务器发来的大分段数据。

根本原因

Java 11的java.net.http.WebSocket实现未遵循RFC6455第5.4节的分段规范——该规范要求WebSocket支持逐段发送消息,无需缓冲完整内容。但Java 11的实现会将所有分段缓冲至最后一个分段标记last=true时,再尝试发送合并后的完整消息,当总大小超过默认16k缓冲区时,就会触发缓冲区不足的错误。

可行解决方案

1. 切换至第三方WebSocket客户端库

选择严格遵循RFC6455规范的第三方库,比如Tyrus(Java EE官方WebSocket实现),它会逐段发送数据,不会缓冲整个消息。

示例代码:

import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;
import java.net.URI;
import java.nio.ByteBuffer;

@ClientEndpoint
public class SegmentedWsClient {
    public static void main(String[] args) throws Exception {
        WebSocketContainer container = ContainerProvider.getWebSocketContainer();
        // 建立连接
        Session session = container.connectToServer(SegmentedWsClient.class, URI.create("wss://myserver.dummy.com/wsweb"));
        
        // 发送第一个分段(非最后一段)
        ByteBuffer segment1 = ByteBuffer.wrap(new byte[16 * 1024]);
        session.getBasicRemote().sendBinary(segment1, false);
        
        // 发送最后一个分段
        ByteBuffer segment2 = ByteBuffer.wrap(new byte[2048]);
        session.getBasicRemote().sendBinary(segment2, true);
    }
}

Maven依赖配置:

<dependency>
    <groupId>org.glassfish.tyrus</groupId>
    <artifactId>tyrus-client</artifactId>
    <version>2.1.3</version>
</dependency>

2. 升级Java版本至17+

Java 17及以上的java.net.http.WebSocket修复了分段发送的缓冲问题,严格遵循RFC6455规范,无需修改代码即可正常发送超16k的分段数据。

3. 临时规避:调整服务器端缓冲区(不推荐)

若无法修改客户端,可尝试调整Tomcat WebSocket服务器的缓冲区大小,但这只是治标不治本,且可能影响其他客户端的兼容性,不推荐作为长期解决方案。

验证结果

使用Tyrus客户端或升级至Java 17后,发送总大小超过16k的分段数据时,服务器可正常接收并合并为完整消息,无缓冲区错误。

内容的提问来源于stack exchange,提问作者zdenko.s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:05:18