Aipoのコメット機構(JavaScript側)

—-(追記 3/20)—-
記事を修正しました。
aipo/war/src/main/webapp/check.htmlにコメット機構のjsが記述されています。
このhtmlファイルは親htmlにiframeとして組み込まれます。
以前の記事は親html内のjsのCronTaskを見ての推測でした。これは間違いです。
前述のcheck.htmlについて解説します。
ーーーーーーーーーーー

コメット機構

チャット形式のwebアプリケーションは、チャットイベントが発生したらすぐに、プラウザに反映される必要があります。

このためAipoにはコメット機構というのがあります。

具体的にはブラウザ側から定期的にリクエストURLを発行して、イベントが発生するまでサーバーが黙っているような感じです。

ブラウザ側には以下のJavaScriptがあり、このjoinメソッドが主にリクエストする処理に対応しています。

リクエストURLを発行

ブラウザ側には以下のJavaScriptがあり、このjoinメソッドが主にリクエストする処理に対応しています。

以下コメント付きで解説します。

function join() {
    if(isConnect) {
        return;          //他にリクエストURLが有効である場合二重にリクエストされてしまうのでこの場合return
    }
    isConnect = true;    //接続してますフラグ

  //paramsはリクエストURLを発行するのに必要なオブジェクト、パラメータを設定している。//
    var params = {
       url: "push/",               //リクエストURLの値
       timeout: 10 * 60 * 1000,    //タイムアウトとする時間(ミリ秒) この場合10分して応答がなければerrorが実行される
       cache: false,               //キャッシュを使うかどうか
       contentType: "application/javascript",
    //success:リクエストに成功する(レスポンスがある)と実行する関数//
       success: function(data, status) {
           isConnect = false;
           retryCount = 0;             //リクエストのリトライ回数
           var type = data.type;        //レスポンスデータのタイプ
           if("messagev2" == type) {      //クライアント側がメッセージを受信し通知完了した場合
               gadgets.rpc.call(null, "requestCheckMessage", null, data);
           }
           if("messagev2_read" == type) { //クライアントの送信したメッセージが通知された場合
               gadgets.rpc.call(null, "requestCheckMessageRead", null, data);
           }
           if("activity" == type) {     //お知らせの通知
               gadgets.rpc.call(null, "requestCheckActivity");
           }
           join();                      //通知後の処理が終わったら、またコメット機構を再開。
       },
    //error:タイムアウトなどでリクエストがエラーとなる時に実行する関数
       error: function(data, status) {
           isConnect = false;           //接続を解除。
           if(retryCount < 10) {
               retryCount++;
               if(retryCount == 1) {
                   join();              //最初のリトライはそのまま実行
               } else {
                   setTimeout(join, 1000);  //二回目以降のリトライは1秒まってから実行
               }
           }
       }
    }
    jQuery.ajax(params);    //paramsを渡してリクエストURLを発行
}

復帰

上記のjsで10分ごとにリクエストURLを発行できるようになりました。しかしこれだけでは放置を続けてretryCountが10になった後、このコメット機構はとまってしまいます。そのためリフレッシュして復帰するメソッドとイベントが必要です。

aipoではcheck.html内にrefresh()を定義して、以下のように親HTMLからonfocusのイベント処理にrefreshを追加することでコメット機構を復帰させています。

dojo.connect(window, "onfocus", null, function(e) {
    var sharedStateIframe = document.getElementById('sharedStateIframe').contentWindow;
    if(sharedStateIframe) {
        try {
            sharedStateIframe.refresh();
        } catch(ignore) {}
    }
});