web-dev-qa-db-fra.com

L'utilisation de Socket.IO sur Android renvoie toujours une erreur d'interrogation XHR

J'écris une application Android qui doit se connecter à une instance Socket.IO s'exécutant sur un serveur node.js.

Tenter de se connecter à l'instance et de transmettre des données à l'aide d'un périphérique iOS fonctionne parfaitement, mais cela n'aboutit pas lorsque j'essaie de le faire avec un périphérique Android.

J'utilise le client Java natif , et voici le code que j'utilise côté Android:

mManager = new Manager(new URI("https://example.com"));
mSocket = mManager.socket("/users");

// socket events listeners
    mSocket.on(Socket.EVENT_CONNECTING, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "Caught EVENT_CONNECTING");
            for (Object obj : args) {
                Log.v(TAG, "Errors :: " + obj);
            }
        }
    }).on(Socket.EVENT_CONNECT, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "connected to the backend");
            Log.v(TAG, String.format("JSON Obj to emit: %s", jsonObject.toString()));
            mSocket.emit("hello_packet", jsonObject);
        }
    }).on(Socket.EVENT_RECONNECTING, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "Caught EVENT_RECONNECTING");
            for (Object obj : args) {
                Log.v(TAG, "Errors :: " + obj);
            }
        }
    }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "Socket disconnected");
        }
    }).on(Socket.EVENT_ERROR, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "Caught EVENT_ERROR");
            for (Object obj : args) {
                Log.v(TAG, "Errors :: " + obj);
            }
        }
    }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            Log.v(TAG, "Caught EVENT_CONNECT_ERROR");
            for (Object obj : args) {
                Log.v(TAG, "Errors :: " + obj);
            }
        }
    });

    Log.v(TAG, "Connecting socket");
    mSocket.connect();

Chaque fois que j'essaie de me connecter (essentiellement dès que la ligne mSocket.connect();) s'affiche, le journal imprime les lignes suivantes:

05-07 22:41:36.684 15552-15552/com.my.app V/Main Activity: Connecting socket
05-07 22:41:36.699 15552-15858/com.my.app V/Main Activity: Caught EVENT_CONNECTING
05-07 22:41:36.926 15552-15866/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:36.926 15552-15866/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:38.189 15552-15884/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:38.189 15552-15884/com.my.app V/Main Activity: Errors :: 1
05-07 22:41:38.207 15552-15887/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:38.208 15552-15887/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:39.518 15552-15911/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:39.518 15552-15911/com.my.app V/Main Activity: Errors :: 2
05-07 22:41:39.531 15552-15915/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:39.531 15552-15915/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:41.846 15552-15949/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:41.846 15552-15949/com.my.app V/Main Activity: Errors :: 3
05-07 22:41:41.857 15552-15953/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:41.857 15552-15953/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:46.863 15552-16025/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:46.864 15552-16025/com.my.app V/Main Activity: Errors :: 4
05-07 22:41:46.879 15552-16029/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:46.879 15552-16029/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:51.883 15552-16126/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:51.883 15552-16126/com.my.app V/Main Activity: Errors :: 5
05-07 22:41:51.895 15552-16130/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:51.895 15552-16130/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:41:56.900 15552-16236/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:41:56.900 15552-16236/com.my.app V/Main Activity: Errors :: 6
05-07 22:41:56.921 15552-16240/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:41:56.921 15552-16240/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:01.927 15552-16357/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:01.927 15552-16357/com.my.app V/Main Activity: Errors :: 7
05-07 22:42:01.945 15552-16361/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:01.945 15552-16361/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:06.951 15552-16466/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:06.952 15552-16466/com.my.app V/Main Activity: Errors :: 8
05-07 22:42:06.969 15552-16470/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:06.970 15552-16470/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:11.975 15552-16545/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:11.976 15552-16545/com.my.app V/Main Activity: Errors :: 9
05-07 22:42:11.994 15552-16549/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:11.994 15552-16549/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:17.000 15552-16629/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:17.000 15552-16629/com.my.app V/Main Activity: Errors :: 10
05-07 22:42:17.012 15552-16633/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:17.012 15552-16633/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:22.017 15552-16710/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:22.017 15552-16710/com.my.app V/Main Activity: Errors :: 11
05-07 22:42:22.033 15552-16714/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:22.033 15552-16714/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:27.039 15552-16788/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:27.039 15552-16788/com.my.app V/Main Activity: Errors :: 12
05-07 22:42:27.056 15552-16792/com.my.app V/Main Activity: Caught EVENT_CONNECT_ERROR
05-07 22:42:27.056 15552-16792/com.my.app V/Main Activity: Errors :: io.socket.engineio.client.EngineIOException: xhr poll error
05-07 22:42:32.061 15552-16957/com.my.app V/Main Activity: Caught EVENT_RECONNECTING
05-07 22:42:32.062 15552-16957/com.my.app V/Main Activity: Errors :: 13

