Python - Flask-SocketIO Nachricht vom Thread senden: funktioniert nicht immer

Ich bin in der Situation, in der ich eine Nachricht vom Kunden erhalte. Innerhalb der Funktion, die diese Anfrage bearbeitet (@ socketio.on), möchte ich eine Funktion aufrufen, in der schwere Arbeit geleistet wird. Dies sollte nicht dazu führen, dass der Haupt-Thread blockiert wird und der Client nach Abschluss der Arbeit informiert wird. Also starte ich einen neuen Thread.

Jetzt stoße ich auf ein merkwürdiges Verhalten: Die Nachricht erreicht den Client nie. Der Code erreicht jedoch die bestimmte Stelle, an der die Nachricht gesendet wird. Noch überraschender ist die Tatsache, dass, wenn im Thread nichts passiert, außer der Nachricht, die an den Client gesendet wird, die Antwort tatsächlich den Weg zum Client findet.

Um es zusammenzufassen: Wenn etwas rechenintensives passiert, bevor die Nachricht gesendet wird, wird es nicht zugestellt, andernfalls ist es.

Wie es heißtHie undHie, das Senden von Nachrichten von einem Thread an die Clients ist überhaupt kein Problem:

In allen bis zu diesem Zeitpunkt gezeigten Beispielen reagiert der Server auf ein vom Client gesendetes Ereignis. Bei einigen Anwendungen muss der Server jedoch der Absender einer Nachricht sein. Dies kann nützlich sein, um Benachrichtigungen an Clients über Ereignisse zu senden, die vom Server ausgehen, z. B. in einem Hintergrundthread.

Hier ist ein Beispielcode. Beim Entfernen der kommentierenden Punkte (#) findet die Nachricht ('foo from thread') keinen Weg zum Client, andernfalls.

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)

Ich verwende Python 3.4.3, Flask 0.10.1, flask-socketio1.2, Eventlet 0.17.4.

Dieses Beispiel kann kopiert und in eine .py-Datei eingefügt werden, und das Verhalten kann sofort reproduziert werden.

ann jemand dieses seltsame Verhalten erkläre

Aktualisiere

It scheint, ein Fehler des eventlet zu sein. Wenn ich mache

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

Erzwingt, dass die Anwendung das Eventlet nicht verwendet, obwohl es installiert ist.

Dies ist jedoch keine geeignete Lösung für mich, da "Threading" verwendet wird, da async_mode die Annahme von Binärdaten verweigert. Jedes Mal, wenn ich Binärdaten vom Client an den Server sende, heißt es:

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

Die dritte Option, gevent als async_mode zu verwenden, funktioniert bei mir nicht so gut wie gevent hat noch keine Unterstützung für Python 3.

So irgendwelche anderen Vorschläge?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage