2016-01-03 34 views
15

Tôi đang trong tình huống mà tôi nhận được tin nhắn từ khách hàng. Trong hàm xử lý yêu cầu đó (@ socketio.on) Tôi muốn gọi hàm mà một số công việc nặng được thực hiện. Điều này sẽ không dẫn đến việc chặn luồng chính và khách hàng được cho là được thông báo khi công việc được thực hiện. Vì vậy, tôi bắt đầu một chủ đề mới.Python - Flask-SocketIO gửi tin nhắn từ chủ đề: không phải lúc nào cũng hoạt động

Bây giờ tôi gặp phải một hành vi thực sự lạ: Thông báo không bao giờ tiếp cận khách hàng. Tuy nhiên, mã đạt đến vị trí cụ thể mà thư được gửi. Thậm chí đáng ngạc nhiên hơn là một thực tế là nếu không có gì xảy ra trong chủ đề ngoại trừ tin nhắn được gửi cho khách hàng thì câu trả lời thực sự tìm đường đến máy khách.

Để tổng hợp: Nếu có điều gì đó tính toán chuyên sâu xảy ra trước khi thư được gửi thì thư sẽ không được gửi, nếu không thì sẽ được gửi.

Giống như người ta nói herehere, gửi tin nhắn từ một thread để khách hàng không phải là một vấn đề gì cả:

Trong tất cả các ví dụ cho thấy đến thời điểm này, máy chủ đáp ứng một sự kiện được gửi bởi khách hàng. Nhưng đối với một số ứng dụng, máy chủ cần phải là người khởi tạo của một tin nhắn. Điều này có thể hữu ích khi gửi thông báo cho các khách hàng của các sự kiện có nguồn gốc trong máy chủ, ví dụ trong một chủ đề nền.

Đây là mã mẫu. Khi loại bỏ các sharps bình luận (#), thông báo ('foo from thread') không tìm đường đến máy khách, nếu không thì nó sẽ xuất hiện.

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) 

Tôi đang sử dụng Python 3.4.3, Flask 0.10.1, flask-socketio1.2, eventlet 0.17.4.

Mẫu này có thể được sao chép và dán trong một tệp .py và hành vi có thể được sao chép ngay lập tức.

Ai đó có thể giải thích hành vi kỳ lạ này?

Cập nhật

Nó có vẻ là một lỗi của eventlet. Nếu tôi làm:

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

Nó buộc ứng dụng không sử dụng eventlet mặc dù nó được cài đặt.

Tuy nhiên, đây không phải là giải pháp áp dụng cho tôi khi sử dụng 'luồng' vì async_mode từ chối chấp nhận dữ liệu nhị phân. Mỗi lần tôi gửi một số dữ liệu nhị phân từ máy khách đến máy chủ nó nói:

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

Lựa chọn thứ ba, sử dụng gevent như async_mode không làm việc cho tôi cũng như gevent không có hỗ trợ cho python 3 chưa.

Vì vậy, bất kỳ đề xuất nào khác?

+0

@rfkortekaas điều đó có ý nghĩa như thế nào trong giao thức không đồng bộ? Và ngoài ra, phản hồi được gửi đi. Đó là những gì "phát ra". Điều khác đang xảy ra trong một chủ đề riêng biệt. – Schnodderbalken

+0

Tôi đã xóa nhận xét của mình khi tôi đọc sai câu hỏi. – rfkortekaas

+0

Tôi gặp phải một vấn đề rất giống nhau, nhưng chúng tôi không làm gì tốn kém về mặt tính toán. Nó có vẻ là một vấn đề với grabbing đúng "socketio" khi gọi socketio.emit. Bởi vì phát ra DOES xảy ra, nhưng không có khách hàng nào nhận được tin nhắn. Thêm async_mode = 'luồng' dường như để khắc phục sự cố. Nhưng hy vọng có một cách tốt hơn – AMB0027

Trả lời

Các vấn đề liên quan