Je reçois donc immédiatement une erreur d'interrogation Xhr après une tentative de connexion et toutes les tentatives de connexion suivantes rencontrent le même résultat.

J'ai vu des publications affirmant qu'un tel problème pouvait être causé par un problème de certificat SSL, même si toutes les tentatives que j'ai faites pour tempérer avec le contexte SSL utilisé par la bibliothèque Socket.IO ne fonctionnaient pas.

Si anyoen a une idée de ce que je pourrais peut-être essayer de faire fonctionner cela, ce serait excellent.

Si des informations ou des codes manquent, faites-le moi savoir et je les ajouterai.

11
Mor Paz

Après d'autres tests, j'ai trouvé ce qui suit:

  1. Si vous déboguez votre socket lorsque vous rencontrez différents événements (par exemple, EVENT_ERROR), l’exception que vous intercepterez contiendra le code de réponse reçu à partir de l’adresse que vous avez essayé d’atteindre.
  2. Dans mon cas, lors de la tentative d’atteinte de mon serveur avec HTTP, j’ai reçu un code de réponse 301 car l’URL que j’essayais d’atteindre me redirigeait automatiquement vers l’adresse HTTPS.
  3. Lors de la tentative d’atteinte de l’adresse HTTPS, j’ai reçu un code de réponse 401 - c’est-à-dire que la demande faite par mon socket avait atteint le serveur mais n’était pas autorisée - La raison en était que le serveur cible avait authentification de base activée}, et Je n'ai pas fourni les informations d'identification requises dans les en-têtes de demande de socket.
  4. Après avoir fourni les en-têtes requis, j'ai réussi à me connecter correctement au serveur de sockets, mais lors de l'envoi d'une requête, la requête a échoué et mon socket est revenu à une boucle de tentative de reconnexion. La raison en était que le JSON que j'ai envoyé au serveur mon téléphone Android n'était pas au format attendu et le serveur n'a pas pu recevoir cette demande.

Le code que j'ai utilisé pour ajouter un en-tête d'authentification de base à ma demande de socket:

// Adding authentication headers when encountering EVENT_TRANSPORT
mSocket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        Transport transport = (Transport) args[0];
        // Adding headers when EVENT_REQUEST_HEADERS is called
        transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.v(TAG, "Caught EVENT_REQUEST_HEADERS after EVENT_TRANSPORT, adding headers");
                Map<String, List<String>> mHeaders = (Map<String, List<String>>)args[0];
                mHeaders.put("Authorization", Arrays.asList("Basic bXl1c2VyOm15cGFzczEyMw=="));
            }
        });
    }
});

Si vous rencontrez une erreur d'interrogation XHR lorsque vous essayez d'utiliser Socket.IO, assurez-vous que la connexion à votre serveur de socket est disponible et que vous vous connectez correctement. En fin de compte, dans mon cas, tout tournait autour du serveur nécessitant une authentification de base et je ne le fournissais pas lorsque je contactais le serveur.

Aussi, car j'ai rencontré cette solution un peu en essayant de résoudre ce problème - Lorsque vous essayez de joindre votre serveur via HTTPS, vous avez généralement inutile un vérificateur spécial du nom d'hôte ou spécial. gestionnaire de certificat. Essayez d'éviter ces solutions car elles nuisent grandement à la sécurité de votre application.

6
Mor Paz

j'ai utilisé votre code et j'avais exactement le même résultat, mais votre résolution ne m'a pas résolu le problème. La solution que j'ai trouvée consistait à émettre des données toutes les X secondes. En gros, la connexion était interrompue s'il n'y avait aucune donnée envoyée.

Je n'ai pas eu à faire d'autorisation.

Le code est exactement comme ci-dessus la partie EVENT_TRANSPORT et le EVENT_CONNECT est le suivant:

socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                Log.d("mylogs", "Socket: Web socket opened");

                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {

                        socket.emit("YOUR_TOPIC", "YOUR_DATA_VALUE");

                        handler.postDelayed(this, 1000);
                    }
                };
                handler.post(runnable);

            }
        })

Je voulais juste laisser cela ici, cela pourrait aider quelqu'un dans le futur, croyez-le ou non, c'était un problème difficile à résoudre, "l'erreur de sondage Xhr" est très vague et beaucoup de choses différentes peuvent y conduire. Après avoir essayé tant de choses différentes, ce code simple l'a résolu.

0
Ricardo Abreu