当前位置:  开发笔记 > 编程语言 > 正文

Python - Flask-SocketIO从线程发送消息:并不总是有效

如何解决《Python-Flask-SocketIO从线程发送消息:并不总是有效》经验,为你挑选了1个好方法。

我处于收到客户留言的情况.在处理该请求的函数内(@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的一个bug.如果我做:

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

它会强制应用程序在安装时不使用eventlet.

但是,对于我来说这不是一个适用的解决方案,因为使用'threading'async_mode拒绝接受二进制数据.每当我从客户端向服务器发送一些二进制数据时,它会说:

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

使用gevent作为async_mode的第三个选项对我来说不起作用,gevent也不支持python 3.

还有其他建议吗?



1> Schnodderbal..:

我设法通过monkeypatching几个Python函数来解决这个问题,这导致Python使用eventlet函数而不是本机函数.这样背景线程可以与eventlet一起使用.

https://github.com/miguelgrinberg/Flask-SocketIO/blob/master/example/app.py#L30-L31

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有