Я использую aSmack в своем приложении для Android для связи с моим сервером XMPP, и я включил отладку для Smack, чтобы видеть все входящие/исходящие XML. Моя проблема здесь в том, что я использую PacketListener для получения ответа сервера для пакета, который я отправил, но когда я вызываю метод toXML() пакета, я получаю странный вывод.
Классы и более подробная информация ниже.
На моем сервере есть реализация XEP-0136, и, поскольку у aSmack еще нет кода для него, я создаю пакет IQ и отправляю его, и он работает, как и ожидалось, как вы можете видеть ниже в моем XML-пакете, разработанном в XEP-0136, получение списка коллекций ( http://xmpp.org/extensions/xep-0136.html#manage-list )
Xml-пакет отправлен на сервер
06-13 14:11:21.769: D/SMACK(3018): 02:11:21 PM SENT (1079273464):
<iq id="[email protected]/Smack/Conversations" type="get">
<list with="[email protected]" xmlns="urn:xmpp:archive">
<set xmlns="http://jabber.org/protocol/rsm">
<max>30</max>
</set>
</list>
</iq>
Чтобы создать этот XML, я получил файлы схемы XML, разработанные в XEP-0136, и с помощью библиотеки SimpleXML я сопоставил все элементы, и это код, который я использую для создания и отправки пакета:
XMPPService.java
private static final int MAX_LIST = 30;
public void getConversations(String email, BaseActivity activity)
{
if (isAuthenticated())
{
String packetId = connection.getUser() + "/Conversations";
Set set = new Set();
set.setMax(MAX_LIST);
List list = new List();
list.setWith(email);
list.setSet(set);
final IQ iq = new IQ();
iq.setList(list);
iq.setType(IQType.get);
iq.setId(packetId);
PacketIDFilter filter = new PacketIDFilter(packetId);
connection.addPacketListener(new ChatListListener(activity), filter);
sendPacket(iq);
}
}
public void sendPacket(IQ iq)
{
if (isAuthenticated())
{
connection.sendPacket(new IQPacket(iq));
}
}
IQPacket.java
public class IQPacket extends Packet {
private IQ iq;
public IQPacket(IQ iq)
{
this.iq = iq;
}
public IQPacket(Packet packet, IQ iq)
{
super(packet);
this.iq = iq;
}
@Override
public String toXML()
{
StringWriter writer = new StringWriter();
Serializer serializer = new Persister();
try
{
serializer.write(iq, writer);
return writer.getBuffer().toString();
} catch (Exception e)
{
Log.e("COMPANY", "Error serializing xml", e);
}
return null;
}
}
Как я уже сказал, эта часть работает, моя проблема заключается в прослушивателе, когда я вызываю метод toXML() для полученного пакета, я не могу получить важную информацию о чатах, но вывод отладки Smack выводит мне все информация, которую я ожидаю, как вы можете видеть ниже:
Smack Debug для полученного XML
06-13 14:11:21.989: D/SMACK(3018): 02:11:21 PM RCV (1079273464):
<iq type="result" id="[email protected]/Smack/Conversations" to="[email protected]/Smack">
<list xmlns="urn:xmpp:archive">
<chat with="[email protected]" start="2013-06-10T13:19:25.000Z"/>
<chat with="[email protected]" start="2013-06-10T13:36:50.876Z"/>
<set xmlns="http://jabber.org/protocol/rsm">
<first index="0">2</first>
<last>3</last>
<count>9</count>
</set>
</list>
</iq>
Кроме того, этот XML является ожидаемым ответом, так как все эти элементы отображаются как JavaBeans, но это то, что я получаю, когда получаю пакет в своем ChatListener и вызываю метод toXML():
06-13 14:11:22.009: I/System.out(3018):
<iq id="[email protected]/Smack/Conversations" to="[email protected]/Smack" type="result">nullnullnullnullnullnull2nullnull3nullnull9nullnull</iq>
ChatListListener.java
public class ChatListListener implements PacketListener {
private BaseActivity activity;
public ChatListListener(BaseActivity activity)
{
this.activity = activity;
}
@Override
public void processPacket(Packet packet)
{
activity.notifyPacketReceived();
System.out.println(packet.toXML());
}
}
Пакет взят из org.jivesoftware.smack.packet.Packet, поэтому это пакет по умолчанию из библиотеки aSmack.
Итак, мой вопрос: чем я отличаюсь от отладчика Smack? Я посмотрел его код и увидел, что он также вызывает метод toXML() из пакета и добавляет ReceiveListener. Моя идея заключается в том, что после вызова toXML() я могу использовать SimpleXML для преобразования его в свой IQ.java, который я сопоставил, и начать использовать его информацию.
ИЗМЕНИТЬ
Добавление дополнительной информации. Итак, после просмотра кода Smack и того, как он обрабатывает полученный пакет, я понял, что, возможно, мне следует использовать IQProvider. Итак, я зарегистрировал свой IQProvider
ProviderManager.getInstance().addIQProvider("list", "urn:xmpp:archive", new ListIQProvider());
И после этого я ставлю точку останова на метод parseIQ(XmlPullParser arg0) моего IQProvider, и пакет действительно отправляется моему провайдеру, но все равно содержит все эти нулевые элементы. Я сейчас немного растерялся, потому что мне нужно, чтобы это продолжало работать, я буду продолжать исследовать исходный код Smack.