И опять всем суток, очень недавно создавал
вопрос о том, что smack криво работает.
Там я писал: «Еще раз напомню, что первая проблема самостоятельно существует от второй, они как-то связанны.», я ошибся, прошлый раз видимо не все отключил, каюсь :-) Если отключить все свои расширения — smack работает как надо.
Еще раз напомню перефразированную проблему (под катом):
Есть самописные кастомы (
extensions), я регистрирую его для соединения, добавляю слушатель, обрабатываю, опять же, все бы ничего — но это работает через раз.
Как я понял, это ошибка моя, неверное в использование парсинга, в следствии чего падает общий парсинг пакетов. Но почему такое происходит, я так и не понял.
Создание, регистрация, слушание расширения выглядит так:
Инициализация и кидание слушателя:
ProviderManager pm = ProviderManager.getInstance();
pm.addExtensionProvider(TestEvent.elementname, TestEvent.namespace, new TestEvent.Provider());
...
OnlineListener onlineListener = new OnlineListener();
PacketExtensionFilter onlineFilter = new PacketExtensionFilter(TestEvent.namespace);
connection.addPacketListener(onlineListener, onlineFilter);
Реализация
OnlineListener:
public static class OnlineListener implements PacketListener
{
@Override
public void processPacket(Packet packet)
{
TestEvent e = (TestEvent) packet.getExtension(TestEvent.namespace);
Message message = new Message();
message.setTo(e.getUser().aid + "@" + SERVER);
OnlineEvent response = new OnlineEvent();
message.addExtension(response);
connection.sendPacket(message);
}
Реализация расширения:
public class TestEvent implements PacketExtension {
private UserRepresentation user;
public static String namespace = "sometext:event:testevent";
public static String elementname = "event";
public ProfileviewEvent()
{
}
public void setUser(UserRepresentation value) {
user = value;
}
public UserRepresentation getUser() {
return user;
}
public String getElementName() {
return ProfileviewEvent.elementname;
}
public String getNamespace() {
return ProfileviewEvent.namespace;
}
public String toXML() {
StringBuffer buf = new StringBuffer();
buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append("\">");
if(user != null) buf.append(user.toXML());
buf.append("</").append(getElementName()).append(">");
return buf.toString();
}
public static class Provider implements PacketExtensionProvider
{
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
TestEvent extension = new TestEvent();
boolean done = false;
while(!done) {
int eventType = parser.next();
breakpoint(parser.getName()); // ###
if(eventType == XmlPullParser.START_TAG) {
if(parser.getName().equals("User"))
{
UserRepresentation user = new UserRepresentation();
...
extension.setUser(user);
done = true;
}
}
}
return extension;
}
}
}
Мало того, что такой способ ломает глобальный парсер (в прошлом вопросе — ломает MUC), так еще в breakpoint летят теги, которые не относятся к расширению вообще; может они там и должны быть, но мне показалось это нелогичным, т.к. я передаю пространство имен и название тега, вроде бы, теги должны быть в парсере Provider только те, которые я ему и передал (зарегистрировал).
________
P.S. можно и не вешать слушатели на коннектор, достаточно просто зарегистрировать расширение:
pm.addExtensionProvider(TestEvent.elementname, TestEvent.namespace, new TestEvent.Provider());
Как он ломает глобальный парсер (не ложит, но заставляет криво работать), такое ощущение, что он игнорирует тегнейм и пространство имен.
Я уже эту проблему не могу решить второй день :(