2

我正在尝试将 WebSockets 用作应用程序协议(这里没有浏览器)并且遇到了流控制问题......我目前正在使用带有 WebSocketServlet 和 @WebSocket 的 Jetty 9.1.0.RC0。

第一种情况是消息进来的速度比我处理它们的速度快。在这种情况下,我想暂停从该套接字读取并让 TCP 背压来做它的事情。这在以前的应用程序(当然非 websocket)中效果很好。我认为 Session.suspend() 可能会做我想做的事,但它似乎没有影响,并且返回的令牌为空。

有没有办法怀疑阅读?作为基于 nio 的连接器,Jetty 将继续读取帧并缓冲它们,直到我可以处理它们为止,我宁愿暂停读取,也不必引入一些流控制消息。

我的第二种情况是我向连接的客户端发送 websocket 消息 - 这可能是一个浏览器,但并非总是如此......看来我可以通过使用 sendStringByFuture 方法获得一些流量控制,但是有没有办法获得一个未来完成时回调,而不是等待它或轮询它?

由于我已经嵌入了 jetty 并将其用于 SpringMVC,因此如果我能获得所需的流控制,以避免在另一个端口上运行类似 Netty 的东西,那就太好了。

谢谢。

4

1 回答 1

0

Jetty 和 JSR API 确实具有异步回调编写方式。在 Jetty 中是:sendBytes(ByteBuffer data, WriteCallback callback) 而 JSR API 是:sendBinary(ByteBuffer data, SendHandler handler)

两者都有短信等价物。但这两者都存在一些问题。首先,如果回调用于流量控制,那么回调将“在消息已传输时得到通知”。这对于高吞吐量来说不是最优的,因为这意味着下一条消息的发送将始终等到前一条消息已传输完毕,从而没有机会将多条消息聚合到一次写入中。

如果后续对 sentBytes 或 sendBinary 的调用不等待回调,那么它们可以将多个帧排队,这些帧将被有效传输,但问题是发送时没有背压,因此内部队列可能会永远增长。

一种“解决方案”是限制队列大小,但随后您会遇到对 sendBytes 的所谓异步调用突然阻塞的问题!

我认为解决方案是为发送提供另一种形式的回调,一旦消息排队等待传输,但实际上并未传输。一旦调用了这个回调,那么任何传递的缓冲区都可以被重用/回收,并且可以进行另一个调用和另一个对 sendBytes/sendBinary 的调用。

也许是这样的:

公共接口 QueuedWriteCallback 扩展 WriteCallback { writeQueued(); }

对于 JSR:

公共接口 QueuedSendHandler 扩展 SendHandler { onQueued(); }

于 2013-12-16T00:08:05.723 回答