如何绕过websocket调用阻止其他websocket调用

时间:2016-01-28 17:44:19

标签: python flask websocket socket.io

我试图从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发出停止。

任何人都知道如何解决这个问题?

谢谢!

1 个答案:

答案 0 :(得分:1)

您没有提到这一点,但我的猜测是您使用eventlet或gevent作为应用程序的Web服务器,因为这是在使用WebSocket和Flask-SocketIO时最有意义的。

Eventlet和gevent是协程服务器。他们可以处理多任务,但这是合作完成的。这意味着,对于从一个任务到另一个任务的上下文切换,第一个任务必须释放CPU。在进行某些I / O调用时,CPU会自动透明地释放,例如从套接字读取或写入时。您还可以通过调用sleep函数显式释放CPU。如果任务在没有进行任何I / O或显式释放CPU的情况下进行一些长时间的计算,那么整个过程就会阻塞。

在运行长功能时,基本上有两种方法可以保持机器运转。一种方法是定期发出睡眠呼叫。当发生睡眠调用时,调度程序将在从睡眠状态返回之前将CPU提供给其他任务。例如,如果函数有一个循环,则可以在每次迭代时添加它:

eventlet.sleep(0)

另一种不阻塞的方法是将long函数放在子进程中,这可能需要更多的更改,只是在这里和那里添加休眠。

希望这有帮助!