27 votes

Demandes POST de Socket.io à partir de Socket.IO-Client-Swift

J'exécute socket.io sur un serveur Apache via Python Flask. Nous l'intégrons dans une application iOS (à l'aide de l'application Socket.IO-Client-Swift ) et nous avons un problème étrange.

À partir du code côté client de l'application (écrit en Swift), je peux afficher le journal des connexions (côté client dans XCode) et voir la connexion établie à partir de l'IP du client et les demandes effectuées. Le client ne reçoit jamais l'information en retour (ou toute information en retour ; même en utilisant un gestionnaire de réponse d'événement global) du serveur de socket.

J'ai écrit un test très simple script en Javascript sur une page HTML et envoyé des requêtes de cette façon et reçu les réponses appropriées en retour. Cela dit, il semble que ce soit probablement un problème avec iOS. J'ai trouvé ces articles (mais aucun d'entre eux n'a aidé à résoudre le problème) :

https://github.com/nuclearace/Socket.IO-Client-Swift/issues/95 https://github.com/socketio/socket.io-client-swift/issues/359

Ma prochaine idée est d'étendre la journalisation de socket.io pour savoir exactement quelles données sont POSTées dans l'espace de noms de la socket. Existe-t-il un moyen d'enregistrer exactement les données qui arrivent sur le serveur (gardez à l'esprit que le hook 'on' côté serveur que j'ai mis en place ne reçoit aucune donnée ; j'ai essayé d'enregistrer les données à partir de là, mais cela ne semble même pas aller jusque là).

J'ai trouvé mod_dumpio pour Linux qui permet d'enregistrer toutes les requêtes POST, mais je ne suis pas sûr qu'il fonctionne bien avec le multi-threading et un serveur de socket.

Avez-vous des idées sur la façon d'obtenir les données exactes qui sont affichées afin que nous puissions au moins dépanner la syntaxe et nous assurer que les données ne sont pas mal formées lorsqu'elles sont envoyées au serveur ?

Merci !

Mise à jour

Lors des tests locaux, nous avons réussi à le faire fonctionner (il s'agissait d'un paramètre dans le code Swift où l'espace de nom n'était pas déclaré correctement). Cela fonctionne bien maintenant sur localhost mais nous avons exactement les mêmes problèmes lorsque nous émettons vers le serveur Apache.

Nous n'utilisons pas mod_wsgi (pour autant que je sache ; je suis relativement novice en matière de mod_wsgi, je m'excuse pour toute ignorance). Nous avions l'habitude d'avoir un fichier .wsgi qui appelait l'application principale script à exécuter mais nous avons dû changer cela parce que mod_wsgi n'est pas compatible avec Flask SocketIO (comme indiqué dans la section Serveur Web uWSGI aquí ). La manière dont j'exécute le script maintenant est en utilisant supervisord pour exécuter le fichier .py en tant que démon (en l'utilisant spécifiquement pour qu'il démarre automatiquement en cas de panne du serveur).

Localement, cela a bien fonctionné une fois que nous avons installé le module eventlet via pip. Lorsque j'ai exécuté pip freeze sur mon environnement virtuel sur le serveur, l'eventlet était installé. Je l'ai désinstallé et réinstallé juste pour voir si cela pouvait résoudre le problème, mais cela n'a rien donné. Aucun autre module Python présent sur ma copie locale ne semble avoir d'incidence sur ce problème.

Une autre chose à garder à l'esprit est que dans la fonction qui initialise l'application, nous changeons le port en port 80 :

socketio.run(app,host='0.0.0.0',port=80)

parce que d'autres fonctions de l'API passent par un domaine qui pointe vers le serveur de cette application. Je ne suis pas sûr que cela ait une incidence, mais cela ne semble pas avoir d'importance sur la version locale.

Je suis à nouveau dans une impasse et j'essaie de trouver quelque chose qui pourrait m'aider. Merci de votre aide !

Une autre mise à jour

Je ne sais pas encore exactement ce qui se passe, mais nous avons réécrit une partie du code, en veillant à prêter une attention particulière aux déclarations d'espace de noms dans chaque événement de socket. on fonction. Elle fonctionne bien maintenant. Dès que j'aurai plus de détails, je les posterai ici car je pense que cela pourra être utile à d'autres personnes qui ont le même problème. Ce fil de discussion contient également des informations très utiles sur la façon de déboguer et d'enregistrer ce type de problèmes, même si nous n'avons jamais trouvé la réponse à la question initiale.

4voto

Miguel Points 15459

Je suppose que vous avez vérifié qu'Apache reçoit bien les requêtes POST. Cela devrait être votre premier test, si Apache n'enregistre pas les requêtes POST provenant d'iOS, alors vous avez un autre type de problème.

Si vous recevez des requêtes POST, vous pouvez ajouter du code personnalisé dans le middleware utilisé par Flask-SocketIO et imprimer les données de la requête transmises par le mod_wsgi d'Apache. Ceci se trouve dans le fichier flask_socketio/ init .py . La partie pertinente est la suivante :

class _SocketIOMiddleware(socketio.Middleware):

    # ...

    def __call__(self, environ, start_response):
        # log what you need from environ here
        environ['flask.app'] = self.flask_app
        return super(_SocketIOMiddleware, self).__call__(environ, start_response)

Vous pouvez découvrir ce qu'il y a dans environ dans le Spécification WSGI . En particulier, le corps de la requête est disponible dans environ['wsgi.input'] qui est un objet de type fichier dans lequel vous lisez.

Gardez à l'esprit qu'une fois que vous aurez lu les données utiles, ce fichier sera consommé, de sorte que le serveur WSGI ne sera pas en mesure de le lire à nouveau. La recherche du fichier à la position qu'il occupait avant la lecture peut fonctionner sur certaines implémentations WSGI. Une astuce plus sûre que j'ai vu des gens faire pour éviter ce problème est de lire l'ensemble des données utiles dans un tampon, puis de remplacer environ['wsgi.input'] avec un tout nouveau StringIO o BytesIO objet.

3voto

Kenny Powers Points 462

Utilisez-vous flask-socketio du côté serveur ? Si oui, il y a beaucoup de débogage disponible dans le constructeur.

socketio = SocketIO(app, async_mode=async_mode, logger=True, engineio_logger=True)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X