使用Jetty WebSocket进行流量控制

时间:2013-10-25 20:21:11

标签: websocket jetty

我尝试使用WebSockets作为应用程序协议(此处没有浏览器),并且遇到流量控制问题......我目前正在使用带有WebSocketServlet的Jetty 9.1.0.RC0,并且一个@WebSocket。

第一种情况是消息的传入速度比我处理速度快。在这种情况下,我想暂停从该套接字读取并让TCP背压做它的事情。这在之前的应用程序中非常有效(当然非websocket)。我认为Session.suspend()可能会做我想要的,但它似乎没有任何影响,并且返回的标记为null。

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

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

由于我已经嵌入了jetty并且正在将它用于SpringMVC,如果我能够获得我需要的流量控制,以避免在另一个端口上运行像Netty这样的东西,那将是很好的。

感谢。

1 个答案:

答案 0 :(得分:0)

Jetty和JSR API确实具有一种独特的回调写作风格。在Jetty它是:     sendBytes(ByteBuffer数据,WriteCallback回调) 和JSR API是:     sendBinary(ByteBuffer数据,SendHandler处理程序)

都有文本消息等价物。但是这两个都存在一些问题。首先,如果回调用于流量控制,则回调将“在消息传输时被通知”。这对于高吞吐量来说不是最佳的,因为这意味着下一条消息的发送将一直等到前一条消息被发送,没有机会将多条消息聚合成单一写入。

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

一个“解决方案”是拥有一个有限的队列大小,但是你会遇到一个问题,假设异步调用sendBytes突然阻塞!

我认为解决方案是对邮件排队等待传输但在实际传输时调用的传输有一种替代形式的回调。一旦调用了这个回调,就可以重用/回收任何传递的缓冲区,并且可以进行另一次调用和另一个sendBytes / sendBinary调用。

也许是这样的:

public interface QueuedWriteCallback扩展了WriteCallback   {     writeQueued();   }

和JSR:

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