для рабочего решения см. мой ответ, который использует Gevent
отаю на «простом» сервере, использующем многопоточный SocketServer в Python 3.
Я переживаю много проблем с реализациейнеисправность за это. Приведенный ниже код, который я нашел в интернете, отключение работает изначально, но перестает работать после отправки нескольких команд от клиента через telnet. Некоторое расследование говорит мне, что оно зависает в threading._shutdown ... threading._wait_for_tstate_lock, но пока это не звонит в колокол.
Мое исследование говорит мне, что существует около 42 различных решений, фреймворков и т. Д., Как это сделать в разных версиях Python. До сих пор я не смог найти рабочий подход для python3. Например. я люблюtelnetsrv (https://pypi.python.org/pypi/telnetsrv/0.4) для python 2.7 (он использует гринлеты из gevent), но этот не работает для python 3. Так что, если есть более питонический, стандартный подход lib или что-то, что работает надежно, я хотел бы услышать об этом!
Моя ставка на данный момент сделана с сокетсервером, но я пока не могу понять, что делать с зависшим сервером. Я удалил все операторы журнала и большинство функций, чтобы я мог опубликовать этот минимальный сервер, который выявляет проблему:
# -*- coding: utf-8 -*-
import socketserver
import threading
SERVER = None
def shutdown_cmd(request):
global SERVER
request.send(bytes('server shutdown requested\n', 'utf-8'))
request.close()
SERVER.shutdown()
print('after shutdown!!')
#SERVER.server_close()
class service(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
msg = str(self.request.recv(1024).strip(), 'utf-8')
if msg == 'shutdown':
shutdown_cmd(msg, self.request)
else:
self.request.send(bytes("You said '{}'\n".format(msg), "utf-8"))
except Exception as e:
pass
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def run():
global SERVER
SERVER = ThreadedTCPServer(('', 1520), service)
server_thread = threading.Thread(target=SERVER.serve_forever)
server_thread.daemon = True
server_thread.start()
input("Press enter to shutdown")
SERVER.shutdown()
if __name__ == '__main__':
run()
Было бы замечательно иметь возможность также остановить сервер от обработчика (см. Shutdown_cmd)