Python - Flask-SocketIO отправляет сообщение из потока: не всегда работает

Я нахожусь в ситуации, когда я получаю сообщение от клиента. Внутри функции, которая обрабатывает этот запрос (@ socketio.on), я хочу вызвать функцию, в которой выполняется некоторая тяжелая работа. Это не должно приводить к блокировке основного потока, и считается, что клиент будет проинформирован, как только работа будет завершена. Таким образом, я начинаю новую тему.

Теперь я сталкиваюсь с действительно странным поведением: сообщение никогда не достигает клиента. Однако код достигает той конкретной точки, куда отправляется сообщение. Еще более удивительным является тот факт, что если в потоке ничего не происходит, кроме сообщения, отправляемого клиенту, то ответ на самом деле находит свой путь к клиенту.

Подводя итог: если что-то требует значительных вычислительных ресурсов перед отправкой сообщения, оно не доставляется, в противном случае это происходит.

Как сказаноВот а такжеВототправка сообщений из потока клиентам не проблема вообще:

Во всех примерах, показанных до этого момента, сервер отвечает на событие, отправленное клиентом. Но для некоторых приложений сервер должен быть отправителем сообщения. Это может быть полезно для отправки клиентам уведомлений о событиях, которые произошли на сервере, например, в фоновом потоке.

Вот пример кода. При удалении комментирующих острых предметов (#) сообщение ('foo from thread') не находит своего пути к клиенту, в противном случае это делает.

from flask import Flask
from flask.ext.socketio import SocketIO, emit
app = Flask(__name__)
socketio = SocketIO(app)

from threading import Thread
import time 

@socketio.on('client command')
def response(data):
    thread = Thread(target = testThreadFunction)
    thread.daemon = True
    thread.start()

    emit('client response', ['foo'])

def testThreadFunction():
#   time.sleep(1)

    socketio.emit('client response', ['foo from thread'])

socketio.run(app)

Я использую Python 3.4.3, Flask 0.10.1, flask-socketio1.2, eventlet 0.17.4.

Этот образец может быть скопирован и вставлен в файл .py, и поведение может быть немедленно воспроизведено.

Может кто-нибудь объяснить это странное поведение?

Обновить

Кажется, это ошибка Eventlet. Если я сделаю:

socketio = SocketIO(app, async_mode='threading')

Это заставляет приложение не использовать eventlet, хотя оно установлено.

Однако для меня это неприменимое решение, так как использование 'многопоточности', поскольку async_mode отказывается принимать двоичные данные. Каждый раз, когда я отправляю некоторые двоичные данные с клиента на сервер, он говорит:

WebSocket transport not available. Install eventlet or gevent and gevent-websocket for improved performance.

Третий вариант, использующий gevent в качестве async_mode, не работает для меня, так как gevent еще не поддерживает python 3.

Так какие-нибудь другие предложения?

Ответы на вопрос(2)

Ваш ответ на вопрос