6
votes

lecture / journalisation non bloquante à partir d'un flux http

J'ai un client qui se connecte à un flux http et enregistre les données de texte qu'il consomme.

J'envoie le serveur de streaming une demande http get ... Le serveur répond et publie continuellement des données ... il publiera régulièrement du texte ou envoyer un message de ping (texte) ... et ne fermera jamais la connexion.

J'ai besoin de lire et de connecter les données qu'il consomme de manière non bloquante. p>

Je fais quelque chose comme ceci: p>

import urllib2

req = urllib2.urlopen(url)    
for dat in req: 
    with open('out.txt', 'a') as f:        
        f.write(dat) 


0 commentaires

4 Réponses :


6
votes

Hey, c'est trois questions dans une! ; -)

Il pourrait bloquer parfois - même si votre serveur génère des données assez rapidement, les goulots d'étranglement réseau peuvent en théorie causer vos lectures à bloquer.

lire les données URL à l'aide de "pour DAT in Req" Je veux dire lire une ligne à la fois - pas vraiment utile si vous lisez des données binaires telles qu'une image. Vous obtenez un meilleur contrôle si vous utilisez xxx

qui peut bien sûr bloc.

si c'est le meilleur moyen dépend des spécificités non disponibles dans votre question. Par exemple, si vous devez utiliser sans blocage d'appels, vous devrez envisager un cadre comme torsadé . Si vous ne voulez pas bloquer le blocage de vous retenir et que vous ne voulez pas utiliser Twisted (qui est un tout nouveau paradigme par rapport à la manière bloquante de faire des choses), vous pouvez faire tourner un fil pour faire la lecture et l'écriture à Fichier, tandis que votre thread principal va sur sa manière joyeuse: xxx

évidemment, j'ai omis la vérification des erreurs / la manipulation des exceptions, etc. Mais espérons-le, il suffit de vous donner la photo.


0 commentaires

1
votes

Oui lorsque vous rattrapez le serveur, il bloquera jusqu'à ce que le serveur produit plus de données

Chaque DAT sera une ligne, y compris la nouvelle ligne à la fin

tordu est une bonne option

J'y échangez avec et pendant autour de votre exemple, voulez-vous vraiment ouvrir et fermer le fichier pour chaque ligne qui arrive?


1 commentaires

le pour / avec la commande était intentionnel. Cela ouvrira / fermera la poignée de fichier avec chaque écriture. Pas efficace pour un flux occupé, mais dans mon cas, le flux est principalement bloqué / en attente, puis reçoit occasionnellement des données pour se connecter.



3
votes

Vous utilisez une interface de trop haut niveau pour avoir un bon contrôle sur des problèmes tels que la taille des blocs de blocage et de mise en mémoire tampon. Si vous n'êtes pas disposé à aller jusqu'au bout d'une interface ASYNC (auquel cas torsadé , déjà suggéré , est difficile à battre!), pourquoi pas HTTPLIB , qui est après tout dans le Bibliothèque standard? Httpresponse Instance .read (montant) La méthode est plus susceptible de bloquer pour ne plus que nécessaire pour lire montant octets, que la méthode similaire de l'objet renvoyée par urlopen (Bien que certes, il n'y a pas de spécifications documentées à ce sujet sur le module, HMMM ...).


0 commentaires

2
votes

Une autre option consiste à utiliser directement le module socket directement. Établissez une connexion, envoyez la demande HTTP, définissez le socket sur le mode sans blocage, puis lisez les données avec socket.recv () manipulation 'ressource temporairement indisponible' exceptions (ce qui signifie qu'il n'y a rien lire). Un exemple très rugueux est celui-ci: xxx

Cependant, urllib.urlopen () a des avantages si le serveur Web redirige, vous avez besoin d'une authentification de base basée sur l'URL. pourrait utiliser le module SELECT qui vous indiquera quand il y a des données à lire.


0 commentaires