(Complete Test-App auf GitHub: https://github.com/olingerc/socketio-copy-large-file)Flask-socketio vermisst Ereignisse während Thread-Datei im Hintergrund zu kopieren
I Flask bin mit zusammen mit der Kolben-SocketIO Plugin. Meine Clients können den Server bitten, Dateien über Websocket zu kopieren, aber während die Dateien kopiert werden, möchte ich, dass die Clients mit dem Server kommunizieren können, um ihn um andere Dinge zu bitten. Meine Lösung besteht darin, den Kopiervorgang (shuthil) in einem Hintergrundthread auszuführen. Dies ist die Funktion:
def copy_large_file():
source = "/home/christophe/Desktop/largefile"
destination = "/home/christophe/Desktop/largefile2"
try:
os.remove(destination)
except:
pass
print("Before copy")
socketio.emit('my_response',
{'data': 'Thread says: before'}, namespace='/test')
shutil.copy(source, destination)
print("After copy")
socketio.emit('my_response',
{'data': 'Thread says: after'}, namespace='/test')
ich folgendes Verhalten beobachten: Wenn die Funktion Starten des nativen socketio Methode:
socketio.start_background_task(target=copy_large_file)
alle eingehenden Ereignisse während eine große Datei, bis die verzögert wird kopiert Die Datei ist fertig und eine nächste Datei wird gestartet. Ich gues shutil nicht ist relasing die GIL oder so ähnlich, so dass ich getestet mit einem Gewinde:
thread = threading.Thread(target=copy_large_file)
thread.start()
gleiches Verhalten. Vielleicht Multiprozessing?
thread = multiprocessing.Process(target=copy_large_file)
thread.start()
Ah! Das funktioniert und Signale, die über socketio innerhalb der Funktion copy_large_file ausgegeben werden, werden korrekt empfangen. ABER: Wenn ein Benutzer beginnt, eine sehr große Datei zu kopieren, schließt ihren Browser und kommt 2 Minuten später zurück, verbindet sich der Socket nicht mehr mit der gleichen Socket "Sitzung"? und empfängt somit keine Nachrichten mehr, die vom Hintergrundprozess ausgegeben wurden.
Ich denke, die Hauptfrage ist: Wie kann ich große Dateien im Hintergrund kopieren, ohne flask-socket zu blockieren, aber immer noch in der Lage sein, Signale aus dem Hintergrundprozess an den Client zu senden.
- Klon https://github.com/olingerc/socketio-copy-large-file
- installieren Anforderungen
- wählen Methode in der copy_file Funktion (Linie 42)
- beginnt mit ./app:
Das Test-App kann das Verhalten zu reproduzieren verwendet werden. py
im Browser:
- zu localhost gehen: 5000
- Klicken Sie auf Copy
- Klicken Sie auf Ping-Datei eine Nachricht zu senden, während die Datei kopiert wird
- beobachten auch für andere Signale von Hintergrund-Thread
Was ist mit der Zuweisung einer Zimmer-ID an den Client, dann senden Sie eine Nachricht an den Raum statt. Wenn der Client zurückkommt, treten Sie dem vorherigen Raum bei. –