【问题标题】:how to get around a websocket call blocking other websocket calls如何绕过阻止其他 websocket 调用的 websocket 调用
【发布时间】:2016-01-28 17:44:18
【问题描述】:

我正在尝试执行从 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 发射停止。

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

谢谢!

【问题讨论】:

  • 你指的是什么循环?我没有看到循环。您的问题是在服务器端还是在客户端阻塞?
  • 本例中的“循环”是 setInterval(function()... 它每 1000 毫秒发出一次 ping
  • 在长时间运行的作业完成后,该作业运行时发生的 ping 发射被转储到屏幕上,因此它似乎在假脱机直到长时间运行的作业完成。目标是让它同时做这两件事。

标签: python flask websocket socket.io


【解决方案1】:

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

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

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

eventlet.sleep(0)

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

希望这会有所帮助!

【讨论】:

  • 你说得对,我正在使用flask-socketIO,这给了我一些东西可以继续,我可以进行更多实验,看看如何最好地处理它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
相关资源
最近更新 更多