2014-06-23 51 views
2

我正在開發基於xmpp(smack + openfire)的聊天系統。當我嘗試發送一些常規消息以及一些「額外數據」時,我遇到了問題。當製備該消息本人執行以下操作:XMPP Smack - 正在修改的消息

MyData myObject = new MyData("some text"); 

Message msg = new Message("[email protected]", Message.Type.chat); 

DefaultPacketExtension dpe = new DefaultPacketExtension("packetName", "http://namespace.stuff"); 
dpe.setValue("dataTag", myObject.toXMLString()); 

msg.addExtension(dpe); 
msg.setBody("Hello World!"); 

的myObject.toXmlString()返回邁德特對象的XML表示(使用DOM4J)。 在此之後我繼續與此消息的發送:

Chat personalChat = chatmanager.createChat(msg.getTo(),new MessageListener() { 
     @Override 
     public void processMessage(Chat chat, Message message) { 
      System.out.println("MESSAGE RECEIVED:"); 
      System.out.println("From: "+message.getFrom()); 
      System.out.println(message); 
     } 
}); 

personalChat.sendMessage(msg); 

調試客戶端報告以下消息。

出消息:

<message id="Fx5bQ-4" to="[email protected]" from="[email protected]/Smack" type="chat"> 
    <body>Hello World!</body> 
    <thread>ef9632e3-6d27-4fea-a5c8-b3f7c85052d8</thread> 
    <packetName xmlns="http://namespace.stuff"> 
     <dataTag> 
      <myData xmlns:me="namespace"> 
       <name>some text</name> 
       <points>0</points> 
       <res>0</res> 
       <contract/> 
       <bonuses/> 
       <position>0</position> 
       <secret/> 
      </myData> 
     </dataTag> 
    </packetName> 
</message> 

在消息:

<message id="Fx5bQ-4" to="[email protected]" from="[email protected]/Smack" type="chat"> 
    <body>Hello World!</body> 
    <thread>ef9632e3-6d27-4fea-a5c8-b3f7c85052d8</thread> 
    <packetName xmlns="http://namespace.stuff"> 
      <bonuses/> 
      <name>some text</name> 
      <res>0</res> 
      <contract/> 
      <position>0</position> 
      <secret/> 
      <points>0</points> 
    </packetName> 
</message> 

正如你可以看到出現了一些數據的 「損失」。實際上,「dataTag」和「myData」只是作爲傳出消息的一部分記錄下來,但不會出現在傳入消息中!這是否意味着(性能的東西......「無用」發送「空」節點)或者是否有openfire設置有問題?

這只是一個小例子......在真實項目中,我在傳出消息中有1000多行「myData」對象,而在傳入消息中,大多數行都丟失了(比如90%的packetExtension是丟失了,不僅僅是xml的「空」節點)!

+0

你在使用什麼服務器?這是您正在使用的實際XML,還是嘗試生成示例?例如,你的'xmlns:me'命名空間聲明並沒有被實際使用。 –

回答

2

原因是你缺少一個特定的packetExtensionProvider,因此當你的數據包到達DefaultPacketExtensionProvider無法正確解析它。事實上,這個DefaultPacketExtensionProvider非常簡單,只能解析1級孩子左右的簡單XML。

對於你的情況,你需要定義是這樣的:

class MyExtensionProvider implements PacketExtensionProvider{ 
    @Override 
    public PacketExtension parseExtension(XmlPullParser parser)throws Exception { 
     LOGGER.info("[parseExtension] Executing parseExtension()"); 

     DefaultPacketExtension extension = new DefaultPacketExtension(MyExtension.ELEMENT_NAME,MyExtension.NAMESPACE); 

     boolean done = false; 

     int eventType = parser.getEventType(); 

     while (!done) { 
      System.out.println(parser.getText()); 

      if (eventType == XmlPullParser.START_TAG) { 

       String name = parser.getName(); 
       System.out.println(name); 

       // If an empty element, set the value with the empty string. 
       if (parser.isEmptyElementTag()) { 
        extension.setValue(name,""); 
       }else { 
        eventType = parser.next(); 
        if (eventType == XmlPullParser.TEXT) { 
         String value = parser.getText(); 
         System.out.println(value); 
         extension.setValue(name, value); 
         done=true; 
        } 
       } 
      } 

      eventType = parser.next(); 
     } 
     return extension; 
    } 
} 

這是所以你要定義自己的一個簡單的。然後,你需要註冊您的供應商:

ProviderManager providerManager = ProviderManager.getInstance();  
    providerManager.addExtensionProvider(MyExtension.ELEMENT_NAME, MyExtension.NAMESPACE,new MyExtensionProvider()); 

記住:當你發送郵件它必須有MyExtension.ELEMENT_NAMEMyExtension.NAMESPACE設置是否正確,否則將無法正常工作。 ProviderManager將不會識別該數據包,並且不會調用正確的PacketExtensionProvider