Project

General

Profile

I receive duplicated message

Ildar Zaripov
Added about 1 year ago

I use Tigase XMPP Server on backend side and Tigase JaXMPP library on mobile app. I faced with strange problem: each sent message is received in duplicate.
I tested app in the following cases:

  1. Communication between Android App (using JaXMPP lib) and PSI:
    • message from Android app => to PSI - everything is OK.
    • message from PSI => to Android app - I receive duplicated message
  2. Communication between 2 Andoird Apps:
    • Android App <=> Android App - each time I receive duplicated message

The code responsible for receiving messages in Android App:

jaxmpp = new Jaxmpp();
 try {
    tigase.jaxmpp.j2se.Presence.initialize(jaxmpp);
 } catch (JaxmppException e) {
    e.printStackTrace();
 }


jaxmpp.getConnectionConfiguration().setServer("host");
jaxmpp.getConnectionConfiguration().setPort(5222);
jaxmpp.getConnectionConfiguration().setUseSASL(true);

jaxmpp.getProperties().setUserProperty(SessionObject.DOMAIN_NAME, "localhost");
jaxmpp.getProperties().setUserProperty(SessionObject.USER_BARE_JID, BareJID.bareJIDInstance("user@localhost"));
jaxmpp.getProperties().setUserProperty(SessionObject.PASSWORD, "password");

jaxmpp.getConnectionConfiguration().setDisableTLS(false);

jaxmpp.getProperties().setUserProperty(SocketConnector.SSL_SOCKET_FACTORY_KEY, sslSocketFactory); // SSLContext - trusts all certificates (for development purposes)


presenceHandler = new PresenceHandler();  

jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactAvailableHandler(presenceHandler);
jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactChangedPresenceHandler(presenceHandler);
jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactUnavailableHandler(presenceHandler);


jaXMPPConnection.getJaxmpp().getModulesManager().register(new MessageModule()); // tigase.jaxmpp.core.client.xmpp.modules.chat.MessageModule
jaXMPPConnection.getJaxmpp()
                .getEventBus()
                .addHandler(MessageModule.MessageReceivedHandler.MessageReceivedEvent.class, new MyMessageReceiver());


public class MyMessageReceiver implements MessageModule.MessageReceivedHandler {

    @Override
    public void onMessageReceived(SessionObject sessionObject, Chat chat, Message stanza) {
      try {
          System.out.println("MESSAGE RECEIVED "+stanza.getBody());
      } catch (XMLException e) {
          e.printStackTrace();
      }
    }

}

private class PresenceHandler implements
            PresenceModule.ContactAvailableHandler,
            PresenceModule.ContactUnavailableHandler,
            PresenceModule.ContactChangedPresenceHandler { ... }

The code responsible for sending messages:

try {
  Message msg = Message.create();
  JID jid = JID.jidInstance("friend@localhost");
  msg.setTo(jid);
  msg.setType(StanzaType.chat);
  msg.setBody("Hi! How are you?");
  msg.setId(UIDGenerator.next());

  MessageModule messageModule = jaxmpp.getModule(MessageModule.class);

  if (jaxmpp.isConnected()) {
     messageModule.sendMessage(msg);
  }

} catch (JaxmppException e) {
  e.printStackTrace();
}

Some XMPP related output log:

I/Jaxmpp: Using SocketConnector
I/SocketConnector: Opening connection to /my_ip:5222
I/SocketConnector: TLS completed javax.net.ssl.HandshakeCompletedEvent[source=SSL socket over Socket[address=/my_ip, port=5222,localPort=60184]]
I/SocketConnector: ZLIB compression started

Maybe you have any ideas about this problem?
Thank you!


Replies (2)

(2)
Avatar?id=6098&size=32x32

Added by Bartosz Małkowski TigaseTeam about 1 year ago

What do you mean by "duplicated message"? That onMessageReceived() is called twice in the same time?

