Я использую сервер сокетов python, к которому я подключаюсь с Android, и периодически отправляю сообщения. У меня проблема с тем, что запрос закрыт для каждого отправленного сообщения, и мне нужно, чтобы он оставался открытым до тех пор, пока Android не решит закрыть его.
Curentlly выглядит так:
class SingleTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
try:
while True:
message = self.rfile.readline().strip() # clip input at 1Kb
my_event = pygame.event.Event(USEREVENT, {'control':message})
pygame.event.post(my_event)
except KeyboardInterrupt:
sys.exit(0)
finally:
self.request.close()
Я решил это, добавив некоторое while True
в определение handle()
, однако это критиковали как плохое решение и что правильный путь - переопределить методы process_request
и shutdown
.
Попытка решения
Я удалил while
из кода, подключился к серверу локально с netcat, отправил сообщение и пошел посмотреть, когда будет закрыто соединение.
Я хотел посмотреть, что такое метод, после которого соединение закрывается, чтобы выяснить, что мне нужно переопределить.
Я сделал шаг с отладчиком через serve_forever()
и последовал за ним в эту часть кода:
> /usr/lib/python2.7/threading.py(495)start()
494 try:
--> 495 _start_new_thread(self.__bootstrap, ())
496 except Exception:
После передачи строки 495 (я не могу войти в нее) соединение закрыто.
Я почему-то сомневаюсь, что такая суета для поддержания соединения через сокет, это в основном причина, по которой мы решили общаться через сокет, иметь непрерывное соединение, а не систему "одно соединение для отправленного сообщения".
Идеи о реализации или ссылки?
Метод handle
вызывается для каждого клиентского соединения, и соединение закрывается, когда оно возвращается. Используя while
цикл в порядке. Выйдите из цикла, когда клиент закроет соединение.
Пример (синтаксис Python 3):
class EchoHandler(socketserver.StreamRequestHandler):
def setup(self):
print('{}:{} connected'.format(*self.client_address))
def handle(self):
while True:
data = self.request.recv(1024)
if not data: break
self.request.sendall(data)
def finish(self):
print('{}:{} disconnected'.format(*self.client_address))