Comment maintenir une connexion XMPP stable sur Android avec (a) smack?
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?
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
}
}
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.
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();
}
}
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
Dans Smack 4.1, j'utilise ServerPingWithAlarmManager
. Vous pouvez trouver plus de détails sur garder la connexion vivante ramzandroid blog ici.
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();
}
}
}