Передача дополнительных метаданных в RequestHandler с использованием SocketServer и детей python

Я реализую приложение python, которое использует ThreadingTCPServer и собственный подкласс BaseRequestHandler . Проблема заключается в том, что ThreadingTCPServer кажется, автоматически порождает потоки и создает экземпляры обработчика, вызывая их функцию handle() . Однако это не оставляет мне возможности передавать данные обработчику, кроме использования глобальных переменных или переменных класса, оба из которых кажутся хакерскими. Есть ли лучший способ сделать это?

В идеале это должно быть примерно так:

 class ThreadedTCPServer(ThreadingTCPServer): def process_request(self, *args, **kwargs): ThreadingTCPServer.process_request(self, data, *args, **kwargs) 

с обработчиком вроде

 class ThreadedTCPRequestHandler(BaseRequestHandler): def handle(self,data): #do something with data 

3 Solutions collect form web for “Передача дополнительных метаданных в RequestHandler с использованием SocketServer и детей python”

Я наткнулся на то же самое. Мое решение было следующим:

 class ThreadedTCPRequestHandler(SocketServer.StreamRequestHandler): def handle(self): print(self.server.mycustomdata) class ThreadedTCPServer(SocketServer.ThreadingTCPServer): pass server = ThreadedTCPServer((args.host, args.port), ThreadedTCPRequestHandler) server.mycustomdata = 'foo.bar.z' server.serve_forever() 

RequestHandler вызывается с объектом сервера в качестве третьего параметра, и он сохраняется как атрибут self.server , поэтому вы можете получить к нему доступ. Если вы установите этот атрибут на вызываемый, вы также можете легко вызвать его:

 def handle(self): mycustomdata = self.server.mycustomdata() 

Поскольку handle реализуется подклассом BaseRequest , он может получать данные от себя, не передавая их вызывающей стороне. ( handle также может быть атрибутом вызываемого объекта экземпляра запроса, например, аргументы user_data ясными user_data как правило, не нужны в идиоматически разработанном python.)

Если посмотреть на код SocketServer, нужно переопределить finish_request чтобы передать дополнительные данные в ваш BaseRequestHandler подтипа BaseRequestHandler который сохранит его в экземпляре для используемого handle .

Первый ответ сработал для меня, но я думаю, что более __init__ изменить метод __init__ и передать атрибут в конструкторе:

 class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): def __init__(self, host_port_tuple, streamhandler, Controllers): super().__init__(host_port_tuple, streamhandler) self.Controllers = Controllers 

Обратите внимание на третий параметр «Контроллеры» в конструкторе, а затем на вызов супер без этого параметра, затем установите новый атрибут Controllers в свойство self.Controllers. Остальная часть класса не изменилась. Затем в вашем Requesthandler вы получаете доступ к параметру, используя атрибут «server», как описано выше:

 def handle(self): self.Controllers = self.server.Controllers <rest of your code> 

Это почти то же самое, что и ответ выше, но я нахожу его немного более чистым, потому что конструктор перегружен, и вы просто добавляете атрибут, который вы хотите в конструкторе:

 server = ServerInterface.ThreadedTCPServer((HOST, PORT), ServerInterface.ThreadedTCPRequestHandler, Controllers) 
  • неблокирующий сокет, ошибка всегда
  • Программирование сокетов в Python: ошибка сборки socket.error: < Ошибка подключения
  • Python Sockets: gethostbyaddr: обратная ошибка поиска DNS
  • сервер / клиентский протокол сокета python с нестабильным подключением к клиенту
  • Требовать входа в сокет Django Channels?
  • Python Socket Flush
  • Получение нескольких сообщений через socketserver, но один отправляется
  • Производительность S / Python Socket?
  • Python - лучший язык программирования в мире.