Comment maintenir une connexion XMPP stable sur Android avec (a) smack?

<!-J'utilise la bibliothèque asmack-android-7-beem pour Android. J'ai un service d'arrière-plan en cours d'exécution, comme mon appli reste en vie. Mais tôt ou tard, la connexion XMPP meurt sans préavis. Le serveur dit que le client est toujours en ligne mais aucun paquet n'est envoyé ou reçu.

par exemple le client ne reçoit pas de paquets de présence lorsque les autres clients ont une nouvelle présence. J'ai XMPPConnection comme attibute de ma classe D'Application principale.

J'ai mis ConnectionConfiguration config.setReconnectionAllowed(true) avant le la connexion a été établie.

Mais la reconnexion ne se produit pas. XMPPConnection connection.isConnected() renvoie la valeur true.

ainsi le client n'est pas conscient que la connexion est réellement perdue.

Est-il possible de garder la connexion?

24
demandé sur andlrc 2012-10-26 08:01:15

6 réponses

lorsque vous utilisez asmack mettez un code comme celui-ci dans votre application pour que Dalvik charge la classe ReconnectionManager et exécute son bloc d'initialisation statique:

static {
    try {
        Class.forName("org.jivesoftware.smack.ReconnectionManager");
    } catch (ClassNotFoundException ex) {
        // problem loading reconnection manager
    }
}
12
répondu bradlaronde 2014-08-21 04:59:45

en fait, il n'y a pas de problème avec le Gestionnaire de Reconnection. Vous devez d'abord ajouter écoute de connexion à votre gestionnaire de connexion.

connection.addConnectionListener(new ConnectionListener() {

                    @Override
                    public void reconnectionSuccessful() {
                        Log.i("","Successfully reconnected to the XMPP server.");

                    }

                    @Override
                    public void reconnectionFailed(Exception arg0) {
                        Log.i("","Failed to reconnect to the XMPP server.");
                    }

                    @Override
                    public void reconnectingIn(int seconds) {
                        Log.i("","Reconnecting in " + seconds + " seconds.");
                    }

                    @Override
                    public void connectionClosedOnError(Exception arg0) {
                        Log.i("","Connection to XMPP server was lost.");
                    }

                    @Override
                    public void connectionClosed() {
                        Log.i("","XMPP connection was closed.");

                    }
                }); 

si une erreur se produit, le connectionClosedOnError (Exception arg0) sera automatiquement appelé lorsque la connexion est fermée

 public void connectionClosed() {
                        Log.i("","XMPP connection was closed.");
                        //You can manually call reconnection code if you                  want to reconnect on any connection close
                    }

puis vérifiez que cela va appeler la méthode reconnectingin () et essayer de se reconnecter.

espérons que cela vous aidera.

utiliser le code ci-dessous pour vérifier la connexion PingManager pingManager = PingManager.getInstanceFor(connection); pingManager.setPingInterval(5000);

ajouter listner pour la gestion des pannes ping pour gérer la connexion est connecté ou non parce que la méthode isConnected n'est pas fiable pour vérifier l'état de connexion.

pingManager.registerPingFailedListener(PingFailedListener);

pour la connectivité réseau mobile est un très gros problème donc vous devez vérifier la connectivité réseau pour mobile en utilisant récepteur de diffusion et sur la reconnection des données vous pouvez utiliser la méthode pingMyServer pour vérifier la connexion est vivante ou non, si vous recevez réponse ping du serveur, signifie la connexion est vivante sinon sur ping fail vous pouvez reconnecter la connexion manuellement.

8
répondu Mandeep 2016-01-04 12:10:59

Voici mon code fonctionne très bien pour ReconnectionManager

1) Ajouter addConnectionListener sur xmpp connexion

XMPPConnectionListener mConnectionListener = new XMPPConnectionListener(username);
connection.addConnectionListener(mConnectionListener);

2) si la connexion est fermée, reconnectez-vous automatiquement en utilisant ReconnectionManager classe

 ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
 reconnectionManager.enableAutomaticReconnection();
 reconnectionManager.setEnabledPerDefault(true);

3)ConnectionListener pour reconnecter, connecter et authentifier sur le serveur. si la connexion authentifiée avec succès avec le serveur enregistre aussi PingManager et ServerPingWithAlarmManager classe.

public class XMPPConnectionListener implements ConnectionListener {
    String username="";
    public XMPPConnectionListener(String username){
        this.username=username;
    }
    @Override
    public void connected(final XMPPConnection connectionObeject) {

        sendPresenceAvailable();
        Log.d(TAG, "xmpp Connected()");
        connected = true;

    }

    @Override
    public void connectionClosed() {

        Log.d(TAG, "xmpp ConnectionCLosed()");

        isAuthenticatedPreviouly=false;
        connected = false;

        loggedin = false;

    }

    @Override
    public void connectionClosedOnError(Exception arg0) {
        Log.d(TAG, "xmpp ConnectionClosedOnError() :"+System.currentTimeMillis());

        isAuthenticatedPreviouly=false;
        connected = false;

        loggedin = false;
    }

    @Override
    public void reconnectingIn(int arg0) {
        Log.d(TAG, "xmpp reconnectingIn() :"+System.currentTimeMillis());

        loggedin = false;
    }

    @Override
    public void reconnectionFailed(Exception arg0) {
        Log.d(TAG, "xmpp ReconnectionFailed!");
        connected = false;

       // chat_created = false;
        loggedin = false;
        try {
            connection.connect();
        } catch (SmackException | IOException | XMPPException | InterruptedException exception) {
            exception.printStackTrace();
        }
    }

