使用 BOSH 时处理 JavaScript 中丢失的消息
Posted
技术标签:
【中文标题】使用 BOSH 时处理 JavaScript 中丢失的消息【英文标题】:Dealing with missing messages in JavaScript when using BOSH 【发布时间】:2010-04-25 14:37:27 【问题描述】:我们最近对我们的旗舰产品进行了私人测试,并举办了一场小型发布会。不幸的是,场地的无线连接很糟糕,数据包被左右和中心丢弃,在没有系统的情况下造成了严重破坏,基本上它根本无法工作!幸运的是,我们能够切换到不同的网络并拯救演示。这突出了我知道已经是一个问题但没有意识到它可能是一个多大的问题。我们的系统严重依赖 BOSH,并且有一个相当大的 javascript 代码库,现在在良好的网络条件下运行良好。但是我们需要让它在糟糕的网络条件下也能正常工作。
由于 XMPP 的工作方式是一种即发即弃的系统,因此很难判断您发送或应该接收的消息是否实际发送或接收。例如,我们有一个报价系统,一个用户将通过 BOSH 向另一个用户发送报价。当服务器接收到此消息时,将向提供用户 offer_sent PEP 节点发布一条消息,并向接收用户 offer_received PEP 节点发布一条类似消息。虽然发送用户能够(相对)轻松地判断他们的报价是否已发送(相对),但如果从未收到发送给接收用户的通知,该用户将永远不会知道它错过了一条消息。
关于 JavaScript 设置的一点点,它有 4 个主要层:
-
StropheJS
一个用于处理低级任务并在其之上构建的 MVC 框架
一个应用层,包含应用逻辑路由、控制器模型等以及模型数据的浏览器缓存
一个 UI 层,用于接收事件并将事件发布到应用层和从应用层发布事件
解决丢失消息问题的一种方法是定期检查 PEP 节点以获取浏览器不知道的新数据。如果发现新消息,则浏览器缓存将失效,并且将从服务器请求所有新数据。我不确定这是最好的方法,也不能涵盖所有情况。我们当然不希望陷入我们发送消息以确认在其目的地收到前一条消息的情况,因为这会使网络流量增加一倍。
随着实时网站的数量每天都在增长,这是其他开发人员肯定遇到过的问题,看看其他人如何解决这个问题会很有趣。据我所知,消息丢失有两种情况:
-
在连接不佳时,由于数据包被丢弃而无法发送或接收消息
涉及页面之间的导航,浏览器接收到一条消息,但在卸载页面之前未完全处理并存储在本地缓存中。或者一条消息被添加到发送队列中,但在页面卸载之前从未发送过
我怀疑最难解决的问题将是第二个问题。对此主题的任何想法将不胜感激。
【问题讨论】:
【参考方案1】:对此没有好的解决方案,但是有一个可行的解决方案。
BOSH 会话仅在给定时间(在大多数实施中默认为 60 秒)保持有效。一旦会话过期,假的 c2s 连接就会关闭,用户必须重新登录。
在会话有效期间,不应丢失任何消息或无序到达。丢失的唯一可能性是在允许 HTTP 重新打开连接的 60 秒窗口期间,并且如前所述,如果该窗口关闭,则必须创建一个新会话。如果在该窗口内发出新的 HTTP 请求,则不会丢失任何内容或无序到达。
我建议,因为您使用 PEP 作为您的存储,所以每当创建会话时,您在客户端中有一个钩子,您从 PEP 节点获取项目以初始化您的客户端缓存(请参阅section 6.5 of XEP-0060)。
如果您的 BOSH 客户端成功接收到消息,但在成功处理之前关闭或重新加载网页,消息仍然可能丢失。但是,对于其他情况,您应该不会再看到任何数据丢失,只是在启动期间由于项目检索而出现额外的延迟。
【讨论】:
我们实施了一项临时修复,使我们的系统使用起来更加稳定。我们在每次页面加载时都从 PEP 和 PubSub 节点请求所有数据。虽然这并不理想,因为它会增加流量,但它确实有效。将来我们将实施 BOSH ACKing(请参阅xmpp.org/extensions/xep-0124.html#acks),这将使我们能够确保消息传递。由于这需要在客户端和服务器端进行大量工作,因此我们将在以后需要此优化时实施。【参考方案2】:您应该使用请求和响应确认来解决此问题:http://xmpp.org/extensions/xep-0124.html#acks strophe.js 作者提到他将在未来的某个时间添加对此的支持。
【讨论】:
您提供的链接指向 XEP 的错误部分(哈哈),这是正确的 url:xmpp.org/extensions/xep-0124.html#ack以上是关于使用 BOSH 时处理 JavaScript 中丢失的消息的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 BOSH 连接到 google talk xmpp 服务器?
使用 XMPP Strophe BOSH 刷新页面后客户端自动变为不可用
使用 strophe 和 ejabberd bosh 连接到 localhost 上的 jid 帐户时连接失败