【问题标题】:Delivering messages to offline users in a multi-user chat (ejabberd)在多用户聊天中向离线用户传递消息 (ejabberd)
【发布时间】:2014-04-16 16:00:14
【问题描述】:

实际上,我们正在将 ejabberd 服务器用于我们客户的聊天应用程序之一。除了群聊之外,一切都运行良好。

我们正在使用 MUC 进行群聊,但它不会在使用离线时向成员发送消息。是否有任何替代插件或我们可以使其工作的东西?

或者任何人都可以建议如何从群聊历史中接收该用户的离线消息。

提前致谢

【问题讨论】:

标签: xmpp chat ejabberd


【解决方案1】:

16.09 版本的新 ejabberd 服务器对多用户聊天进行了改进 - MUC Sub:

MUC Sub 的目标是尝试尽可能多地依赖现有的 MUC 规范,同时进行尽可能小的更改,使移动群组对话客户端变得容易。

该功能默认启用。要使用它,只需确保在要使用它的房间中设置新参数“允许订阅”即可。

这里是文档链接:https://docs.ejabberd.im/developer/proposed-extensions/muc-sub/

更多信息在这里:https://blog.process-one.net/xmpp-mobile-groupchat-introducing-muc-subscription/

【讨论】:

    【解决方案2】:

    我在为我的聊天应用程序实施群聊时遇到了您的问题。我遇到了同样的问题,即 MUC 没有为每个收件人存储离线消息。而且我不想检索需要用户重新加入每个 MUC 以更新他的消息数据库的 MUC 历史记录。我想要的是服务器按收件人保存离线消息,并让收件人在他上线时获取所有 MUC 消息(无需加入每个 MUC)。

    我这样做的方式是通过 pubsub。使用 pubsub 将强制服务器为每个收件人存储离线消息。当用户重新连接时,他会得到所有的离线消息,包括作为普通消息发送的 pubsub 消息——就是这样。我在 MUC 上使用 pubsub 时遇到的一个问题是很难获得订阅者列表。因此,当我的应用程序创建群聊时,它会为消息创建一个 pubsub 节点,邀请所有参与者(包括自己)订阅 pubsub,我的应用程序还创建一个 MUC 并使每个参与者成为该 MUC 的所有者。这样,可以通过查看 MUC 的所有者列表来检索群聊参与者的列表。 MUC 的唯一目的是保存参与者列表以及群聊的名称。其他一切都由 pubsub 节点处理。

    有什么不清楚的请告诉我。

    其他细节: 本质上,当用户想要创建群聊时,我们的应用程序会创建一个 pubsub 节点以及一个 MUC。您需要熟悉这两个概念。对于 pubsub 节点,您需要设置一个选项以允许任何订阅者发布。当用户发送消息时,他实际上是在节点上发布,ejabberd 会将消息发送给所有订阅者,就像它是一条常规消息一样(来自 pubsub.yourdomain.com 的消息除外)。因此,如果收件人离线,ejabberd 会将此消息存储为任何其他常规消息。

    这不是 ejabberd 处理 MUC 消息的方式。这些仅发送给当前聊天室中的人。然而,ejabberd 可以存储消息的历史记录,但要让接收者获得历史记录,他需要加入 MUC。这意味着每次应用重新连接时,它都必须加入所有用户现有的 MUC。我们发现这不切实际。

    我们也为同一个群聊使用了一个 MUC,但这只是为了存储参与者,以便用户可以随时获取列表(无法使用 pubsub)。

    在 MUC 上使用 pubsub 的另一个好处是 ejabberd 存储 pubsub 数据的方式更加高效。我没有对此进行深入研究,但我希望 pubsub 的性能更好。

    【讨论】:

    • 看来您并没有真正使用 MUC,也没有得到 pubsub 背后的逻辑。
    • 乔治,感谢您的详细描述!我们公司正在寻找相同的解决方案来接收来自 MUC 的所有离线消息。您能否提供一些示例如何配置创建群聊和 pubsub 节点的应用程序?
    • Hey Georges,请与我们分享,您是如何使用 pubsub 节点获取群聊的离线消息的。这对所有面临问题的人都有好处。
    • @Georges:'基本上,当用户想要创建群聊时,我们的应用程序会创建一个 pubsub 节点以及一个 MUC。'。你会好心地展示一些这样做的代码吗?谢谢。
    • @SreekumarKalarikkal:您可以参考 Smack (Android) 和 XMPPFramework (iOS) 的文档。两者都包含执行所有这些操作的框架。
    【解决方案3】:

    那是因为多用户聊天室没有这样的概念。事实上,如果你多想一下,你就会明白为什么:

    • 在任何给定时间,房间中都可能存在潜在的无限数量的参与者。

      那么,服务器究竟应该为哪些用户当前不存在在 MUC 房间中将消息存储在离线存储中?我的意思是,在一般情况下,服务器并不知道所有可能在它托管的给定房间中聊天的用户。

      (好吧,如果这是唯一的问题,它可能适用于仅限会员的房间,我必须承认。)

    • MUC 房间不是“仅限本地服务器”:来自任何数量的其他服务器的潜在无限数量的用户可能会加入房间,并且将通过各自的服务器路由这些用户来传递给这些用户的消息。

      显然,这也是为什么“MUC机房离线存储”这种想法没有意义的另一个原因。

    • 根据定义,MUC 房间是瞬态的:当用户离线时,他们不在任何房间——(重新)加入房间是一个显式操作。

      这其实是不支持离线存储的最重要原因。

    如您所见,XMPP MUC 房间很像 IRC 聊天室。

    所以你真正想要的是"room history"——XMPP-0045 扩展的一部分,它允许客户端明确地向房间询问他们错过的消息历史记录。从某种意义上说,房间可能被配置为仅存储一定数量的最近发送给它的消息(或给定时间段内的所有此类消息),而不是为每个用户存储离线消息。然后房间支持加入的用户查询这些消息。

    您可能会探索另一种可能性:XEP-0033"multicast addressing"(“扩展节寻址”)。基本上,它允许客户端使用特殊的多播服务将他们的消息一次发送给多个接收者。好处是离线存储再次出现。缺点是我怀疑 ejabberd 开箱即用地支持这样的多播服务,而且似乎该扩展留下了很多关于如何实现未指定的细节。

    【讨论】:

    • 感谢 Kostix,我检查了多播,这很有意义。我在想的是结合名册组和多播。我们已经在 Android 上进行了尝试,它运行良好,因为我们收到了每个客户端的离线消息。我发现的唯一问题是在 iOS 中。有人可以指导我吗?我还想知道我们是否可以发送属性或其他东西,我们可以定义收到的消息是针对特定组的。
    • 只是为了更好地了解我想要什么。我们不想在 XMPP 服务器上存储任何历史记录。我见过的另一个选项是 PUBSUB。但是没有任何想法,或者是否有人可以建议我别的东西。
    • @user2609447,我不太了解你:离线存储(在某些目标用户离线时与多播一起使用)和 pubsub 都在服务器上存储信息——这是合乎逻辑的,对吗? MUC 历史与这种消息存储有何不同?
    • @user2609447,还请注意,我不确定 ejabberd 是否会对脱机消息进行重复数据删除。我的意思是,如果你有 10k 用户在一个房间里聊天,其中 2k 离线并且错过了 1k 条消息,那么房间历史记录将只存储 1k 条消息,而通过多播将这 1k 条消息传递给这 2k 离线用户需要存储 2k× 1k 条消息。当然,现在存储很便宜,但无论如何都值得考虑。
    • Kostix,我同意你关于存储的看法。实际上,我们正在尝试建立类似于 Whatsapp 的群聊。问题是如果用户下线并重新上线,我们需要让用户重新加入 MUC 组,然后我们可以获得该组的历史记录,但我们从一开始就获得历史记录。我不知道我是否说清楚了我要解释的任何内容。
    猜你喜欢
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2023-01-31
    相关资源
    最近更新 更多