Websockets - 自定义排队系统有意义吗?

Posted

技术标签:

【中文标题】Websockets - 自定义排队系统有意义吗?【英文标题】:Websockets - does a custom queueing system make sense? 【发布时间】:2017-02-17 15:00:21 【问题描述】:

我正在为基于回合的 Unity 游戏编写 node.js websocket 后端。这是我第一次使用 node.js 和 websockets,所以我想我会这样做,以便玩家可以重新连接,并会收到他们错过的任何消息。

然后我开始在游戏中实现它,并想测试我的排队系统,所以我关闭了我的互联网连接并重新打开它 - 并且惊讶地发现连接仍然存在,并且发送了任何错过的消息通过相同的连接。无需重新连接并将积压工作发送到新连接。

所以看起来 websocket 技术已经可以处理离线队列了?通过自己执行此操作(并通过将消息保留在其中增加服务器的内存负载)使服务器代码复杂化甚至有意义吗?

另外,它如何在没有互联网连接的情况下保持套接字连接?是否有标准化的超时时间,或者除非我手动关闭它,否则双方都会跟踪它?

谢谢!

【问题讨论】:

据我了解,您使用 socket.io 对吗? 不,我选择直接使用 websockets(即 require('websocket').server),因为我不需要 socket.io 的 ajax fallbacks。 我在半年前阅读并记下了一个笔记事实证明,保证消息传递确认是不可能的,但 TCP 保证在“无限”重试的情况下传递和订购。 你可以试试 Wireshark 或类似的跟踪套接字并进行一些测试以了解队列现在如何用于 WebSockets 的工具。 【参考方案1】:

然后我开始在游戏中实现它,并想测试我的排队系统,所以我关闭了我的互联网连接并重新打开它 - 并且惊讶地发现连接仍然存在,并且发送了任何错过的消息通过相同的连接。无需重新连接并将积压工作发送到新连接。

关闭连接不会自动终止通过该连接建立的任何套接字。当套接字尝试发送数据失败时,套接字最终会关闭,并且在多次重试和时间流逝之后,它们得到的只是错误。如果套接字没有主动尝试发送任何数据并且没有配置任何可能自动执行此操作的保持活动状态,那么它可能会在连接失效的情况下坐在那里数小时,并且根本不知道连接已失效。只要不使用套接字,它就没有自动方式知道它的端到端连接不再起作用。只有当它尝试使用连接并收到错误时才会发现。

请注意,如果服务器进程崩溃但连接保持活动状态,情况会有所不同。在这种情况下,服务器上的 TCP 堆栈会看到服务器进程崩溃,并会尝试清理它正在使用的所有套接字,并将关闭的数据包发送到另一端,而另一端将被主动告知该套接字是关闭。但是,您只是中断传输的情况并不相同。

所以看起来 websocket 技术已经可以处理离线队列了?通过自己执行此操作(并通过将消息保留在其中增加服务器的内存负载)使服务器代码复杂化甚至有意义吗?

websocket 是 TCP 套接字之上的协议层。 TCP 旨在成为一种可靠的传输方式,这意味着当它无法发送数据(但没有收到任何类型的套接字已被另一端关闭的通知)时,它会挂在该数据上并重试。它最终会放弃并反馈一些错误。

您可能对 socket.io 感兴趣,它是 webSocket 之上的一个层。它在此处添加了一些相关的内容:

    从端到端定期 ping,以便知道传输何时中断。 当套接字关闭或传输中断时无缝自动重新连接。 连接暂时中断时发送的数据自动排队。

另外,它如何在没有互联网连接的情况下保持套接字连接?是否有标准化的超时时间,或者除非我手动关闭它,否则双方都会跟踪它?

正如我之前所说,如果两端都没有尝试发送数据并且互联网连接在两个端点中间的某个地方中断,那么 webSocket 可能根本不知道连接当前不起作用。定期了解连接是否正常工作的唯一方法是通过连接发送数据并查看您是否得到及时响应。这就是 socket.io 对其 ping/pong 消息所做的事情。

无论物理连接发生什么,保持逻辑连接处于活动状态的方法是在物理连接之上使用一个额外的层(就像 socket.io 在 webSocket 之上所做的那样)。然后,这允许您拥有可以在不更改逻辑连接的情况下重新启动物理连接的代码。这正是 socket.io 从客户端所做的事情。如果你想从服务器端获得类似的东西,你可能需要实现你自己的数据队列,你想发送给客户端,只有当你确定它们已经成功发送时才从队列中删除。

【讨论】:

以上是关于Websockets - 自定义排队系统有意义吗?的主要内容,如果未能解决你的问题,请参考以下文章

在单个服务器上运行 Kubernetes 有意义吗?

覆盖ActiveRecord子类中的'=='方法有意义吗?

软考有意义吗?软考容易过吗?

软考有意义吗?软考容易过吗?

SQL插入上的开销有意义吗?

私钥加密公钥解密或者公钥加密私钥解密有意义吗?