我试图从websocket客户端到服务器执行一个常量消息(python / flask / socketio)
我在一个简单的页面上有一个提交按钮,它从一个长时间运行的作业开始。
$('form#emit').submit(function(event) {
socket.emit('submit', {...});
return false;
在python代码中,我启动了长时间运行的工作:
@socketio.on('submit', namespace='/namespace')
def long_running_function(message):
long_running_job_code(message)
我期望发生的是python启动long_running_job_code并返回以setInterval形式执行循环:
在客户端上'循环' :
setInterval(function() { pinger() }, 1000);
function pinger()
{
socket.emit('ping','test');
}
在服务器上:
@socketio.on('ping', namespace='/namespace')
def ping(message):
emit('my response', {'data': '.'})
在点击提交按钮之前,' ping'函数在屏幕上放置....但是在执行long_running_job_code时它不会继续执行该函数。
我认为问题是在服务器端阻塞,但我不确定。长时间运行的作业仍会发送到客户端,但在长时间运行的作业运行时ping发出停止。
任何人都知道如何解决这个问题?
谢谢!
答案 0 :(得分:1)
您没有提到这一点,但我的猜测是您使用eventlet或gevent作为应用程序的Web服务器,因为这是在使用WebSocket和Flask-SocketIO时最有意义的。
Eventlet和gevent是协程服务器。他们可以处理多任务,但这是合作完成的。这意味着,对于从一个任务到另一个任务的上下文切换,第一个任务必须释放CPU。在进行某些I / O调用时,CPU会自动透明地释放,例如从套接字读取或写入时。您还可以通过调用sleep
函数显式释放CPU。如果任务在没有进行任何I / O或显式释放CPU的情况下进行一些长时间的计算,那么整个过程就会阻塞。
在运行长功能时,基本上有两种方法可以保持机器运转。一种方法是定期发出睡眠呼叫。当发生睡眠调用时,调度程序将在从睡眠状态返回之前将CPU提供给其他任务。例如,如果函数有一个循环,则可以在每次迭代时添加它:
eventlet.sleep(0)
另一种不阻塞的方法是将long函数放在子进程中,这可能需要更多的更改,只是在这里和那里添加休眠。
希望这有帮助!