【问题标题】:XMPPFramework - Retrieve Archived Messages From Openfire ServerXMPPFramework - 从 Openfire 服务器检索存档消息
【发布时间】:2012-07-08 23:26:25
【问题描述】:

我正在使用 XMPP 和 openfire 服务器为 iPhone 开发一个聊天应用程序,OpenFire 服务器正在存储用户之间的所有聊天历史记录,但是当我尝试检索特定用户的聊天历史记录时,我只得到日期和聊天次数消息,但不是实际的短信

我已经安装了用于在 openfire 上存档消息的开放存档插件

这是我传递给 Openfire Server 的节

    <iq type='get' id='pk1'>
    <list xmlns='urn:xmpp:archive'
    with='piyush@openfire'>
    <set xmlns='http://jabber.org/protocol/rsm'>
    <max>30</max>
    </set>
    </list>
    </iq>

这是我从服务器收到的结果

  <iq type="result" id="pk1" to="vivek@openfire/iphone">
  <list xmlns="urn:xmpp:archive">
  <chat with="piyush@openfire" start="2012-07-04T13:16:12.291Z"/>
  <chat with="piyush@openfire" start="2012-07-05T08:25:31.555Z"/>
  <chat with="piyush@openfire" start="2012-07-05T12:38:24.098Z"/>
  <set xmlns="http://jabber.org/protocol/rsm">
  <first index="0">15</first>
  <last>25</last>
  <count>3</count>
  </set>
  </list>
  </iq>

这是我想要的也是我期望的结果

 <iq type='result' to='vivek@openfire/iphone' id='page1'>
 <chat xmlns='urn:xmpp:archive'
    with='piyush@openfire'
    start='2012-07-04T13:16:12.291Z'
    subject='She speaks!'
    version='4'>
<from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
<to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
.
[98 more messages]
.
<from secs='9'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
<set xmlns='http://jabber.org/protocol/rsm'>
  <first index='0'>0</first>
  <last>99</last>
  <count>217</count>
</set>

请帮助我得到想要的结果

谢谢

【问题讨论】:

  • 我认为这更像是一个 OpenFire API 问题而不是 iOS 问题。
  • 嘿 piyush,我也试图实现同样的目标。但是(请原谅我的无知)我不知道如何将这节发送到 openfire 服务器。是否有 api 调用?你介意详细说明一下
  • @Piyush Kashyap 你是如何启用聊天记录的,因为我已经安装了monitoring 插件,但是当我在节上方触发时,它返回未实现的功能
  • 请看一下:stackoverflow.com/a/29097289/2225439希望对您有所帮助。
  • @KeithOYS,兄弟你能帮我解决这个问题stackoverflow.com/questions/44172852/… 吗?

标签: ios xmpp openfire xmppframework


【解决方案1】:

在 Swift 4 中获取归档消息的示例

声明并初始化变量 XMPPMessageArchivingCoreDataStorage 我在其中初始化 XMPPStream

var xmppMessageStorage: XMPPMessageArchivingCoreDataStorage?
var xmppMessageArchiving: XMPPMessageArchiving?

xmppMessageStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
    xmppMessageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppMessageStorage)

    xmppMessageArchiving?.clientSideMessageArchivingOnly = true
    xmppMessageArchiving?.activate(stream)
    xmppMessageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)

这样做,每当消息到达时,这将导致它被归档而无需执行任何其他操作。

然后,检索归档的消息

