ForhaxeD
@ForhaxeD

Java: smack xmpp очень странно работает?

Всем суток.


Появилась необходимость написать jabber-бота (client) для одного небольшого изолированного сервера.

Java был выбран потому, что его можно запустить под linux'ом, в языке, к сожалению, я пока плаваю.


Но это мне не помешало написать этого самого бота в самые короткие сроки, в качестве xmpp-прослойки был выбрал Smack API.


О самой проблеме — детально и под катом, вкратце: обработчик рендомно обрабатывает пакеты.



Делаю все как обычно (код упрощен, но ничего другого там нет, что могло бы влиять на работу):

ConnectionConfiguration configuration = new ConnectionConfiguration(SERVER);
configuration.setSASLAuthenticationEnabled(true);

XMPPConnection connection = new XMPPConnection(configuration);
connection.connect();
connection.login(LOGIN, PASSWORD, "systembot");

MultiUserChat muc = new MultiUserChat(connection, TEST_ROOM + "@conference." + SERVER);
muc .join(NICKNAME);

BotChatListener chatListener = new BotChatListener();
muc .addMessageListener(chatListener);



Реализация BotChatListener (находится в том же классе):

public static class BotChatListener implements PacketListener
	{
		@Override
		public void processPacket(Packet packet)
		{
			Process(packet);
		}
		
	}



Подключение проходит успешно, заход в комнату тоже и тут начинается самое интересное, сообщения он принимает, отдает в Process, но тут есть вероятность, не любое сообщение попадает в Process (пытался методом тыка понять, как работает эта вероятность) и после бессонной ночи, бессмысленных правок и изобретений велосипеда — понял, это рендом и ошибка (вероятнее всего) где-то в smack или в моей неправильной конфигурации (ошибка в коде?). Более того, он может принять пакет, может пройти N-ое время и только тогда пакет попадет в Process.


Смотрел в стандартном debug от smack, пакет muc'a попадает в принятые пакеты, а потом, через некоторое время, в Interpreted; если он туда попадает, то Process срабатывает, если нет — последний не срабатывает, то его и в Interpreted тоже нет и он теряется (где?), файлы smack'а я не правил, использую версию 3.2.1.


Кстати, чуть не забыл, висит еще кастомный слушатель на самом connection (его отключаю, проблема с muc остается такой же проблемой, т.е. зависит это не от этого):


Инициализация и кидание слушателя:
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();
                if(eventType == XmlPullParser.START_TAG) {
                    if(parser.getName().equals("User")) 
                    {
                    	UserRepresentation user = new UserRepresentation();
                    	
                    	...
                		
                    	extension.setUser(user);
                        done = true;
                    }
                }
            }
            return extension;
        } 
    }
}



Так вот, с этим тоже происходят необычные вещи, он отвечает на сообщение с extension (может и с обычным тоже) — 50 на 50. Есть мнение, что он так же, либо попадает в Interpreted, либо нет.


Еще раз напомню, что первая проблема самостоятельно существует от второй, они как-то связанны.


_________

Поисковик, конечно, ничего не дал или я мало искал.
  • Вопрос задан
  • 3064 просмотра
Решения вопроса 1
ForhaxeD
@ForhaxeD Автор вопроса
Частичное решение: habrahabr.ru/qa/14061/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы