(在github上完整的測試程序:https://github.com/olingerc/socketio-copy-large-file)燒瓶socketio錯過的事件複製文件在後臺線程
我一起用瓶與瓶-SocketIO插件。我的客戶可以要求服務器通過websocket複製文件,但在文件複製時,我希望客戶端能夠與服務器通信以要求其執行其他操作。我的解決方案是在後臺線程中運行復制過程(shutil)。這是函數:
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')
我遵守以下行爲: 當使用本地socketio方法啓動功能:
socketio.start_background_task(target=copy_large_file)
所有傳入事件,而一個大文件被複制被延遲,直到文件完成並啓動下一個文件。我客串shutil不relasing的GIL或類似的東西,所以我線程測試:
thread = threading.Thread(target=copy_large_file)
thread.start()
相同的行爲。也許多處理?
thread = multiprocessing.Process(target=copy_large_file)
thread.start()
啊!這是有效的,並且通過copy_large_file函數內的socketio發射的信號被正確接收。 但是: 如果用戶開始複製一個非常大的文件,關閉瀏覽器並在2分鐘後回來,套接字不再連接到相同的socketio「會話?」並因此不再接收從後臺進程發出的消息。
我猜主要問題是:如何在不阻塞flask-socketio的情況下在後臺複製大文件,但仍能夠在後臺進程中向客戶端發送信號。
測試應用程序可以被用於重現行爲:
- 克隆https://github.com/olingerc/socketio-copy-large-file
- 安裝要求
- 選擇在COPY_FILE函數方法(線42)
- 開始與./app。 py
在瀏覽器中:
- 去爲localhost:5000
- 點擊複製文件
- 點擊Ping來發送消息,而該文件被複制
- 也監視着從後臺線程其他信號
如何分配一個房間ID給客戶端,然後發送消息到房間。當客戶回來時,加入前一個房間。 –