Java WebSocket 消息限制

Đor*_*jić 8 java websocket google-chrome-devtools java-http-client chrome-devtools-protocol

我正在尝试在简单的 Java 应用程序(使用java.net.http.WebSocket类)和google-chrome使用远程运行之间创建通信google-chrome --remote-debugging-port=9222 --user-data-dir=.

发送和接收小消息按预期工作,但在 16kb 大消息的情况下会出现问题。

这是java源代码的一部分:


var uri = new URI("ws://127.0.0.1:9222/devtools/page/C0D7B4DBC53FB39F7A4BE51DA79E96BB");

/// create websocket client
WebSocket ws = HttpClient
    .newHttpClient()
    .newWebSocketBuilder()
    .connectTimeout(Duration.ofSeconds(30))
    .buildAsync(uri, simpleListener)
    .join();

// session Id attached to chrome tab
String sessionId = "...";

// send message
String message = "{\"id\":1,\"method\":\"Runtime.evaluate\",\"params\":{\"expression\":\"document.body.style.backgroundColor = 'blue';\",\"returnByValue\":true,\"awaitPromise\":true,\"userGesture\":true},\"sessionId\":\"" + sessionId + "\"}";

// this works
ws.send(message, true);

// generate big string contains over 18k chars for testing purpose
String bigMessage = "{\"id\":2,\"method\":\"Runtime.evaluate\",\"params\":{\"expression\":\"[" + ("1,".repeat(9000)) + "1]\",\"returnByValue\":true,\"awaitPromise\":true,\"userGesture\":true},\"sessionId\":\"" + sessionId + "\"}";

// this doesn't work
ws.send(bigMessage, true);
Run Code Online (Sandbox Code Playgroud)

这是堆栈:

java.net.SocketException: Connection reset
    at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:345)
    at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:376)
    at java.net.http/jdk.internal.net.http.SocketTube.readAvailable(SocketTube.java:1153)
    at java.net.http/jdk.internal.net.http.SocketTube$InternalReadPublisher$InternalReadSubscription.read(SocketTube.java:821)
    at java.net.http/jdk.internal.net.http.SocketTube$SocketFlowTask.run(SocketTube.java:175)
    at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
...
Run Code Online (Sandbox Code Playgroud)

我已经通过使用puppeteer(nodejs 库)尝试了基本相同的方法,并且它按预期工作。

我在网上找不到关于这个问题的任何资源。在我的例子中有什么我遗漏的吗?


这是简单示例的网址:https : //github.com/zeljic/websocket-devtools-protocol

小智 2

根据我到目前为止所看到的情况,我最好的猜测是 Chrome 开发工具不会在该公开webSocketDebuggerUrl端点上处理碎片文本消息。Chrome 开发工具是否可以配置为这样做,是另一个问题。然而,我必须指出,RFC 6455(WebSocket 协议)强制要求这样做:

客户端和服务器必须支持接收分片和未分片的消息。

我可以在这里看到一种解决方法。请记住,这是不受支持的,并且将来可能会发生意外变化。运行客户端时,在命令行上指定以下系统属性-Djdk.httpclient.websocket.intermediateBufferSize=1048576(或选择任何其他合适的大小)。只要您继续发送消息并将其true作为boolean last参数传递给send*方法,java.net.http.WebSocket就会在单个 WebSocket 框架中发送完整的消息。