Search code examples
htmlperlwebsocketmojolicious

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


I use Mojolicious WebSocket to establish server-client messaging protocol.

There is long-time operation on server and I want update its progress on client-side.

In several points on server-side code I call $web_socket->send(...) and process it on client-side ws.onmessage = function (event) {...};

Everything work fine, but not in realtime: all messages has received by client at one big bulk list and only after whole server-side script has finished.

Server-side logic:

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

Client-side:

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

Solution

  • I found this works for me: Mojo::IOLoop->one_tick;

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

    UPD: or may be it will be better to separate long operation in background thread ('fork' or 'delay').