func RecibedMessageArchiving(idFriend: String) {

        let JabberIDFriend = idFriend   //id friend chat, example test1@example.com


        let moc = xmppMessageStorage?.mainThreadManagedObjectContext
        let entityDescription = NSEntityDescription.entity(forEntityName: "XMPPMessageArchiving_Message_CoreDataObject", in: moc!)
        let request = NSFetchRequest<NSFetchRequestResult>()
        let predicateFormat = "bareJidStr like %@ "
        let predicate = NSPredicate(format: predicateFormat, JabberIDFriend)

        request.predicate = predicate
        request.entity = entityDescription

        //jabberID id del usuario, cliente
        var jabberIDCliente = ""
        if let jabberj = globalChat.value(forKey: "jabberID"){
            jabberIDCliente = jabberj as! String
        }


        do {
            let results = try moc?.fetch(request)

            for message: XMPPMessageArchiving_Message_CoreDataObject? in results as? [XMPPMessageArchiving_Message_CoreDataObject?] ?? [] {

                var element: DDXMLElement!
                do {
                    element = try DDXMLElement(xmlString: (message as AnyObject).messageStr)
                } catch _ {
                    element = nil
                }

                let body: String
                let sender: String
                let date: NSDate
                let isIncomings: Bool

【讨论】:

    【解决方案2】:

    从 openfire 服务器获取存档消息的 Swift 版本 要求:

    func getArchieveMessages(){
            let iQ = DDXMLElement.elementWithName("iq")
            iQ.addAttributeWithName("type", stringValue: "get")
            iQ.addAttributeWithName("id", stringValue: "page1")
            let list = DDXMLElement.elementWithName("retrieve")
            list.addAttributeWithName("xmlns", stringValue: "urn:xmpp:archive")
            list.addAttributeWithName("with", stringValue: "partner@domain")
            let set = DDXMLElement.elementWithName("set")
            set.addAttributeWithName("xmlns", stringValue: "http://jabber.org/protocol/rsm")
            let max = DDXMLElement.elementWithName("max")
            max.addAttributeWithName("xmlns", stringValue: "http://jabber.org/protocol/rsm")
            //(max as! DDXMLElement).setStringValue("30")
            (set as! DDXMLElement).addChild(max as! DDXMLNode)
            list.addChild(set as! DDXMLNode)
            iQ.addChild(list as! DDXMLNode)
            xmppStream.sendElement(iQ as! DDXMLElement)
        }
    

    回复:

    func xmppStream(sender: XMPPStream!, didReceiveIQ iq: XMPPIQ!) -> Bool {
            let chat = iq.elementForName("chat")
            let chats = (chat as DDXMLElement).children()
            for chat in chats{
                let msg = chat
                let body = (msg as! DDXMLElement).elementForName("body")
                if body != nil{
                    if body.stringValue() != nil{
                        //print(body.stringValue()!)
                        chatMessages.append(body.stringValue()!)
                        if msg.attributeForName("jid") == nil{
                            type.append("Send")
                        }
                        else{
                            type.append("Receive")
                        }
                    }
                }
            }
            print("Did receive IQ")
            return false
        }
    

    *with 是您要获取其存档消息的人的 jid

    【讨论】:

      【解决方案3】:

      首先,要从 openfire 检索聊天记录,您需要安装 Open Archive 插件,因为监控插件仅用于在管理面板上监控和记录聊天记录,因此一旦您安装 Open Archive,您将不会收到代码“500”的任何错误.

      您可以从以下链接下载并学习安装 Open Archive。

      https://nexus.reucon.com/content/repositories/opensource-snapshots/com/reucon/openfire/plugins/archive/

      https://maven.reucon.com/projects/public/archive/

      上面代码中的另一个问题是,当您在请求中提到开始标记时,它会与具有确切时间戳的聊天匹配,这就是它返回错误代码“404”的原因。我从我的请求中省略了开始标记并编写了以下代码,该代码返回与用户的整个聊天历史记录。

      NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
      [iq1 addAttributeWithName:@"type" stringValue:@"get"];
      [iq1 addAttributeWithName:@"id" stringValue:@"pk1"];
      
      NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve" xmlns:@"urn:xmpp:archive"];
      
      [retrieve addAttributeWithName:@"with" stringValue:@"rahul@vishals-mac-pro.local"];
      NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
      NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];
      
      [iq1 addChild:retrieve];
      [retrieve addChild:set];
      [set addChild:max];
      [[[self appDelegate] xmppStream] sendElement:iq1]; 
      

      这将返回用户 Rahul 和当前登录用户之间的 XML 响应中的整个聊天历史记录。

      更多详细信息请参考此博客http://question.ikende.com/question/363439343236313430

      【讨论】:

        【解决方案4】:

        您必须向&lt;retrieve&gt; 发出请求(请参阅http://xmpp.org/extensions/xep-0136.html),然后您可以从收到的&lt;list&gt; 结果中获取特定时间。例如:

        发送:

            <iq type='get' id='pk1'>
               <list xmlns='urn:xmpp:archive'
                       with='piyush@openfire'>
                <set xmlns='http://jabber.org/protocol/rsm'>
                    <max>30</max>
                </set>
              </list>
           </iq>
        

        接收:

         <iq type="result" id="pk1" to="vivek@openfire/iphone">
             <list xmlns="urn:xmpp:archive">
              <chat with="piyush@openfire" start="2012-07-04T13:16:12.291Z"/>
              <chat with="piyush@openfire" start="2012-07-05T08:25:31.555Z"/>
              <chat with="piyush@openfire" start="2012-07-05T12:38:24.098Z"/>
              <set xmlns="http://jabber.org/protocol/rsm">
                  <first index="0">15</first>
                   <last>25</last>
                   <count>3</count>
              </set>
            </list>
         </iq>            
        

        现在您选择starts 之一并发送(日期和时间必须准确):

          <iq type='get' id='pk1'>
            <retrieve xmlns='urn:xmpp:archive'
                with='piyush@openfire''
                start='2012-07-04T13:16:12.291Z'>
             <set xmlns='http://jabber.org/protocol/rsm'>
               <max>100</max>
             </set>
            </retrieve>
         </iq>
        

        您将收到类似这样的信息(取决于最大值 -> max=30,body=30):

           <iq type='result' to='vivek@openfire/iphone' id='page1'>
              <chat xmlns='urn:xmpp:archive'
                     with='piyush@openfire'
                      start='2012-07-04T13:16:12.291Z'
                    subject='She speaks!'
               version='4'>
                 <from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
                 <to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
                  .
                  [28 more messages]
                  .
                 <from secs='9'><body>How cam'st thou hither, tell me, and therefore?           </body>   
                 </from>
              <set xmlns='http://jabber.org/protocol/rsm'>
               <first index='0'>0</first>
               <last>29</last>
               <count></count>
             </set>
          <iq>
        

        【讨论】:

        • 是用户ID(JabberID)
        • 不,这里的 pk1 是发送 iq 节的 unique_id。如果您使用某种 xmpp 客户端 api,则可以忽略它,因为该 api(如果支持)将处理 id 的设置。
        • 我们可以在 XMPP 服务器端存储聊天记录吗?
        • 是否支持MUC。 (即)获取 MUC 归档消息
        • @DRMA,你能帮我解决这个问题stackoverflow.com/questions/44172852/… 吗?
        【解决方案5】:

        获取聊天的具体时间

        发送它以获取时间:

         NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
         [iq1 addAttributeWithName:@"type" stringValue:@"get"];
         [iq1 addAttributeWithName:@"id" stringValue:@"pk1"];
         NSXMLElement *retrieve = [NSXMLElement elementWithName:@"list" xmlns:@"urn:xmpp:archive"];
         [retrieve addAttributeWithName:@"with" stringValue:@"amit@openfire"];
         NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
         NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];
         [iq1 addChild:retrieve];
         [retrieve addChild:set];
        
        
         [set addChild:max];
        
        
         [xmppStream sendElement:iq1];
        

        检索聊天记录

        使用开始日期并发送:

         NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
         [iq1 addAttributeWithName:@"type" stringValue:@"get"];
         [iq1 addAttributeWithName:@"id" stringValue:@"pk1"];
        
         NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve" xmlns:@"urn:xmpp:archive"];
         [retrieve addAttributeWithName:@"with" stringValue:@"amit@openfire"];
         [retrieve addAttributeWithName:@"start" stringValue:@"2013-11-18T05:11:53.460Z"];
         NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
         NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];
         [iq1 addChild:retrieve];
         [retrieve addChild:set];
         [set addChild:max];
         [xmppStream sendElement:iq1];
        

        【讨论】:

        • @Amit Gupta 是的,我也被困在这里。请告诉我这里的pk1是什么?
        • 如果我执行上面的代码,那么 xmppstream 委托方法,即 didReceiveMessage 将调用,但我没有得到任何结果,我正在使用开火,所以我可以在我的服务器上做任何技巧,请帮助我。
        • 我收到错误 500,功能未实现错误,该怎么办??
        • Pk1 是自定义 id 名称。您可以使用任何您想要的 id 名称。没有问题。
        • 我收到错误 503 服务不可用。我正在使用 OpenFire。你能告诉我它的原因吗?详情请查看:stackoverflow.com/questions/35935397/…
        猜你喜欢
        • 2012-12-19
        • 2018-05-10
        • 1970-01-01
        • 2013-02-16
        • 2012-12-26
        • 1970-01-01
        • 2013-10-27
        • 1970-01-01
        相关资源
        最近更新 更多