Duplicate messages receiving in android smack 4.1

3.9k views Asked by At

I have been trying to create an android chat app using smack 4.1. Message sending and receiving is working fine, but the problem is same message is getting several times with in the mXmppConnection.addAsyncStanzaListener.I don't know if i have missed to add something to the connection.

This is my connection class:

XMPPTCPConnectionConfiguration.Builder configBuilder = new XMPPTCPConnectionConfiguration.builder();

 configBuilder.setUsernameAndPassword(mUser, "password@123");
configBuilder.setPort(5555);
configBuilder.setServiceName("tvm.myname.com");
configBuilder.setDebuggerEnabled(true);                    configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
try 
{
XMPPTCPConnection mConnection = new XMPPTCPConnection(configBuilder.build());
mConnection.connect();
mConnection.login();
} 
catch (SmackException e) 
{
} 

And this the code where message receives:

mXmppConnection.addAsyncStanzaListener(new StanzaListener() {
 @Override
 public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
 Message message = (Message)packet;  
  Log.i("XMPPClient", "****** message " + message);
  // code for handling message
}                  `enter code here`
},null);

The real problem is i am getting the message several times..the value of message is printing in the logs several time. Please help me....

4

There are 4 answers

2
Nidheesh On BEST ANSWER

FINALLY GOT SOLUTION

The issue is not with the client but due to careless coding. I have been assigning single instance of connection object to a class variable and listener is adding to these reference object every time. So that leads to calling listener multiple times....The fix is done by adding listener to the singleton connection object.

0
raditya gumay On

Just use addSyncStanzaListener instead addAsyncStanzaListener

0
Vinod Makode On

Same problem I have faced but I got the solution, you don't unregistered your BroadcastReceiver when you logout from app below is code of logout and also you make all the connection is singleton.

try {
Presence pr=new Presence(Presence.Type.unavailable);
pr.setStatus(RoosterConnection.getConnection().getUser() + "false");
RoosterConnection.getConnection().sendStanza(pr);
if (mConnection != null) {
mConnection.disconnect();
}
    //  mBus.unregister(this);
    mConnection = null;
// Unregister the message broadcast receiver.
if (uiThreadMessageReceiver != null) {
mApplicationContext.unregisterReceiver(uiThreadMessageReceiver);
uiThreadMessageReceiver = null;
}

Intent intent = new Intent(this,LoginActivity.class);
startActivity(intent);
finish();}catch(SmackException.NotConnectedException e){    e.printStackTrace();}catch(InterruptedException e){
e.printStackTrace();}
1
Nidheesh On

I don't know is there any best approach for keeping the xmpp connection stable through out the application.If anyone knows a better solution please post the answer here. I am using a global connection variable, all the chat operations are done by making use of this static connection variable. This is working for me. For sending and receiving messages using smack we need to make connection with xmpp server.

public static AbstractXMPPConnection getInstance(Context context) {
    mContext = context;
    sendMessageCallBack = (XmppSendMessageCallBack) context;
    if (mConnection == null) {
        mInstance = new XmppClient();
        mUser = new Preferences(context).getPhone();
        setUserToServer();
    }
    return mConnection;
} 


