iOS:XMPP:获取离线消息

4

场景:


问题:

  • 我发送给离线用户的信息会丢失。
  • 当该用户上线后,他并没有接收到之前未接收到的信息。
  • 在群聊中这个问题不存在,因为如果用户再次加入聊天室,他将默认接收所有信息。
  • 但在一对一聊天中,消息就会丢失。

已经实现了保存所有聊天记录并检索它们的功能。 我正在使用XMPPMessageArchivingXMPPMessageArchivingCoreDataStorage来实现此功能。

如果有人能指点我解决这个问题,那将非常有帮助。


你正在使用哪个XMPP服务器?请确保启用了离线存储。 - vitalyster
你可以分享一下如何保存聊天记录并检索吗? - Md Jahirul Islam
3个回答

7
离线消息是服务器的责任。如何处理离线消息在 XEP-160 中有解释。
在客户端上,您需要确保发送类型为“normal”或“chat”的消息数据包。
您还需要确保在 eJabberd 中启用了离线消息存储。
当您上线后,您可以逐个获取所有离线消息。
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message` 

XMPPMessage将会包含延迟和时间戳标签,如下所示。

<message xmlns="jabber:client" from="demo@demoHost/demoResource" to="you@demoHost" type="chat" id="234E5B61-C450-4F15-B2E6-5AF68AA8D376"><body>offline message test body</body><html xmlns="http://jabber.org/protocol/xhtml-im"><body xmlns="http://www.w3.org/1999/xhtml" style="background-color:#e9e9e9;color:#000000;"><span style="font-family: 'Helvetica';font-size: 12px;">offline message test body</span></body></html><x xmlns="jabber:x:event"><composing></composing></x><active xmlns="http://jabber.org/protocol/chatstates"></active><delay xmlns="urn:xmpp:delay" from="suhailk-imac.local" stamp="2014-09-19T10:41:50Z">Offline Storage</delay><x xmlns="jabber:x:delay" stamp="20140919T10:41:50"></x></message>

我们已经创建了一个用于聊天的应用程序,目前当用户在线时它可以正常工作。但是当用户进入离线模式时,我们遇到了问题。此时,我们需要通过监控服务插件在30秒后从离线消息存档表中获取一条消息。请问这个插件是否有办法帮助我们更快地将消息插入数据库中? - Shashank Shah

2
无论何时用户上线,使用XMPPPresence发送用户的在线状态。一旦ejabberd知道用户存在,它将把所有离线消息发送回给用户。

1

我也尝试从服务器获取所有消息,但无法获取。因此,我使用XMPPMessageArchivingCoreDataStorage和XMPPMessageArchiving检索消息。

首先声明变量。

 private var xmppMessageStorage: XMPPMessageArchivingCoreDataStorage?
 private var stream = XMPPStream()
 private var xmppMessageArchiving: XMPPMessageArchiving?

开始连接时。
// for retrive old chat messages
xmppMessageStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
xmppMessageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppMessageStorage)
xmppMessageArchiving?.clientSideMessageArchivingOnly = true
xmppMessageArchiving?.activate(stream) //By this line all your messages are stored in CoreData
xmppMessageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)

这个方法用于获取特定用户在CoreData中的离线消息。
func getArchieveMessages(forUser user:String){
    
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
    fetchRequest.predicate = NSPredicate(format: "bareJidStr = %@", user)
    let context = xmppMessageStorage?.mainThreadManagedObjectContext
    var messageEntity: NSEntityDescription? = nil
    if let context = context {
      messageEntity = NSEntityDescription.entity(forEntityName: "XMPPMessageArchiving_Message_CoreDataObject", in: context)
    }
    
    fetchRequest.entity = messageEntity
    
    let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]
    var results: [Any]? = []
    do {
      results = try context?.fetch(fetchRequest)
      self.modelController.delegate?.localHistoryMessages(results ?? [])
    } catch let error {
      debugPrint(error.localizedDescription)
    }
    debugPrint(results as Any)
}

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