我正在开发一个基于xmpp(smack + openfire)的聊天系统。当我尝试发送一些正常消息时,我遇到了一些“额外数据”。在准备消息时,我会执行以下操作:
MyData myObject = new MyData("some text");
Message msg = new Message("a@me", 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()返回MyData对象的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="a@me" from="a@me/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="a@me" from="a@me/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 :(得分: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_NAME
和MyExtension.NAMESPACE
,否则无效。 ProviderManager
无法识别数据包,也无法调用正确的PacketExtensionProvider
。