在多用户聊天中(ejabberd),向离线用户发送消息

9

实际上,我们为客户的聊天应用程序使用ejabberd服务器。除了群组聊天之外,一切都运作良好。

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

或者,有人可以建议如何从群组聊天历史记录中接收该用户的离线消息。

提前感谢。


1
@EelLee,实际上,对于那些相当熟悉XMPP规范及其扩展的人来说,这个问题并不含糊。;-) - kostix
可能是[持久化XMPP MUC(XEP-45),类似于WhatsApp群聊]的重复问题(https://dev59.com/e18e5IYBdhLWcg3wNIJp) - Flow
3个回答

13
那是因为多用户聊天室没有这样的概念。事实上,如果你再想一想,你就会明白为什么:
- 任何时候房间里都可能有无限数量的参与者。 - 那么对于那些当前不在 MUC 房间中的用户,服务器应该将消息存储在离线存储中吗?我是说,在通用情况下,服务器并不知道所有可能在其托管的给定房间中聊天的用户。 - (好吧,如果这是唯一的问题,它可能适用于仅成员的房间,我必须承认。) - MUC 房间并非“仅限本地服务器”:来自任意数量其他服务器的潜在无限数量的用户可能加入房间,并通过它们各自的服务器路由将消息传递给这些用户。 - 显然,这是“MUC 房间离线存储”的另一个没有意义的原因。 - MUC 房间根据定义是短暂的:当用户离线时,他们不在任何房间中——重新加入房间是一种明确的操作。 - 这实际上是不支持离线存储的最重要原因。

正如您所看到的,XMPP MUC聊天室非常像增强版IRC聊天。

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

还有另一个可能性可以探索:"多播寻址",它属于XEP-0033("扩展数据包寻址")。 基本上,它允许客户端使用特殊的多播服务将其消息同时发送给多个收件人。 优点是再次具有离线存储功能。 缺点是我怀疑ejabberd默认情况下是否支持这样的多播服务,并且似乎该扩展留下了许多关于如何实现它的细节未指定。


谢谢Kostix,我已经检查了多播并且很有意义。我正在考虑将Roster组和Multicast组合在一起。我们已经从Android尝试过它,并且它运行良好,因为我们通过每个单独的客户端接收了离线消息。我发现的唯一问题是在iOS上。有人可以指导我吗?我还想知道是否可以发送属性或其他东西,以便我们可以定义接收到的消息是针对特定组的。 - user2609447
只是为了更好地说明我的想法。我们不想在XMPP服务器上存储任何历史记录。我看到的另一个选项是PUBSUB。但我不知道还有什么其他建议。 - user2609447
@user2609447,我不太明白你的意思:离线存储(与多播一起使用时,用于某些目标用户离线时)和发布/订阅确实都会在服务器上存储信息——这是很合理的,对吧?那么MUC历史记录真正与这种消息存储有何不同呢? - kostix
Kostix,我同意关于存储的事情。实际上,我们正在尝试构建类似于WhatsApp的群聊。问题是,如果用户离线并重新上线,我们需要使用户重新加入MUC组,然后我们才能获取该组的历史记录,但我们只能从一开始就获取历史记录。我不知道我是否清楚地解释了我的意思。 - user2609447
@user2609447,顺便说一下,如果你需要消息的保证传递,XMPP不是一个好选择——它可能对于常规点对点消息有所作用(如果两个对等方都同意使用消息回执),但我认为对于多播消息来说情况会更糟。不确定AMP是否能在这里提供帮助。 - kostix
显示剩余3条评论

3
我曾经面临过与您同样的问题,即在我的聊天应用程序中实现群聊时,MUC无法为每个收件人存储离线消息。我不想检索MUC历史记录,因为这需要用户重新加入每个MUC以更新他的消息数据库。我希望服务器能够按收件人保存离线消息,并在收件人上线时获取所有MUC消息(而无需加入每个MUC)。
我使用pubsub来解决这个问题。使用pubsub将强制服务器为每个收件人存储离线消息。当用户重新连接时,他会收到所有离线消息,包括作为普通消息发送的pubsub消息。我使用pubsub时遇到的一个问题是很难获取订阅者列表。因此,当我的应用程序创建群聊时,它会为消息创建一个pubsub节点,邀请所有参与者(包括自己)订阅该pubsub,我的应用程序还会创建一个MUC,并使每个参与者成为该MUC的所有者。这样可以通过检查MUC的所有者列表来检索群聊参与者的列表。 MUC的唯一目的是保存参与者列表和群聊名称。其他所有内容都由pubsub节点处理。
如果有任何不清楚的地方,请告诉我。
附加细节: 实际上,当用户想要创建群聊时,我们的应用程序会创建一个pubsub节点和一个MUC。您需要熟悉这两个概念。对于pubsub节点,您需要设置一个选项以允许任何订阅者发布。当用户发送消息时,他实际上是在节点上发布,ejabberd将像普通消息一样将消息发送给所有订阅者(除了它来自pubsub.yourdomain.com)。因此,如果收件人离线,ejabberd将像处理其他常规消息一样存储此消息。
这不是ejabberd处理MUC消息的方式。那些只发送给当前在聊天室中的人。ejabberd可以存储消息历史记录,但是为了使收件人获取历史记录,他需要加入MUC。这意味着每次应用程序重新连接时,它都必须加入所有用户现有的MUC。我们发现这不切实际。
我们还使用MUC进行相同的群聊,但这仅用于存储参与者,以便用户随时可以获取列表(无法使用pubsub)。
使用pubsub而不是MUC的另一个好处是ejabberd存储pubsub数据的方式更有效率。我没有深入研究过这一点,但我预计pubsub会有更好的性能表现。

看起来你在实际中没有使用MUC,也不理解pubsub背后的逻辑。 - DivineDesert
Georges,感谢您提供详细的说明!我们公司正在寻找同样的解决方案,以接收来自MUC的所有离线消息。您能否提供一些配置创建群聊和发布订阅节点的应用程序的示例? - Murz
嘿,乔治,请与我们分享一下,你如何使用pubsub节点获取群聊的离线消息。这将对所有遇到此问题的人都有所帮助。 - Arbaz Shaikh
@Georges:“基本上,当用户想要创建一个群聊时,我们的应用程序会创建一个发布订阅节点以及一个MUC。”。您能否友好地展示一些执行此操作的代码?谢谢。 - Sreekumar Kalarikkal
@SreekumarKalarikkal:你可以参考 Smack(Android)和 XMPPFramework(iOS)的文档。它们都包含了完成所有这些操作的框架。 - Georges
显示剩余3条评论

1

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

MUC Sub的目标是尽可能依赖现有的MUC规范,同时尽可能少地进行更改,以使移动群组会话客户端易于使用。

该功能默认启用。要使用它,请确保在要使用它的房间中设置新参数“Allow subscription”。

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

更多信息请查看: https://blog.process-one.net/xmpp-mobile-groupchat-introducing-muc-subscription/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接