如何使用 websocket 检查消息是不是真的在 Netty 中传递?
Posted
技术标签:
【中文标题】如何使用 websocket 检查消息是不是真的在 Netty 中传递?【英文标题】:How to check if a message is really delivered in Netty using websocket?如何使用 websocket 检查消息是否真的在 Netty 中传递? 【发布时间】:2014-03-14 02:33:43 【问题描述】:我正在使用 Netty 开发一个 websocket 应用程序。我想知道消息是否真的从源传递到目的地。特别是,让我们假设客户端和服务器有一个开放的通道并交换一些消息一段时间。在某个时刻,客户端宕机了,但通道在 Netty 中仍然处于活动状态。我尝试在发送消息之前使用 isReachable(),但这种方法在某些情况下似乎有问题(例如,装有 Win7 的机器已启动,但 isReachable() 返回 false)。现在,我的想法是使用 ACK 实现一种机制,即服务器发送消息,客户端发送回一个 ack。为此,我需要一个超时来查看是否在某个时间间隔后相应的 ack 没有到达。 Netty 有类似的吗?
【问题讨论】:
【参考方案1】:关于 isReachable() - 这只是一个尽力而为的 API。文档指出它尝试发送 ICMP 回显请求或创建到目标主机上的端口 7 的 TCP 连接,这两者都极有可能被防火墙阻止。你的情况是这样吗?
至于承认,Netty 中没有任何东西将其作为标准提供,但实施起来应该不会太难。首先,每条消息都需要通过某种标识符来唯一标识,可能是序列号,但全局唯一标识符意味着您可以在断开连接时恢复。然后你想创建一个实现 ChannelInboundHandler 和 ChannelOutboundHandler 的组合处理程序(假设 Netty 4)。消息发送时
将消息添加到由其 id 索引的地图中 创建一个与消息 ID 关联的计时器。将其添加到由消息 ID 索引的另一个地图中 转发消息当收到 ACK 时取消定时器并从它们各自的映射中删除定时器和消息。如果计时器触发,则使用关联的 id 来决定如何处理计时器和消息(可能重新传输并重置计时器)。
Netty 提供了一个 HashedWheelTimer 来有效地管理大量具有适合此类活动的分辨率的计时器。
您可能还想考虑限制重试次数,这样您就可以停止并引发错误,而不是无限期地持续。
【讨论】:
非常感谢您的回复,johnstir。如果命令由 shell 执行,Win7 会回复 ping 请求,而不是由 java 执行。出于这个原因,我说它可能有点错误。我不确定这对我的软件来说是否“太多”。这就像一个聊天,所以它转发了很多消息,软件应该包含很多很多计时器。好的,让我们假设我的软件尝试在没有 ACK 的情况下尽力而为,但如果它只想在发送消息之前检查客户端仍然连接怎么办?对于 isReachable(),我们有哪些替代方案? 好吧,我的问题也是这样:***.com/questions/21677864/…你也回复了! :) 我应该强调 isReachable() 并不真正适合您的需求。我希望您已经找到了答案,但是关于拥有大量计时器的问题,通常通过限制您在任何时候可以处理的消息数量来解决这个问题。因此,例如,您发送 10 条消息并将它们放入队列(称为发送窗口)中,并将其他消息留在其他数据结构中的队列中。当一条消息被确认时,您将其从发送窗口中删除并从您的另一个队列中发送另一条消息,从而再次填充发送窗口。这限制了未完成的消息和计时器。以上是关于如何使用 websocket 检查消息是不是真的在 Netty 中传递?的主要内容,如果未能解决你的问题,请参考以下文章
使用原始 WebSocket 时如何知道消息是不是已成功发送?