2011-04-18 3 views
1

L'application est une configuration client/serveur WxPython qui a plusieurs clients se connectant au serveur et s'engageant dans un protocole de réseau duplex. Par le passé, Twisted avait déjà été couplé avec AMP, mais il ne l'a pas complètement coupé pour l'architecture de l'application sans trop compliquer les choses à la fin.Client réseau Python, essayant de répondre aux réponses du serveur

Donc, pour le serveur, j'ai SocketServer avec la configuration ThreadingMixIn. En ce moment je travaille sur la file d'attente tampon/commande pour le serveur, mais ce n'est pas le problème.

Du côté client, je peux faire tout l'envoi normal de données, déclenché par des événements dans l'interface utilisateur, sans trop de problèmes. Je suis actuellement bloqué essayant d'obtenir le client pour écouter des réponses sans bloquer l'application entière. Donc, je veux mettre cela dans un fil, mais devrait-il commencer à la partie qui est maintenant commentée ou devrait-il être complètement différent et je ne le vois tout simplement pas? En bref: je souhaite que le client envoie des commandes au serveur et écoute les réponses sans bloquer/bloquer l'application entière.

Le code ci-dessous est un code de prototypage, s'il vous plaît excuser les erreurs typiques telles que les valeurs magiques et autres données codées en dur, il sera différent dans le code final.

import socket 
import threading 
import time 


class CommandProxy(object): 
    def __init__(self, host, port): 
     self.host = host 
     self.port = port 

    def close(self): 
     if self.connection: 
      self.connection.close() 

    def connect(self): 
     try: 
      self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
      self.connection.connect((self.host, self.port)) 
     except socket.error as e: 
      print "Socket error: {0}".format(e) 

    def send_command(self, command, *kw): 
     datalist = ' '.join(kw) 
     data = command + ' ' + datalist + '\x00' 

     print 'DATA: {0}'.format(data) 

     self._write(data) 

#  while True: 
#   data = self._read() 
#   if data == 0: 
#    break 
# 
#  print "DATA RECEIVED: {0}".format(data) 

    def _read(self): 
     data = self.connection.recv(1024) 
     return data 

    def _write(self, bytes): 
     self.connection.sendall(bytes) 


if __name__ == '__main__': 
    HOST, PORT = 'localhost', 1060 

    proxy = CommandProxy(HOST, PORT) 
    proxy.connect() 
    try: 
     while True: 
      proxy.send_command('ID', '1') 
      time.sleep(2) 

    except KeyboardInterrupt: 
     print "Interrupted by user" 
    except socket.error as e: 
     print "Socket error: {0}".format(e) 
    except Exception as e: 
     print "something went wrong: {0}".format(e) 
    finally: 
     proxy.close() 

Répondre

0

IMO votre droite avec un fil. Démarrer un thread pour chaque requête, et quand c'est fait et avoir une donnée, générer un événement wx (voir http://wiki.wxpython.org/CustomEventClasses)

+0

Ok, donc en substance avoir un fil séparé écouter sur le socket tout le temps et chaque fois que les données reviennent du serveur génèrent WxEvents? – asmodai

1

Je pense que vous vous trompez de savoir si une approche monothread ou multi-thread compliquera votre application plus ou moins. Le problème que vous rencontrez actuellement est l'un des nombreux que (par exemple) Twisted résout pour vous hors de la boîte.

La plainte la plus fréquente que les gens ont à propos de Twisted est que cela leur fait étrangement structurer leur code, d'une manière à laquelle ils ne sont pas habitués. Cependant, lorsque vous utilisez une bibliothèque GUI comme wxPython, vous avez déjà accepté cette contrainte. L'architecture événementielle de Twisted est exactement comme l'architecture événementielle de tous les toolkits populaires de l'interface graphique. Tant que vous continuez à utiliser wxPython, l'utilisation de Twisted ne vous obligera pas non plus à faire quoi que ce soit d'autre que vous ne voulez pas faire. D'un autre côté, le passage aux threads signifie que vous devez faire très attention à l'accès aux structures de données partagées, vous ne pourrez pas tester efficacement les unités, et de nombreux problèmes ne surviendront que si quelqu'un d'autre le fait exécute votre application - parce qu'ils ont un nombre différent de cœurs que vous, ou que leur réseau a des caractéristiques de latence différentes, ou un nombre d'autres choses qui font que votre code thread s'exécute d'une manière que vous n'avez jamais rencontrée. Avec un soin extrême, vous pouvez toujours écrire quelque chose qui fonctionne, mais ce sera beaucoup plus difficile.

Puisque vous n'avez posté aucun de vos codes Twisted ici, je ne peux pas vraiment donner de conseils spécifiques sur la façon de garder les choses aussi simples que possible. Cependant, je recommande que vous jetiez un autre regard sur une solution non-threaded. Rejoignez la liste de diffusion [email protected], sautez sur #twisted sur freenode, ou postez d'autres questions à propos de stackoverflow. Beaucoup de gens seront désireux d'aider. :)

+0

Bonjour Jean-Paul, nous avons déjà parlé du code sur lequel je travaillais.J'avais Twisted dans la base de code pour gérer les aspects de mise en réseau et asynchrones, mais à la fin le code est devenu difficile à la fois dans la maintenance et la facilité à expliquer aux autres. A cela s'ajoute le fait que je dois introduire une barrière en tant que point de synchronisation, ce que vous avez dit il y a environ un an deviendrait problématique avec Twisted dans le mix. Étant donné que j'ai déjà complètement retiré Twisted de la base de code, je continue sur cette voie avec le filetage. Merci pour l'offre d'aide si. – asmodai

Questions connexes