Subscribed unsubscribe Subscribe Subscribe

WebSocketを使って重い処理の進み具合をリアルタイムにクライアントへ通知する

分割が可能な重い処理をサーバー側で実行して、処理の状況の変化をクライアント側で表示させたいとき(プログレスバーみたいなのを作るとき)、どういう方法がいいかちょっと考えてみた。問題は「どうやって処理の進歩状況の情報をクライアントサイドでリアルタイムに受け取るか」ということ。

JSでタスクを制御する方法はどうか

まず最初に浮かぶのが、分割されたタスクを1つ行うAPIをサーバー側で用意して、クライアント側からJSのsetTimeoutなりライブラリのdeferredなり使って並行リクエストして、コールバックでプログレスバーを書き換える・・・みたいなのが浮かんだ。
けれど、メインの処理をするロジックはサーバーサイドにまとめておきたい(って思うのって変わってるのかな…?)し、PerlにはCoroやAE::HTTPみたいな便利なものがあるし、「折角なので並行処理の制御はあくまでサーバー側でできないか?」と考えていた。

あくまで並行処理の制御はサーバー側でやってみる

で、次に思い付いたのが、「分割されたタスクが1つ終わるたびにサーバー側からクライアント側に情報をpushする」こと。これを実現するのにWebSocketを使ってみた。
コードはこんな感じ。 (ほとんどサンプルコードをもとにしている。P::M::WebSocket++)この例では、5つのWebページに並行でGETリクエストをしている。

Startボタンを押すとサーバー側で並行処理がスタートする。GETリクエストが1つ済むごとに、サーバー側から情報がpushされる。これをクライアント側でmessageイベントを拾うことで処理する。
http://gyazo.com/7e19484c1aaef53f3452ae56f986117f.png
     ↓
http://gyazo.com/f861f0c8b90c17b96a350bcd9b5cb904.png
(リアルタイムにリクエストの終了が通知される)

ws.onmessage = function (ev) {
    // サーバーから受け取った情報 ev.data を使った処理
    // (プログレスバーを書き換えるなど)
};

この例のような、分割可能な処理の状況をWebSocketで逐一クラアントに伝えれば、プログレスバーのような実行状況の変化を表示するものの実装は容易だ。


・・・ということをしてみたのだけど、実際はこういうの(重い処理の進歩状況をクライアントへ逐一伝える)ってどうやって実装するのがベタな方法なんだろう? 詳しい人いたら教えてください。