著作一覧 |
ロングポールは無限ではないので、どこかのタイミングでレスポンスを返す。あるいは、ブラウザ(の先のXHRの先のTCPソケット)がタイムアウトする。
どちらでも良いが、そこで次のリクエストを送る。ここに隙間が生まれる。当然の様にマーフィーの第五法則によって、この隙間でサーバーイベントがファイアされる。したがって、新たなロングポールも虚しく待ち続け、そして返って行く。
どうすればこの問題を解決できるだろうか?
ロングポールを2個使い、常にポールがかかっているようにする。
が、それは同一ドメイン2コネクション制限(を持つブラウザを前提し、かつ単一ノード複数ドメインを採用しない場合。いずれにしろクロスドメインのあれこれは面倒だから複数ドメインは採用しないのだが)を使い切る。UIによる中止動作や遷移をブロックしてしまう(そのUIイベントの先頭で、ロングポールをアボートすれば良い)。
サーバーイベントを滞留させて、隙間を新たなロングポールが届くまで引き延ばす(意味的には隙間を接合する)。
前者は出来れば避けたい手段だ。XHRの中断はリソースリークフリーか確信が持てなすぎる。出来ればレスポンスを受けて終わらせたい。
後者はバカみたくサーバの実装が厄介となる。DBへの書き込みイベントのような本質的に不揮発性の情報であれば、最後に受信した情報の続きを読めば(つまり、それがある限りロングポールではなく普通のよみこみだ)良いので話は単純だが、ここで問題としているのは、例えばセンサーによる検出のような揮発性かつ累積的情報だ。
と、書いてみれば結論は1つとなる。最後にポールによって得た累積値を持ってサーバーへリクエストを出し、既にその累積値と異なる値に変化していれば、その値を返せば良い。等しければ待ち状態に入る。DBのロウ追加の読み出しとそれほど違いは無い。異なるのは隙間が多数のイベントで区切られていても、最終状態のみしか受けられないことだが、累積値なのだからそれは問題とならない)。サーバーの実装は、元々累積値を持っているのだから何も難しいことは無い。
ジェズイットを見習え |
WS-POSでの議論時は<br>>サーバーイベントを滞留させて、隙間を新たなロングポールが届くまで引き延ばす(意味的には隙間を接合する)。<br>こっちを漠然と考えていました。デバイスからのイベントをサーバでキュー管理、次のポーリングまで保持します。<br>自分の業務に身近な実装で考えてしまうと、バーコードスキャナからの入力イベントはキュー管理、プリンタのステータスアップデートイベントは累積値という感じに思います。<br>(見当はずれのお話していたらすみません)<br>POSシステムにおけるバーコードスキャナみたいに連続して商品を読み込むようなデバイスをサービスとして考える場合、ロングポールの隙間にたくさんのバーコードスキャナからのイベントがあったとき、次のポールではイベントのリストを一度に取得する実装が、通信の粒度を考えると現実的か、と思っています。(が、検証はしてません…)<br>と、ここまで書いたのですが、たしかにサーバ実装は面倒くさくなりますね。キューの永続性、使用権などの設計がきちんとしてないとどこかでロックしそうです。
どうも! 想定とは違うけど核心です。というかキューが頭から抜け落ちてました。キュー待ちならリクエスト処理はきれいにまとまりそうです。るいせ<br>WSPOSの場合。隙間はFreezeでうめられないかな?
るいせ→累積値なのでオブジェクトにするという発想がなかった
接続を2本にしても抜けるものは抜けるし、サーバをステートフルにすると性能の問題が出るので、ネイティブクライアントは複数接続し、ブラウザ向けに一定期間おきに複数回配信、重複削除はクライアント側、とかやりました。<br><br>おまけネタで、複数接続はそれぞれ別サーバにつながってほしいわけですが、DNSラウンドロビンやロードバランサとの相性でちょっとハマりました。
定期的に複数回配信、重複管理はクライアント側かぁ。その方法も覚えておきます。ありがとう。