Here is code I tested, and I cannot reproduce your problem :-(

import tigase.jaxmpp.core.client.*;
import tigase.jaxmpp.core.client.exceptions.JaxmppException;
import tigase.jaxmpp.core.client.xml.XMLException;
import tigase.jaxmpp.core.client.xmpp.modules.chat.Chat;
import tigase.jaxmpp.core.client.xmpp.modules.chat.MessageModule;
import tigase.jaxmpp.core.client.xmpp.modules.chat.xep0085.ChatStateExtension;
import tigase.jaxmpp.core.client.xmpp.modules.presence.PresenceModule;
import tigase.jaxmpp.core.client.xmpp.stanzas.Message;
import tigase.jaxmpp.core.client.xmpp.stanzas.Presence;
import tigase.jaxmpp.core.client.xmpp.stanzas.StanzaType;
import tigase.jaxmpp.j2se.Jaxmpp;
import tigase.jaxmpp.j2se.connectors.socket.SocketConnector;

import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Test {

    /**
     * @param args Arguments are important!<br/>
     * <code>userbarejid password testmessagereceiverjid</code><br/>
     * example:<br/>
     * <code>user@localhost secret friend@localhost</code>
     */
    public static void main(String[] args) throws Exception {
        Jaxmpp jaxmpp = new Jaxmpp();
        try {
            tigase.jaxmpp.j2se.Presence.initialize(jaxmpp);
        } catch (JaxmppException e) {
            e.printStackTrace();
        }

        jaxmpp.getConnectionConfiguration().setUserJID(BareJID.bareJIDInstance(args[0]));
        jaxmpp.getConnectionConfiguration().setUserPassword(args[1]);
        jaxmpp.getConnectionConfiguration().setResource("test");
        //      jaxmpp.getConnectionConfiguration().setServer("127.0.0.1");

        final TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }};

        jaxmpp.getProperties().setUserProperty(SocketConnector.TRUST_MANAGERS_KEY, trustManagers);

        PresenceHandler presenceHandler = new PresenceHandler();
        jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactAvailableHandler(presenceHandler);
        jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactChangedPresenceHandler(presenceHandler);
        jaxmpp.getModulesManager().getModule(PresenceModule.class).addContactUnavailableHandler(presenceHandler);

        jaxmpp.getEventBus()
                .addHandler(Connector.StanzaSendingHandler.StanzaSendingEvent.class,
                            (sessionObject, stanza) -> System.out.println("<<< " + stanza.getAsString()));
        jaxmpp.getEventBus()
                .addHandler(Connector.StanzaReceivedHandler.StanzaReceivedEvent.class, (sessionObject, stanza) -> {
                    try {
                        System.out.println(">>> " + stanza.getAsString());
                    } catch (XMLException e) {
                    }
                });

        jaxmpp.getModulesManager().register(new MessageModule());
        jaxmpp.getEventBus()
                .addHandler(MessageModule.MessageReceivedHandler.MessageReceivedEvent.class, new MyMessageReceiver());

        ChatStateExtension cse = new ChatStateExtension(jaxmpp.getModule(MessageModule.class).getChatManager());
        jaxmpp.getModule(MessageModule.class).addExtension(cse);

        jaxmpp.getEventBus()
                .addHandler(ChatStateExtension.ChatStateChangedHandler.ChatStateChangedEvent.class,
                            (sessionObject, chat, state) -> System.out.println("NEW CHAT STATE: " + state));

        jaxmpp.login(true);

        Message msg = Message.create();
        JID jid = JID.jidInstance(args[2]);
        msg.setTo(jid);
        msg.setType(StanzaType.chat);
        msg.setBody("Hi! How are you?");
        msg.setId(UIDGenerator.next());

        MessageModule messageModule = jaxmpp.getModule(MessageModule.class);

        if (jaxmpp.isConnected()) {
            messageModule.sendMessage(msg);
        }

    }

    public static class MyMessageReceiver
            implements MessageModule.MessageReceivedHandler {

        @Override
        public void onMessageReceived(SessionObject sessionObject, Chat chat, Message stanza) {
            try {
                // note that message may not contain body!
                if (stanza.getBody() != null) {
                    System.out.println("MESSAGE RECEIVED WITH BODY: " + stanza.getBody());
                }

            } catch (XMLException e) {
                e.printStackTrace();
            }
        }

    }

    private static class PresenceHandler
            implements PresenceModule.ContactAvailableHandler,
                       PresenceModule.ContactUnavailableHandler,
                       PresenceModule.ContactChangedPresenceHandler {

        @Override
        public void onContactAvailable(SessionObject sessionObject, Presence stanza, JID jid, Presence.Show show,
                                       String status, Integer priority) throws JaxmppException {

        }

        @Override
        public void onContactChangedPresence(SessionObject sessionObject, Presence stanza, JID jid, Presence.Show show,
                                             String status, Integer priority) throws JaxmppException {

        }

        @Override
        public void onContactUnavailable(SessionObject sessionObject, Presence stanza, JID jid, String status) {

        }
    }

}
(1)

Added by Ildar Zaripov about 1 year ago

Thank you very much!
I compared your and my code and found a bug - I registered message module 2 times and this was the reason why onMessageReceived() method was called twice.
Sorry for disturbing you :)

    (1-2/2)