ejabberd 中流管理的奇怪错误

Strange errors with stream management in ejabberd

我正在 iOS 上构建一个使用 ejabberd 的即时通讯应用程序。我目前正在测试流管理功能,尤其是在大多数情况下似乎都有效的恢复功能。但是有一种情况我不明白,我可以通过以下步骤进行复制,同时考虑到设置:resume_timeout: 30, resend_on_timeout: if_offline

<message xmlns="jabber:client" from="clientB@mydomain" to="clientA@mydomain/resourceID" type="error" id="CFBF4583-209A-4453-2567-CCCC7894827E">
   <body>test</body>
   <active xmlns="http://jabber.org/protocol/chatstates" />
   <request xmlns="urn:xmpp:receipts" />
   <error code="503" type="cancel">
       <service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
   </error>
</message>

我试过使用 ejabberd 16.01。

80% 的时间都会发生这种情况;有时 A 发送的消息会在 30 秒内重新连接时正确传递给 B。

我的问题是:

  • Stream Management acks仅表示消息已被您的服务器接收。这并不意味着邮件已被处理或发送到指定地址。即使它被发送到地址,那么该设备仍然可以 return 节错误。
  • 这实际上只是盲目尝试,但在浏览了 ejabberd 代码后,可能会发生以下情况:

    1. clientB@mydomain/ResourceB 断开连接,现在有一个会话正在等待使用 ResourceB.
    2. 恢复
    3. 客户端 B 重新连接,但未恢复(因为它崩溃并丢失了状态)。
    4. 客户端 B 再次绑定资源 ResourceB
    5. 现在服务器必须终止正在等待恢复的休眠会话,因为客户端 B 请求了相同的资源。
    6. 服务器检查是否有其他会话,因为设置为if_offline
    7. 服务器发现有一个会话(新会话),因此选择退回而不是重新发送。

    所以我的理论是 if_offline 只在需要处理未确认消息队列时检查是否还有其他会话,而不是在最初收到消息时检查。

@xnyhps 的回答是正确的,我 fixed 下一个 ejabberd 版本的这个特殊情况。然而,@xnyhps 也是正确的,还有其他极端情况,所以如果你想要可靠的消息传递,你应该使用 XEP-0313。 XEP-0198的主要特点是会话恢复。