持久化的XMPP MUC(XEP-45),类似于WhatsApp群聊。

14

根据规范 —

7.14 离开聊天室

为了离开多人聊天室,用户发送一个类型为“unavailable”的出席 stanzas 到它当前所使用的 <room@service/nick> 地址。

例子 80. 用户离开聊天室

<presence
    from='hag66@shakespeare.lit/pda'
    to='coven@chat.shakespeare.lit/thirdwitch'
    type='unavailable'/>
这意味着一旦用户从XMPP服务器断开连接,他就会从服务器端的群组中移除。问题很简单 - 我不想要这种行为;我希望实现与WhatsApp相似的行为,即使用户离线,他仍然是MUC房间的一部分(在服务器端配置为持久性),并且将接收其他用户的消息。

考虑到XEP-0045和XMPPFramework for iOS的规范和文档,我不知道如何实现这个功能,也不确定是否能在传统的ejabberd服务器上实现。


现在还有一个更新的XEP(0369),可以满足您的要求:http://xmpp.org/extensions/xep-0369.html - JC Brand
4个回答

9

XEP-45是10多年前设计的,当时设计者考虑了类似IRC频道的东西。XEP-45的所有设计都基于这样一个假设:用户在启动/终止客户端时进入和离开聊天室。

WhatsApp群聊不同:用户加入群聊并能查看该聊天的完整历史记录。即使用户的客户端离线/不可用,他仍被视为群聊的一部分。

XMPP社区目前正在研究一种新的XEP,提供此类功能。它被称为XEP-0369: Mediated Information eXchange。它是XEP-0045的精神继承者,提供现代群聊所期望的功能。


5
您可以使用MUC的服务器端历史记录(消息存档管理,XEP-0313)来模拟这样的情况,这样当客户端登录时,他们就能够请求他们不在其中时的MUC历史记录。
如果您还想显示房间的离线伪占用者,最简单的方法可能是为每个房间映射一个pubsub节点,以存储这些伪占用者的列表,客户端可以读取该列表来补充普通的占用者列表。
这里可能还有其他解决方案,但我立刻想到的是改变服务器的行为方式,以非标准的方式允许普通占用者查询成员身份列表,而这通常只有管理员才能做到。

谢谢Kev。实施自定义解决方案还存在其他问题。消息归档很好,但通知呢?除非离线用户实际打开应用程序,否则他们将永远不会收到来自服务器的任何消息。进一步思考后,我是否可以只使用PubSub作为我的模型,而不是传统的MUC? - p0lAris
你可以在pubsub的基础上重建MUC,但这需要大量的工作。你也可以保持会话活动并从服务器获取通知。不幸的是,目前还没有标准化,但在今年2月的XMPP峰会上有很多关于实现这一机制的讨论,并且正在制定规范。 - Kev
好的。既然我们手头时间不多,那么这个想法就不可行了。但是按照实际建议——在iOS中如何无限期地保持xmpp会话?我知道有人已经回答过类似的问题,但我不确定我是否理解正确。 - p0lAris
@Kev,XEP的当前状态是否有可用的地方?它的名称是什么? - Flow

5

WhatsApp的模型比您想象的简单得多 - 即使用户断开连接,他们仍会维护用户会话在线,并在他“重新连接”会话时重新发送消息。 XEP-0198引入了类似的概念传统XMPP会话。 您只需要配置更长的不活动时间(通常XEP-0198假设为300秒,但类似于WhatsApp的即时通讯应用程序保持会话24小时以上)


感谢vitalyster。"WhatsApp模型比你想象的简单得多-即使用户断开连接,他们仍然在线维护用户会话,并在重新“附加”会话时重新发送消息。"这是在服务器端吗?如果是这样,他们可能正在使用“可用”状态覆盖“不可用”状态。就XEP-0198而言,我不确定如何在iOS应用程序的上下文中实现它。 - p0lAris
例如,如果您基本上终止iOS应用程序 - 您的流将断开连接。 - p0lAris
如果您终止iOS应用程序,则流将被断开,但会话仍然处于活动状态,它们只是忽略TCP断开连接,而不是存在。因为您仍然可以从状态菜单下线并离开群聊。而且使用XEP-0198也是一样的。 - vitalyster
1
我刚刚在网上搜寻了一下,现在已经看了流管理 XEP 0198,但我仍然不清楚 WhatsApp 如何实现它或者你是如何实现的。如果流被断开,我该如何在 iOS 上保持会话活动?例如一个简单的网络问题或用户手动终止应用程序。您能否用简单的伪代码说明我应该如何在客户端启用此功能。这将非常有帮助。 - p0lAris
1
而保持会话“活跃” - 这是在服务器端完成的,而不是客户端。 - vitalyster
显示剩余2条评论

1

您可以通过以下方式设置配置来使您的组持久化:

NSString *var = [field attributeStringValueForName:@"var"];
if ([var isEqualToString:@"muc#roomconfig_persistentroom"])
{
    [field removeChildAtIndex:0];
    [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
}

1
请问您能否分享演示文稿? - Janak Thakkar

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