XMPP aSmack - How can I listen on my own user state (Online/Offline) to Reconnect

241 Views Asked by At

I am new to xmpp/asmack in android, i'm looking for a method to listen on my own user state and presence changes on the server.

My target it's restore connection if lost.

I'm using presence by roster, which helps me getting the friends presence but actually not the current user itself.

Any help would be appreciated :)

Best regards,

3

There are 3 best solutions below

0
MrPk On BEST ANSWER

You have to enable a ReconectionManager.

Example:

    XmppManager.config = XMPPTCPConnectionConfiguration.builder()
            .setServiceName(serverName)
            .setHost(server)
            .setPort(port)
            .build();

    connection = new XMPPTCPConnection(config);

ConnectionListener connectionListener = new ConnectionListener(){...}; //
connection.addConnectionListener( connectionListener );

int RECONNECTION_ATTEMPT_SECONDS  = 60;

ReconnectionManager.getInstanceFor(connection).enableAutomaticReconnection();
ReconnectionManager.getInstanceFor(connection).setFixedDelay( RECONNECTION_ATTEMPT_SECONDS );

ReconnectionListener looks like this:

   public class ReconnectionListener implements ConnectionListener
    {   

        @Override
        public void reconnectionSuccessful()
        {
            System.out.println( "Connection to chat server restored - You are again online" );

    //additional foo when connection restored
        }

        @Override
        public void reconnectionFailed( Exception e )
        {
            System.out.println("Impossible to reconnect, Chat Server seems to be still unavailable" );

        }

        @Override
        public void reconnectingIn( int seconds )
        {
            System.out.println( "reconnectingIn fired "+seconds);
        }

        @Override
        public void connectionClosedOnError( Exception e )
        {
            System.out.println("Connection closed, Chat Server become unavailable" );
    //additional  foo when connection lost (message to user ?)
        }

        @Override
        public void connectionClosed()
        {
            // "XMPP connection was closed.");
            System.out.println( "Connection closed, Chat Server become unavailable");
        }

        @Override
        public void connected( XMPPConnection connection )
        {
            System.out.println("connected fired - reconnection management enabled");
        }

        @Override
        public void authenticated( XMPPConnection connection, boolean resumed )
        {
            System.out.println("authenticated fired");      
        }

    }

If that helped, please don't forget to accept the answer :)

0
Kevin Chen On

To realize the automatic reconnection, you should utilize the ReconnectionManager, and implement the interface ConnectionListener to get the notification.

Details can be refered in https://ramzandroidarchive.wordpress.com/2016/03/14/handling-connection-break-issue-in-smack-4-1/

0
Z. Mei On

There exist another way to reconnect by using a timer:

public class TaxiConnectionListener implements ConnectionListener {
    private Timer tExit;
    private String username;
    private String password;
    private int logintime = 2000;
    @Override
    public void connectionClosed() {
        Log.i("TaxiConnectionListener", "disconnect");
        XmppConnection.getInstance().closeConnection();
        tExit = new Timer();
        tExit.schedule(new timetask(), logintime);
    }
    @Override
    public void connectionClosedOnError(Exception e) {
        Log.i("TaxiConnectionListener", "failed to disconnect");
        boolean error = e.getMessage().equals("stream:error (conflict)");
        if (!error) {
            XmppConnection.getInstance().closeConnection();
            tExit = new Timer();
            tExit.schedule(new timetask(), logintime);
        }
    }
    class timetask extends TimerTask {
        @Override
        public void run() {
            username = Utils.getInstance().getSharedPreferences("taxicall",
                    "account", MainActivity.context);
            password = Utils.getInstance().getSharedPreferences("taxicall",
                    "password", MainActivity.context);
            if (username != null && password != null) {
                Log.i("TaxiConnectionListener", "logining");
                if (XmppConnection.getInstance().login(username, password)) {
                    Log.i("TaxiConnectionListener", "logined");
                } else {
                    Log.i("TaxiConnectionListener", "reconnect");
                    tExit.schedule(new timetask(), logintime);
                }
            }
        }
    }
    @Override
    public void reconnectingIn(int arg0) {
    }
    @Override
    public void reconnectionFailed(Exception arg0) {
    }
    @Override
    public void reconnectionSuccessful() {
    }
}

You need add a connection listener in your logining method:

TaxiConnectionListener connectionListener = new TaxiConnectionListener();
getConnection().addConnectionListener(connectionListener);

Remove listener in disconnection method:

 connection.removeConnectionListener(connectionListener);