Запуск колбы в резьбу - PullRequest
0 голосов
/ 10 октября 2019

У меня есть интерактивное приложение Python, где я также хочу использовать колбу-сокето для взаимодействия с клиентами Javascript. Следовательно, мне нужно, чтобы Python socketio работал как поток.

Подход № 1:

def socketio_server_fn():
    socketio.run(flask_app, port=5000)
flask_app = Flask(__name__)
socketio = flask_socketio.SocketIO(flask_app, always_connect=True, async_mode='threading')
socketio_thread = socketio.start_background_task(socketio_server_fn)

Проблема 1.1: он не использует транспорт Websocket, так какнесовместим со стандартными потоками Python. Вместо этого socketio возвращается к опросу.

Проблема 1.2: Опрос не только неэффективен, но также спамит консоль сообщениями, такими как эти каждую секунду:

127.0.0.1 - - [10 октября 2019 13:57:11] GET /socket.io/?EIO=3&transport=polling&t=MsrXwsJ&sid=c63dfaefdbb84c688dd53bef2f6d3c77 HTTP / 1.1 "200 -

Я не смогудалите эти сообщения, и другие тоже получили очень смешанные результаты: Отключить консольные сообщения на сервере Flask

Подход № 2: Используйте eventlet

Сначала мынеобходимо запустить систему потоков Python при запуске программы:

import eventlet
eventlet.monkey_patch()

и затем изменить строку создания объекта SocketIO на:

socketio = flask_socketio.SocketIO(flask_app, always_connect=True, async_mode='eventlet')

Теперь socketio использует Websocket.

Проблема 2.1: Я бы предпочел избегать monkey_patch для всей системы многопоточности Python.

Проблема 2.2: Кажется, что использование eventlet нарушает socketio.stop () при закрытии приложения. stop () теперь зависает даже при вызове из функции обработчика HTTP. Один и тот же код разрыва работал с async_mode = 'threading' и с использованием обычного socketio.run (). socketio.server.stop () также зависает.

Проблема 2.3: Кажется, что Eventlet не полностью совместим с prompt_toolkit:

Exception in default exception handler
Traceback (most recent call last):
  File "python\lib\site-packages\prompt_toolkit\eventloop\win32.py", line 102, in _run_task
    t()
  File "python\lib\site-packages\prompt_toolkit\eventloop\context.py", line 116, in new_func
    return func(*a, **kw)
  File "python\lib\site-packages\prompt_toolkit\patch_stdout.py", line 103, in write_and_flush_in_loop
    run_in_terminal(write_and_flush, in_executor=False)
  File "python\lib\site-packages\prompt_toolkit\application\run_in_terminal.py", line 50, in run_in_terminal
    return run_coroutine_in_terminal(async_func, render_cli_done=render_cli_done)
  File "python\lib\site-packages\prompt_toolkit\application\run_in_terminal.py", line 71, in run_coroutine_in_terminal
    assert app._is_running
AssertionError

Подход № 3. Использование gevent Похоже, что это не работает вообще.

Нет ли простого решения, казалось бы, распространенного варианта использования команды flash-socketio как потока?

...