如何从阻塞操作中发送 WebSocket 事件? (需要设计建议)

How to send WebSocket events from blocking operation? (Design advice needed)

我使用 Mojolicious WebSocket 建立服务器-客户端消息传递协议。

服务器有长时间运行,我想在客户端更新它的进度。

在服务器端代码的几个方面,我调用 $web_socket->send(...) 并在客户端处理它 ws.onmessage = function (event) {...};

一切正常,但不是实时的:客户端已在一个大的批量列表中收到所有消息,并且仅在整个服务器端脚本完成后才收到。

服务器端逻辑:

some_computation1();
$web_socket->send('computation1 end');
...
some_computation15();
$web_socket->send('computation15 end');
...
some_computation100();
$web_socket->send('computation100 end. All ok!');

客户端:

ws = new WebSocket(url);
ws.onmessage = function (event) {
    $('#log_view').append('<p>' + event.data + '</p>');
};
ws.onopen = function (event) {
    ... 
};
ws.onclose = function (event) {
    ...
};

There is 两个如何使用两个模块之一制作它的示例:

  1. Mojo::IOLoop::ReadWriteFork
  2. Mojo::IOLoop::ForkCall

到运行它执行命令:
perl perl_ws_long_blocking_operation.pl daemon

更新 如果你有很多长阻塞操作,你应该使用 Mojo::IOLoop::Delay:

Example of many long blocking operation

到运行它执行命令:

morbo perl_ws_many_long_blocking_operations.pl

我发现这对我有用:Mojo::IOLoop->one_tick;

some_computation1();
$web_socket->send('computation1 end');
Mojo::IOLoop->one_tick;

更新:或者在后台线程中分离长时间操作可能会更好('fork' 或 'delay')。