XMPP Smack 聊天应用程序中的多设备支持
Posted
技术标签:
【中文标题】XMPP Smack 聊天应用程序中的多设备支持【英文标题】:Multi Device support in XMPP Smack Chat Application 【发布时间】:2015-07-20 11:16:28 【问题描述】:我正在开发 android 聊天应用程序。
我的要求是将消息传递到多个设备。
考虑两个用户用户 A 和用户 B 之间的这种情况:
User A logs in and sends message to User B.
User B logs in from Device 1 and receives message from User A.
User B logs in from Device 2 but does not get message from User A.
根据我的要求,用户 B 也应该从设备 2 中的用户 A 那里收到消息。
我怎样才能做到这一点?
谢谢。
【问题讨论】:
【参考方案1】:在 XMPP 中,消息只能一次性传递:
在线资源共享最高优先级, 到通过离线消息传递连接的第一个客户端。但是,如果您希望其他客户端重新同步,则应依赖 XEP-0313: Message Archive Management。该规范描述了客户端如何访问消息历史记录并重新同步其状态。
您可以例如query the message archive for all messages after a given time。这将允许连接的客户端获取自上次在线以来错过的所有消息:
<iq type='set' id='juliet1'>
<query xmlns='urn:xmpp:mam:0'>
<x xmlns='jabber:x:data'>
<field var='FORM_TYPE'>
<value>urn:xmpp:mam:0</value>
</field>
<field var='start'>
<value>2010-08-07T00:00:00Z</value>
</field>
</x>
</query>
</iq>
【讨论】:
如果你能给我一些例子,那将非常有帮助。谢谢 一些什么例子? XEP 已经包含有关如何启用查询消息存档的示例节。例如,您可以按时间:xmpp.org/extensions/xep-0313.html#filter-time 不确定我还能提供什么,因为您可以清楚地询问自上次收到的所有消息。编辑消息以更明确地说明如何在设备连接上重新同步消息。 我正在使用 Smack API 库与 ejabberd SaaS 进行通信,但我无法找到如何通过 Smack 获取消息存档。您提到的链接仅解释协议。 我从未使用过 Smack,但如果您认真对待 XMPP 开发,您需要知道这在协议级别是如何发生的。我的拙见是没有办法解决的。【参考方案2】:除了 Mickael 的回答之外,您还应该注意一些事项。如果您将完整的 JID 指定为您的 to 地址,则消息将仅传递到该单个端点。
只有在以下情况下才会将消息传递给同一用户的多个资源:
to 地址是裸 JID 所有连接具有相同的优先级 服务器配置为传送到多个端点。最后一点至关重要。根据规范,服务器可以通过两种方式处理发送到裸 JID 的消息。
发送到具有最高优先级的连接之一。哪个是由服务器决定的,它可以是第一个连接的,最后一个,或者如果有多个具有相同优先级的连接,则随机选择。 发送到所有优先级最高的连接。因此,除非您知道您的服务器支持并配置为允许第二选择,否则无论如何您都无法完成您正在尝试做的事情。
【讨论】:
【参考方案3】:为了参与即时消息和在线活动,客户端(即设备)应在服务器上建立会话。
如XMPP Documentation中所述
如果已经有同名的活动资源,则服务器 必须 (1) 终止活动资源并允许 新请求的会话,或 (2) 禁止新请求的会话 并维护活动资源。服务器执行哪些操作已启动 到实施,尽管建议实施案例#1。在第 1 种情况下,服务器应该向活动资源发送流错误,终止 XML 流和底层 TCP 活动资源的连接,并返回类型为 IQ 节 “结果”(表示成功)到新请求的会话。在情况 #2 中,服务器应该向新请求的会话发送一个节错误,但为此维护 XML 流 连接,以便新请求的会话有机会 在发送另一个资源标识符之前协商一个不冲突的资源标识符 请求建立会话。
(https://www.rfc-editor.org/rfc/rfc6120#section-7.7.2.2)
因此,您应该首先根据应用要求决定处理会话的方式。 现在,由于您使用的是 Ejabberd,您可以通过定义选项 resource_conflict 来配置它
但是,如果您仍想使用多个会话,您可以使用消息存档管理 - XEP-0313
因此您可以将聊天记录存储在服务器上,然后再检索。这可以在 ejabberd 中使用选项mod_mam进行配置
【讨论】:
以上是关于XMPP Smack 聊天应用程序中的多设备支持的主要内容,如果未能解决你的问题,请参考以下文章
使用 Openfire 服务器和 XMPP(SMACK)客户端的 Android 聊天应用程序 [关闭]
Android 基于XMPP Smack openfire 开发的聊天室
Android XMPP 聊天单刻度线以及如何从日志中读取 h 值