1

我有一个网络应用程序,我在其中将模型更改流式传输到 chrome 客户端中的主干集合。有一些主干视图可能会或可能不会呈现页面的某些部分,具体取决于更新的类型和正在查看的内容。例如,对模型的某些更改会导致重新渲染集合的视图,并且可能会或可能不会为正在更新的模型打开详细信息面板视图。这些模型更改可能发生得非常快,因为服务器端工作流程涉及对模型的非常冗长和快速的更改。

这是问题所在:当向客户端发送消息时,我在网络服务器的进程中收到大量 errno 32 管道损坏消息,尽管 websocket 连接仍然处于打开状态并且它readyState仍然是 1(打开)。

我怀疑正在发生的事情是,onmessage当下一条消息进来时,各种视图还没有在回调中完成渲染。在我在标准输出中获得这些回溯后,websocket 连接仍然可以工作,并且 UI 仍然会更新。

如果我放入eventlet.sleep(0.02)从消息队列中读取模型更改并将它们发送到 websocket 的循环中,那么损坏的管道消息就会消失,但这不是一个真正的解决方案,感觉就像一个讨厌的 hack。

有没有人对 websocket 的功能有类似的问题,onmessage试图做太多的工作并且在下一条消息进来时仍然很忙?有人有解决方案吗?

4

1 回答 1

0

我认为最有效的方法是客户端应用程序告诉服务器它们正在显示什么。服务器对此进行跟踪并仅将更改发送到当前查看的对象,仅发送给相关的客户端。

一种方法是使用“谁看什么”项目列表。项目以两种方式编制索引。从客户端 ID 和每个数据对象内部的 isVievedBy 链表(我知道将它与数据混合看起来并不干净,但它非常有效)。您还需要每个数据对象的 lastupdate 时间戳。

当客户端更改视图时,它会向服务器发送“我正在查看这个,我有版本-时间戳-”消息。服务器检查时间戳并在需要时发回对象。它还删除过时的“Who Watch What”(通过客户端 ID 访问它们)项目并创建新项目。

当一个数据对象被更新时,遍历这个对象的 isVievedBy 链表来知道应该更新哪个客户端。将其放入每个客户端的消息缓冲区并手动刷新这些缓冲区(如果您同时更新多个项目,它将发送一条大消息)。

这是很多工作,但您的应用程序将是高效的并且可以优雅地扩展,即使有很多对象和很多客户端。它只发送有用的消息,而且不太可能有太多的消息。

对于您的 onMessage 问题,我会将数据存储在队列中并异步处理它们。

于 2012-09-04T15:12:55.190 回答