如何绕过阻止其他 WebSocket 调用的 Websocket 调用



我正在尝试执行从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 发出在长时间运行的作业进行时停止。

有人知道如何解决这个问题吗?

谢谢!

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

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

在运行长函数时,您基本上有两种方法可以保持机器运行。一种方法是定期拨打睡眠电话。当发生睡眠调用时,调度程序将在从睡眠状态返回之前将 CPU 提供给其他任务。例如,如果您的函数有一个循环,您可以在每次迭代时添加以下内容:

eventlet.sleep(0)

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

希望这有帮助!

相关内容

  • 没有找到相关文章

最新更新