Използвам 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 lib картографирах всички елементи и това е кодът, който използвам, за да създам и изпратя пакета:
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 lib.
Въпросът ми е какво правя различно от дебъгера Smack? Погледнах кода му и за това, което видях, той също извиква метода toXML() от пакета и добавя ReceiveListener. Идеята ми тук е, след като извикам toXML(), мога да използвам SimpleXML, за да го трансформирам в моя IQ.java, който картографирах и да започна да използвам неговата информация.
РЕДАКТИРАНЕ
Добавяне на повече информация. След като потърсих кода на Smack и как той обработва получения пакет, разбрах, че може би трябва да използвам IQProvider. Така че регистрирах своя IQProvider
ProviderManager.getInstance().addIQProvider("list", "urn:xmpp:archive", new ListIQProvider());
И след това поставих точка на прекъсване на метода parseIQ(XmlPullParser arg0) на моя IQProvider и пакетът всъщност се изпраща на моя доставчик, но все пак има всички тези нулеви елементи. Изгубен съм в момента, защото имам нужда от това, за да продължа да работя, ще продължа да проучвам изходния код на Smack.