    @Override
    public void reconnectionSuccessful() {
        Log.d(TAG, "xmpp ReconnectionSuccessful");
        connected = true;
        sendPresenceAvailable();
        loggedin = false;
    }

    @Override
    public void authenticated(XMPPConnection connection2, boolean resumed) {

        Log.d(TAG, "xmpp Type Main Authenticated() :" + connection.isAuthenticated());

        if(connection.isAuthenticated()) {

            ServerPingWithAlarmManager.getInstanceFor(connection).setEnabled(true);

            PingManager pingManager = PingManager.getInstanceFor(connection);
            pingManager.setPingInterval(10);

            try {
                pingManager.pingMyServer();
                pingManager.pingMyServer(true,10);
                pingManager.pingServerIfNecessary();
                pingManager.registerPingFailedListener(new PingFailedListener() {
                    @Override
                    public void pingFailed() {
                        Log.d("Ping","pingFailed");
                        disconnect();
                        connect();
                    }
                });

            registerAllListener();
     }
}
3
répondu Sagar Jethva 2017-12-02 07:51:48

j'ai le même problème, sauf que mon programme tourne en JVM côté serveur.

J'ai utilisé smack 4.0 en premier lieu. Puis j'ai mis à jour sur smack 4.1, mais le problème est toujours arrivé. Enfin j'ai trouvé un module de configuration:PingManager

Après avoir utilisé ceci, l'occurrence de cette situation a été réduite.

    connection = new XMPPTCPConnection(config);     
    PingManager pingManager = PingManager.getInstanceFor(connection);
    pingManager.setPingInterval(300); // seconds
2
répondu crazytomcat 2015-07-20 06:41:18

Dans Smack 4.1, j'utilise ServerPingWithAlarmManager. Vous pouvez trouver plus de détails sur garder la connexion vivante ramzandroid blog ici.

1
répondu taynguyen 2016-05-20 18:15:26

dans ce cas, vous devez gérer la déconnexion manuellement.je veux dire que vous devez intercepter toute déconnexion, l'auditeur de connexion averti quand vous avez une déconnexion terminée.

public void connectionClosedOnError (Exception)

    import android.util.Log;

    import com.dagm8.core.protocols.ConnectionState;
    import com.dagm8.core.service.XMPPService;
    import com.dagm8.events.ConnectionStateEvent;

    import org.greenrobot.eventbus.EventBus;
    import org.jivesoftware.smack.ConnectionListener;
    import org.jivesoftware.smack.SmackException;
    import org.jivesoftware.smack.XMPPConnection;
    import org.jivesoftware.smack.XMPPException;
    import org.jivesoftware.smack.tcp.XMPPTCPConnection;

    import java.io.IOException;

    import static com.dagm8.core.protocols.ConnectionState.CONNECTED;
    import static com.dagm8.core.protocols.ConnectionState.DISCONNECTED;
    import static com.dagm8.core.protocols.ConnectionState.RECONNECTING;

    /**
     * dagm8-android
     * Created by Bedoy on 8/28/17.
     */

    public class ConnectionController implements ConnectionListener {

        private String TAG = getClass().getCanonicalName();

        private XMPPTCPConnection mConnection;

        public void setConnection(XMPPTCPConnection connection) {
            mConnection = connection;
        }

        public void init(XMPPTCPConnection connection) throws InterruptedException, XMPPException, SmackException, IOException {

            setConnection(connection);

            mConnection.setPacketReplyTimeout(10000);
            mConnection.addConnectionListener(this);
            mConnection.connect();
        }

        @Override
        public void connected(XMPPConnection connection) {
            XMPPService.connectionState = RECONNECTING;

            notifyConnectionState(RECONNECTING);

            try {
                mConnection.login();
            } catch (XMPPException | SmackException | IOException | InterruptedException e) {
                e.printStackTrace();
            }

            Log.i(TAG, "connected()");
        }


        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) {
            XMPPService.connectionState = CONNECTED;

            notifyConnectionState(CONNECTED);

            Log.i(TAG, "authenticated()");
        }

        @Override
        public void connectionClosed() {
            XMPPService.connectionState = DISCONNECTED;

            notifyConnectionState(DISCONNECTED);

            Log.i(TAG, "connectionClosed()");
        }

        @Override
        public void connectionClosedOnError(Exception e) {
            XMPPService.connectionState = DISCONNECTED;

            notifyConnectionState(DISCONNECTED);


            try {
                mConnection.connect();
            } catch (SmackException | IOException | XMPPException | InterruptedException exception) {
                exception.printStackTrace();
            }
            Log.i(TAG, "connectionClosedOnError()");
        }

        @Override
        public void reconnectingIn(int seconds) {
            XMPPService.connectionState = RECONNECTING;

            notifyConnectionState(RECONNECTING);

            Log.i(TAG, "reconnectingIn()");
        }

        @Override
        public void reconnectionSuccessful() {
            XMPPService.connectionState = CONNECTED;

            notifyConnectionState(CONNECTED);

            Log.i(TAG, "reconnectionSuccessful()");
        }

        @Override
        public void reconnectionFailed(Exception e) {
            XMPPService.connectionState = DISCONNECTED;

            notifyConnectionState(DISCONNECTED);

            Log.i(TAG, "reconnectionFailed()");
        }


        private void notifyConnectionState(ConnectionState state) {
            EventBus.getDefault().post((ConnectionStateEvent) () -> state);
        }

        public boolean isAuthenticated()
        {
            return mConnection.isAuthenticated();
        }

        public void login() {
            try {
                mConnection.login();
            } catch (XMPPException | SmackException | IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
0
répondu Carlos Bedoy 2017-09-14 23:26:02