如何在 Java 中为 Web 套接字客户端(Jetty)设置最大缓冲区大小

Posted

技术标签:

【中文标题】如何在 Java 中为 Web 套接字客户端(Jetty)设置最大缓冲区大小【英文标题】:How can I set max buffer size for web socket client(Jetty) in Java 【发布时间】:2021-12-26 07:38:34 【问题描述】:

有一个connect web socket连接的功能。

public void connectWebSocket(String vaHost, String apiKey) throws Exception
        logger.info("========= CONNECT WEBSOCKET =========");
        String destUri = "ws://"+vaHost+"/metadata";

        WebSocketClient client = new WebSocketClient();
        SimpleEchoSocket socket = new SimpleEchoSocket();

        client.start();
        client.setConnectTimeout(-1);

        URI echoUri = new URI(destUri);
        ClientUpgradeRequest requestws = new ClientUpgradeRequest();
        requestws.setSubProtocols("va-metadata");

        requestws.setTimeout(-1, TimeUnit.SECONDS);

        client.setMaxBinaryMessageBufferSize(700000);
        client.connect(socket,echoUri,requestws);

        logger.info("=========WS Connecting to :"+echoUri);

您可以找到“setMaxBinaryMessageBufferSize”,以便我将最大缓冲区大小设置为 700000。

但是当 onMessageBuffer 事件发生时,我可以找到如下异常。

org.eclipse.jetty.websocket.api.MessageTooLargeException: Binary message size [484666] exceeds maximum size [65536]
    at org.eclipse.jetty.websocket.api.WebSocketPolicy.assertValidBinaryMessageSize(WebSocketPolicy.java:128)
    at org.eclipse.jetty.websocket.common.Parser.assertSanePayloadLength(Parser.java:133)
    at org.eclipse.jetty.websocket.common.Parser.parseFrame(Parser.java:494)
    at org.eclipse.jetty.websocket.common.Parser.parseSingleFrame(Parser.java:253)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:459)
    at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:440)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
    at java.base/java.lang.Thread.run(Thread.java:831)

如何设置 Web 套接字连接的最大缓冲区大小以防止异常?

【问题讨论】:

请编辑您的问题并添加您的SimpleEchoSocket 代码,问题似乎在该代码中。 还包括您使用的 Jetty 版本。 【参考方案1】:

有2个setMaxTextMessageBufferSize,setMaxBinaryMessageBufferSize

取决于您发送的数据类型:

    wsClient = new WebSocketClient(factory);
    wsClient.setMaxTextMessageBufferSize(Args.maxTextSize);
    wsClient.setMaxBinaryMessageBufferSize(Args.maxTextSize);

https://www.eclipse.org/jetty/javadoc/jetty-11/org/eclipse/jetty/websocket/client/WebSocketClient.html

您还可以选择在Session 上设置它:

CompletableFuture<Session> futureSession = wsClient.connect(webSocket, uri);


Session session = futureSession.get();

session.getPolicy().setMaxBinaryMessageBufferSize(Args.maxTextSize);
session.getPolicy().setMaxBinaryMessageSize(Args.maxTextSize);

session.getPolicy().setMaxTextMessageBufferSize(Args.maxTextSize);
session.getPolicy().setMaxTextMessageSize(Args.maxTextSize);

【讨论】:

策略的解析顺序可以看成:注解,然后是会话,然后是客户端。但是可以在运行时通过使用活动连接的会话来更改该值。 根据您的 Jetty 版本,最多可以有 6 个设置(ws-core 上 2 个,ws-api 上 2 个,ws-connection 上 2 个) 非常感谢你们!我可以解决我的问题。

以上是关于如何在 Java 中为 Web 套接字客户端(Jetty)设置最大缓冲区大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在jmeter中为java采样器请求生成多个登录用户

Spring Web 套接字 Java 客户端

在java中为一次调用执行两次Restful Web服务

如何在Hybris中为WSDL文件生成Java类?

在 Swift 中为聊天应用程序保持套接字打开

将 Ajax Web 应用程序迁移到 Web 套接字