3 votes

Passer des arguments au gestionnaire UDP en Python

J'utilise les sockets pour la première fois en Python, et j'ai un problème.

J'ai un gestionnaire de requêtes threadé pour mon serveur UDP, mais en raison de la façon dont il fonctionne (comme suggéré aquí ) Je n'arrive pas à trouver comment lui passer des arguments. J'ai besoin qu'il accède à d'autres objets de l'application, car il doit leur notifier les actions effectuées par les différents clients du réseau. Cependant, la classe représentant le gestionnaire ne peut pas être instanciée, donc elle ne peut pas prendre d'arguments via le constructeur.

Ceci est une version simplifiée de mon code.

class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):          

    def handle(self):
        data = self.request[0].strip()        
        socket = self.request[1]
        print ("{} wrote:".format(self.client_address[0]))
        print (data)
       #Ideally, I'd call a method of an object here

class ThreadedUDPServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
    pass

class ServerManager():

    def __init__(self, player_box):
        self.player_box = player_box
        HOST, PORT = "xxx.xxx.xxx.xxx", 9999
        self.server = ThreadedUDPServer((HOST, PORT), ThreadedUDPRequestHandler)
        ip, port = self.server.server_address

    def start(self):             
        server_thread = threading.Thread(target=self.server.serve_forever)
        server_thread.start()

    def stop(self):
        self.server.shutdown()

Dans ce cas, l'objet auquel j'aimerais que le gestionnaire de requêtes accède est player_box. Le but est d'appeler une méthode de cet objet à chaque fois qu'une demande est faite. Existe-t-il un moyen de faire cela, ou dois-je utiliser une approche différente ?

J'ai remarqué qu'il y a une question similaire aquí mais la solution proposée ne fonctionne pas du tout pour moi. En fait, elle n'a pas beaucoup de sens pour moi...

1voto

Oded R. Points 465

C'est peut-être un peu moche, mais c'est la meilleure idée que j'ai :

class ThreadedUDPRequestHandler(socketserver.BaseRequestHandler):
    PLAYER_BOX = None
    def handle(self):
       data = self.request[0].strip()        
       # (...)
       self.PLAYER_BOX.foo()

class ServerManager():

    def __init__(self, player_box):
        class ThreadedUDPRequestHandlerWithPlayerBox(ThreadedUDPRequestHandler):
            PLAYER_BOX = player_box
        HOST, PORT = "xxx.xxx.xxx.xxx", 9999
        self.server = ThreadedUDPServer((HOST, PORT), ThreadedUDPRequestHandlerWithPlayerBox)

Comme vous pouvez le constater, l'idée comporte deux parties :

  1. Faites en sorte que votre classe de gestionnaire ait un attribut de classe qui sera accessible depuis sa ou ses méthodes.
  2. Créez des sous-classes de cette classe, où l'attribut ci-dessus sera défini sur la valeur souhaitée (dans votre cas, l'objet player_box).

J'espère que cela vous aidera.

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