使 WebSocket 发送非阻塞

Posted

技术标签:

【中文标题】使 WebSocket 发送非阻塞【英文标题】:Make WebSocket sending non-blocking 【发布时间】:2017-04-06 14:12:43 【问题描述】:

Jetty 使用 org.eclipse.jetty.websocket.common.BlockingWriteCallback 通过 websocket 发送消息。如果客户端“慢”,则此阻塞写入可能会挂起(参见例如此处https://github.com/eclipse/jetty.project/issues/272#issuecomment-290910610)

我使用 Jetty+Spring+Spring 的 Websocket 客户端成功模拟了慢速客户端。

我想“发送并忘记”websocket 消息,所以如果客户端速度很慢(无论它尝试做什么确认),这不会影响 BrokerWriteCallback 的解析。使用 Jetty 实现这一目标的最佳方法是什么(配置或源代码编辑?)

当前 Jetty 版本 9.3.11.v20160721 与 Spring 4.3.3 一起使用。

【问题讨论】:

【参考方案1】:

Jetty 已经有 slow server 和 slow client 测试。

没有所谓的“发送后忘记”,因为这意味着无限缓冲。

有非阻塞发送选项,但强烈建议您注意FuturesCallbacks 以了解本地端点是否已成功发送该消息(或)。

提示:如果前一个消息尚未成功(您需要处理网络拥塞决定),请不要向 RemoteEndpoint 发送另一个消息。

不注意FuturesCallbacks触发内存错误(OOM)。

RemoteEndpoint:

void sendBytes(ByteBuffer 数据,WriteCallback 回调) 未来sendBytesByFuture(ByteBuffer 数据) void sendString(字符串文本,WriteCallback 回调) 未来sendStringByFuture(字符串文本)

如果所有这些看起来都不堪重负,请考虑使用基于 websocket 构建的众多库之一来管理所有这些。

我鼓励你看看开源项目cometd.org

【讨论】:

谢谢!你能详细说明你提到的问题吗?假设我 sendString 带有回调。当客户端收到消息或“写入网络”但没有客户端确认时回调会返回吗?老实说,我还不知道低级通信到底是如何工作的,并且也很欣赏这方面的有用见解。如果客户端“挂起”(无法接收),则线程被阻塞。理想情况下,我希望我的程序能够将数据发送给其他客户端。目前我出于某些原因使用单线程发送(只有一个线程可以调用 Jetty)

以上是关于使 WebSocket 发送非阻塞的主要内容,如果未能解决你的问题,请参考以下文章

如何以非阻塞方式处理 websocket 数据?

Android websock 应用

c# webapi websocket 服务端消息发送

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

SpringBoot - WebSocket

Python websocket 客户端 - 从 python 代码向 WebSocketServer 发送消息