一旦队列填满,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)

客户端在接收数据时不进行任何计算,因此可能不会成为缓慢的加入者。

所以我想知道我能做些什么来解决这个问题?(使用码头9.2.3)

如果错误消息来自同步发送,则有多个线程试图在同一个RemoteEndpoint上发送消息,这是协议不允许的。一次只能发送一条消息。(基本上没有同步发送的队列)

如果错误消息来自异步发送,那么这意味着您有消息在队列中等待发送,但您仍在尝试写入更多异步消息。

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

使用Java期货:

您将希望使用sendBytesByFuture()sendStringByFuture()方法返回时提供的Future对象来验证消息是否已实际发送(可能是错误),如果有足够多的开始排队未发送,您将停止发送更多消息,直到远程端点能够赶上为止。

标准的Future行为和技术适用于此。

使用Jetty回调:

sendBytes(ByteBuffer,WriteCallback)sendString(String,WriteCallback)方法中也有WriteCallback行为,它们会在成功/错误时调用您自己的代码,在这种情况下,您可以围绕发送的内容设置一些逻辑(限制、发送速度较慢、排队、过滤、丢弃一些消息、排定消息优先级等,无论您需要什么)

使用阻塞:

或者,您可以使用阻塞发送来避免太多的消息排队。

相关内容

  • 没有找到相关文章

最新更新