一旦队列填满,WebSocket异步发送可能导致阻止发送 [英] WebSocket async send can result in blocked send once queue filled

查看:843
本文介绍了一旦队列填满,WebSocket异步发送可能导致阻止发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have pretty simple Jetty-based websockets server, responsible for streaming small binary messages to connect clients.

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

To avoid any blocking on server side I was using sendBytesByFuture method.

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

After increasing load from 2 clients to 20, they stop receive any data. During troubleshooting I decided to switch on synchronous send method and finally got potential reason:

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)

客户在接收数据时没有进行任何计算,因此他们可能不会是慢速加入者。

Clients not doing any calculations upon receiving data so potentially they can't be slow joiners.

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

So I wondering what can I do to solve this problem? (using Jetty 9.2.3)

推荐答案

如果同步发送出现错误消息,那么你有多个试图在同一个 RemoteEndpoint 上发送消息的线程 - 这是协议不允许的。一次只能发送一条消息。 (基本上没有用于同步发送的队列)

If the error message occurs from a synchronous send, then you have multiple threads attempting to send messages on the same RemoteEndpoint - something that isn't allowed per the protocol. Only 1 message at a time may be sent. (There is essentially no queue for synchronous sends)

如果异步发送出现错误消息,则表示您在队列中等待发送消息,但是你还在尝试编写更多的异步消息。

If the error message occurs from an asynchronous send, then that means you have messages sitting in a queue waiting to be sent, yet you are still attempting to write more async messages.

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

Try not to mix synchronous and asynchronous at the same time (it would be very easy to accidentally have output that become an invalid protocol stream)

使用Java期货:

你想要的使用 <$ c在 Future 对象/jetty/websocket/api/RemoteEndpoint.html#sendBytesByFuture(java.nio.ByteBuffer)rel =noreferrer> sendBytesByFuture() sendStringByFuture() 方法验证消息实际上是否已发送(可能是一个错误),并且如果有足够的开始排队,则在发送更多消息时退回,直到远程端点可以赶上。

You'll want to use the Future objects that are provided on the return of the sendBytesByFuture() and sendStringByFuture() methods to verify that the message was actually sent or not (could have been an error), and if enough start to queue up unsent you back off on sending more messages until the remote endpoint can catch up.

标准未来行为和技巧适用于此。

Standard Future behavior and techniques apply here.

使用Jetty回调:

还有 WriteCallback 行为stable-9 / apidocs / org / eclipse / jetty / websocket / api / RemoteEndpoint.html#sendBytes(java.nio.ByteBuffer,%20org.eclipse.jetty.websocket.api.WriteCallback)rel =noreferrer> sendBytes(ByteBuffer,WriteCallback) sendString(String,WriteCallback) 方法可以在成功/错误时调用您自己的代码,您可以在其中放置一些逻辑来围绕您发送的内容(限制它,发送速度慢,排队,过滤,删除一些消息,优先处理消息等等,无论你需要什么)

There is also the WriteCallback behavior available in the sendBytes(ByteBuffer,WriteCallback) and sendString(String,WriteCallback) methods that would call your own code on success/error, at which you can put some logic around what you send (limit it, send it slower, queue it, filter it, drop some messages, prioritize messages, etc. whatever you need)

使用阻止

或者您可以使用阻止发送来永远不会有太多的消息排队。

Or you can just use blocking sends to never have too many messages queue up.

这篇关于一旦队列填满,WebSocket异步发送可能导致阻止发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