2014-06-23 47 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