Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass arguments to UDP handler in Python

I'm using sockets for the first time in Python, and I have a problem.

I have a threaded request handler for my UDP server, but because of the way it works (as suggested here) I can't figure out how to pass arguments to it. I need it to access other objects in the application, because it must notify them of the actions performed by the different clients in the network. However the class representing the handler cannot be instantiated, so it can't take arguments via the constructor.

This is a simplified version of my 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()

In this case, the object I'd like the request handler to access is player_box. The goal is to call a method of that object every time a request is made. Is there a way to do this, or should I use a different approach?

I noticed there is a similar question here, but the proposed solution does not work at all for me. In fact, it doesn't make much sense to me...

like image 452
cangrejo Avatar asked Sep 14 '26 23:09

cangrejo


1 Answers

This may be a little ugly, but it's the best idea I have:

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)

As you can see, the idea has two parts:

  1. Let your handler class have a class attribute which will be accessed from its method(s).
  2. Create subclasses of this class, where the above attribute will be set to the wanted value (in your case, the player_box object).

I hope this helps.

like image 155
Oded R. Avatar answered Sep 17 '26 12:09

Oded R.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!