private static void setUserToServer() {

    new Thread(new Runnable() {
        @Override
        public void run() {             
            try {

                Looper.prepare();
                /** connecting  to server ***/
                XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
                configBuilder.setServiceName(Constants.HOST_URL);
                configBuilder.setDebuggerEnabled(true);
                configBuilder.setSendPresence(true);
                configBuilder.setConnectTimeout(XMPPTCPConnectionConfiguration.DEFAULT_CONNECT_TIMEOUT);
                configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
                String[] sslProtocols = {"starttls"
                        , "no_sslv3"
                        , "no_tlsv1"};
                configBuilder.setEnabledSSLProtocols(sslProtocols);

                mConnection = new XMPPTCPConnection(configBuilder.build());
                mConnection.setPacketReplyTimeout(120000);
                mConnection.connect();
                // Log into the server
                if(mConnection!=null) {
                    mConnection.login(mUser, "password@123");

                    reConnectionSetUp();

                    PingManager pingManager = PingManager.getInstanceFor(mConnection);
                    pingManager.setPingInterval(60000);
                    pingManager.pingMyServer();
                    pingManager.registerPingFailedListener(new PingFailedListener() {
                        @Override
                        public void pingFailed() {
                            if (mConnection != null && !mConnection.isConnected())
                                setUserToServer();
                        }
                    });
                    setUpListenersForXmppConnection(mConnection);
                }

            } catch (SmackException.ConnectionException e) {
                Log.e("XmppClient", "ConnectionException :", e);
                Toast.makeText(mContext,"failed to connect to server",Toast.LENGTH_SHORT).show();
            } catch (SmackException.NoResponseException e) {
                Log.e("XmppClient", "NoResponseException :", e);
                Toast.makeText(mContext,"Connection time out please try again",Toast.LENGTH_SHORT).show();
            } catch (XMPPException e) {
                Log.e("XmppClient", "XMPPException :", e);
            }catch (IOException e) {
                Log.e("XmppClient", "IOException :", e);
            }catch (SmackException.NotConnectedException e) {
                Log.e("XmppClient", "NotConnectedException :", e);
                reConnectionSetUp();
            }catch (SmackException e) {
                Log.e("XmppClient", "SmackException :", e);
            }catch (NullPointerException e) {
                Log.e("XmppClient", "NullPointerException :", e);
            }
        }

    }).start();
}


 private static void setUpListenersForXmppConnection(AbstractXMPPConnection xmppConnection){
    try {
        if(xmppConnection!=null) {

            sendOnlineStatus();

            /** adding connection listener **/
            xmppConnection.addConnectionListener(mInstance);

            /** adding privacy manager to connection  **/
            if(xmppConnection!=null)
                mPrivacyListManager = PrivacyListManager.getInstanceFor(xmppConnection);
            /** adding packet listener for receving incoming packets **/
            StanzaFilter filter = MessageTypeFilter.NORMAL;

            if(xmppConnection!=null && mInstance!=null)
                xmppConnection.addSyncStanzaListener(mInstance, null);                            

        }
    } catch (SmackException e) {
        Log.e("XmppClient", "IOException :", e);
    } catch (XMPPException e) {
        Log.e("XmppClient", "XMPPException :", e);
        e.printStackTrace();
    } catch (NullPointerException e) {
        Log.e("XmppClient", "NullPointerException :", e);
    } catch (ConcurrentModificationException e){
        Log.e("XmppClient", "ConcurrentModificationException :", e);
    } catch (IllegalArgumentException e){
        e.printStackTrace();
    }catch (RetrofitError e){
        Log.e("XmppClient", "RetrofitError :", e);
    }

}

When we receive a message the following method will be invoked

   @Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {

    if(packet instanceof Message) {
        Message message = (Message) packet;
        // Do your task

    }
}

We can send message by creating a message object of smack like this,

  Message message = new Message();
    message.setFrom(senderId);
    message.setBody(body);
    message.setSubject(subject);
    message.setTo(receiverId);

 try {
        if(mConnection!=null){
            ChatManager chatManager = ChatManager.getInstanceFor(mConnection);
            if(chatManager!=null){
                chatManager.createChat(message.getTo(), new ChatStateListener() {
                    @Override
                    public void stateChanged(Chat chat, ChatState state) {
                        Log.e("XMPPClient", "******* stateChanged "+state);
                    }
                    @Override
                    public void processMessage(Chat chat, Message message) {
                        Log.e("XMPPClient", "******* processMessage "+message.getSubject());
                    }
                }).sendMessage(message);
            }
        }
        sendMessageCallBack.messageSuccessfullySend(message.getStanzaId(), status);

    }catch (SmackException.NotConnectedException e){
        Log.e("XMPPClient", "******* NotConnectedException ", e);
        sendMessageCallBack.messageSendingFailed("");

    }catch(NullPointerException e){
        Log.e("XMPPClient", "******* NullPointerException ", e);
        sendMessageCallBack.messageSendingFailed("");
    }catch (Exception e){
        sendMessageCallBack.messageSendingFailed("No Network");
    }