Search code examples
androidxmppsmack

Smack XMPP connection not connecting over 4G network


I am using the latest Smack library 4.3.1. The XMPP connection is working fine with WiFi but it's not working with 4G network.

Here is my code for creating a connection with XMPP.

 configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword(this.userName, this.password);
        configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        configBuilder.setServiceName(Constants.HOST);
        configBuilder.setPort(Constants.PORT);
        configBuilder.setHost(Constants.HOST);
        configBuilder.setDebuggerEnabled(Isdebugmode);
        configBuilder.setResource(PDCustomer.getResource());
        configBuilder.setSendPresence(true);
        connection = new XMPPTCPConnection(configBuilder.build());
        connection.setPacketReplyTimeout(30000);
        connection.addConnectionListener(XmppConnection.this);
        connection.addAsyncStanzaListener(XmppConnection.this, null);
   try {
            connection.connect();
           connection.login(userName, password);
        } catch (IOException e) {
            printlog("CONNECT IO EXCEPTION:" + e.getMessage());

        } catch (SmackException e) {
            printlog("CONNECT SMACK EXCEPTION:" + e.getMessage());

        } catch (XMPPException e) {
            printlog("CONNECT XMPP EXCEPTION:" + e.getMessage());

        }

Solution

  • I have tested below code in 4G network

    Create new class of XMPPConnection

    public class XMPPConnection implements ConnectionListener, ChatManagerListener, RosterListener, ChatMessageListener, PingFailedListener {
    private static final String TAG = "XMPPConnection";
    
    public static final String HOST = "XX.XX.XXX.XX"; //Replace this value
    public static final int PORT = 5222;
    public static final String SERVICE = "XX.XX.XXX.XX"; //Replace this value
    public static String USERNAME = ""; // Replace this value
    public static String PASSWORD = ""; //Replace this value
    public static String TEST_JID = "android_dummy"; // Only for testing purpose
    
    private static XMPPConnection mInstance = new XMPPConnection();
    
    private AbstractXMPPConnection mConnection;
    
    private ChatManager mChatmanager;
    private Chat mChat;
    
    private Context mContext;
    
    private String mUserName = "";
    private String mPassword = "";
    
    public XMPPConnection() {
    }
    
    public static XMPPConnection getInstance() {
        return mInstance;
    }
    
    //Initialize
    public void init(String userId, String pwd, Context context) throws SmackException.NotConnectedException {
        Log.i("XMPP", "Initializing!");
    
        this.mUserName = userId;
        this.mPassword = pwd;
        this.mContext = context;
    
        if (userId.contains("@")) {
            this.mUserName = userId.split("@")[0];
            Log.i("UserId", this.mUserName);
        }
        XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
        configBuilder.setUsernameAndPassword(mUserName, mPassword);
        configBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        configBuilder.setServiceName(SERVICE);
        configBuilder.setHost(HOST);
        configBuilder.setPort(PORT);
        configBuilder.setResource("");
        //configBuilder.setDebuggerEnabled(true);
        mConnection = new XMPPTCPConnection(configBuilder.build());
    
        PingManager pingManager = PingManager.getInstanceFor(mConnection);
        pingManager.setPingInterval(300); // 2.5 min
        pingManager.registerPingFailedListener(this);
    
        mChatmanager.getInstanceFor(mConnection).addChatListener(this);
        ReconnectionManager.getInstanceFor(mConnection).enableAutomaticReconnection();
    
        mConnection.addConnectionListener(this);
    
        connectConnection(context);
    }
    
    public void connectConnection(final Context context) {
        AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>() {
    
            @Override
            protected Boolean doInBackground(Void... arg0) {
    
                // Create a connection
                try {
                    mConnection.connect();
    
                    if (mConnection != null) {
                        Log.i(TAG, "doInBackground: ServerStatus:Connected= " + mConnection.isConnected());
                        login(context);
                    }
    
                } catch (IOException e) {
                    Log.i(TAG, "doInBackground : ServerStatus : IOException = " + e.getMessage());
                } catch (SmackException e) {
                    Log.i(TAG, "doInBackground : ServerStatus : SmackException = " + e.getMessage());
                } catch (XMPPException e) {
                    Log.i(TAG, "doInBackground : ServerStatus : XMPPException = " + e.getMessage());
                }
    
                return null;
            }
        };
        connectionThread.execute();
    }
    
    public void login(Context context) {
        try {
            Log.i(TAG, "login: USERNAME:" + mUserName + " PASSWORD:" + mPassword);
    
            mConnection.login(mUserName, mPassword);
            if (mConnection.isAuthenticated()) {
                Log.i("LOGIN", "Yey! We're connected to the Xmpp server!");
                sendMessage("", TEST_JID, "", "", "", "android_dummy", "android", "android", context);
            }
    
    
        } catch (XMPPException | SmackException | IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            Log.i(TAG, "Login : Exception = " + e.getMessage());
        }
    }
    
    public void sendMessage(String message, String to, String from, String dattingId, String deviceToken, String senderName, String senderOSName, String opponentOSName, Context context) {
        this.mContext = context;
    
        if (mConnection.isConnected() == true) {
            Log.i(TAG, "sendMsg: Sending Message...");
            // Assume we've created an XMPPConnection name "connection".
            mChatmanager = ChatManager.getInstanceFor(mConnection);
            mChat = mChatmanager.createChat("" + to, this);
    
            // Original code
            try {
                Message msg = new Message();
                // Set message
                msg.setBody(message);
                msg.setType(Message.Type.chat);
                msg.setTo("" + to);
                msg.setFrom("" + from);
    
                Log.i(TAG, "Message to send : " + msg.toXML());
    
                mChat.sendMessage(msg);
            } catch (SmackException.NotConnectedException e) {
                e.printStackTrace();
            }
        } else {
            Log.i(TAG, "sendMsg : Unable to send Message.");
        }
    }
    
    // Disconnect Function
    public void disconnectConnection() {
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (mConnection != null && mConnection.isConnected())
                    mConnection.disconnect();
                mConnection = null;
            }
        }).start();
    }
    
    @Override
    public void processMessage(Chat chat, Message message) {
        if (mConnection.isConnected() && mConnection != null) {
            Log.i(TAG, "Message " + message);
        }
    }
    
    @Override
    public void chatCreated(Chat chat, boolean createdLocally) {
        Log.i(TAG, "chatCreated()");
        chat.addMessageListener(this);
    }
    
    @Override
    public void connected(org.jivesoftware.smack.XMPPConnection connection) {
        Log.i(TAG, "Listener connected = " + connection.getUser());
    }
    
    @Override
    public void authenticated(org.jivesoftware.smack.XMPPConnection connection, boolean resumed) {
        Log.i(TAG, "Listener authenticated = " + connection.getUser());
        Log.i(TAG, "Listener authenticated = resumed : " + resumed);
    }
    
    @Override
    public void connectionClosed() {
        Log.i(TAG, "Listener connectionClosed");
    }
    
    @Override
    public void connectionClosedOnError(Exception e) {
        Log.i(TAG, "Listener connectionClosedOnError = " + e.getMessage());
    }
    
    @Override
    public void reconnectionSuccessful() {
        Log.i(TAG, "Listener reconnectionSuccessful");
        if (mContext != null) {
            sendMessage("", TEST_JID, "", "", "", "android_dummy", "android", "android", mContext);
        }
    }
    
    @Override
    public void reconnectingIn(int seconds) {
        Log.i(TAG, "Listener reconnectingIn = " + seconds);
    }
    
    @Override
    public void reconnectionFailed(Exception e) {
        Log.i(TAG, "Listener reconnectionFailed = " + e.getMessage());
    }
    
    @Override
    public void pingFailed() {
        Log.i(TAG, "Listener pingFailed");
    }
    
    @Override
    public void entriesAdded(Collection<String> addresses) {
    
    }
    
    @Override
    public void entriesUpdated(Collection<String> addresses) {
    
    }
    
    @Override
    public void entriesDeleted(Collection<String> addresses) {
    
    }
    
    @Override
    public void presenceChanged(Presence presence) {
        Log.i(TAG, "presenceChanged: " + presence.getClass().toString());
    }
    

    }

    Now call init() method like,

    // Check XMPP connection
        try {
            XMPPConnection.getInstance().init(USER_JABBERID, USER_JABBER_PASSWORD, HomeActivity.this);
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        }