一旦队列填满,WebSocket异步发送可能导致阻塞发送

rim*_*mas 3 java jetty websocket

我有非常简单的基于Jetty的websockets服务器,负责流式传输小二进制消息以连接客户端.

为了避免在服务器端出现任何阻塞,我使用的是sendBytesByFuture方法.

在将负载从2个客户端增加到20之后,它们会停止接收任何数据.在故障排除期间,我决定打开同步发送方法,最终得到了可能的原因:

java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130)
at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendBytes(WebSocketRemoteEndpoint.java:244)
Run Code Online (Sandbox Code Playgroud)

客户端在接收数据时没有进行任何计算,因此可能无法成为缓慢的加入者.

所以我想知道如何解决这个问题呢?(使用Jetty 9.2.3)

Joa*_*elt 8

如果从同步发送出现错误消息,则您有多个线程尝试在同一发送上发送消息RemoteEndpoint- 这是协议不允许的.一次只能发送一条消息.(基本上没有同步发送的队列)

如果异步发送出现错误消息,那么这意味着您将队列中的消息等待发送,但您仍在尝试编写更多异步消息.

尽量不要同时混合同步和异步(很容易意外地将输出变成无效的协议流)

使用Java Futures:

您将需要使用Future返回sendBytesByFuture()sendStringByFuture()方法时提供的对象来验证消息是否实际发送(可能是一个错误),如果有足够的开始排队,则发送更多内容消息,直到远程端点赶上.

标准Future行为和技术适用于此处.

使用Jetty回调:

也有WriteCallback可用的行为sendBytes(ByteBuffer,WriteCallback)sendString(String,WriteCallback)方法,将呼吁成功/错误你自己的代码,在这你可以把你身边送什么一些逻辑(限制它,把它慢,排队它,将其过滤,滴一些消息,根据需要优先处理消息等

使用阻止:

或者你可以使用阻塞发送来永远不会有太多的消息排队.