2008년 6월 12일 목요일






개발자 커뮤니티

Sun






구글














One Week of Google Maps - Part 1, Part 2, Part 3, Part 4, Part 5, Part 6, Part 7




도조 Dojo





















돔 DOM








브라우저 Browser







씨에스에스 CSS















애이작스 AJAX(XMLHttpRequest 포함)와 RIA


Ajax 강의 21회








































































































Remote Scripting with AJAX, Part 1


































애이작스 온 위켓 AJAX on Wicket



웹 보안


웹 UI 컴포넌트





웹 2.0










웹 표준 적용







자바 스크립트 JavaScript(DHTML 포함)




















































JSON












캔버스 Canvas  



프로토타입(Prototype), Script.aculo.us






















Protowidget


폼 처리





피쓰리피 P3P



[사이트 링크]


CometとAJAX CHATの作り方について整理

AJAXでCHATを作る場合のパターンについて、現時点で集めた情報をまとめてみました。
前提

JavaScript は、HTTP通信オブジェクトである XMLHttpRequest を持つためにブラウザの再読込なしにデータの送受信が可能です。また、JavaScriptはDOMを扱うことができるのでHTMLの要素を自由に書き換えることができます。(innerHTMLを用いても可) この二つの特徴を生かすと、ブラウザの再読込なしにHTTP経由で受け取ったデータをHTMLに表示することができます。
このような技術を用いて CHATを作ると、画面遷移(リロード)のない高速なCHATを構築することができます。あたかも IRCクライアントのようにWebページにログを書き出していくことができるわけです。これがAJAXでCHATを行う場合のメリットです。

ここまでは、AJAXでCHATを作るメリットについての前提条件です。紛らわしいので、以下、JavaScriptという記述はAJAXに統一します。
二つの方法

AJAX(XMLHttpRequest)を利用したCHATの実装方法は大きく分けて二つあります。

1. ポーリング(polling)による実装
2. Cometによる実装

ポーリングによるCHATの実装

ポーリングとは、一定間隔おきにサーバにリクエストを送り、データの変化を確認する処理を意味します。前世紀から存在する一般的なWEB CHATアプリケーションで行われていた処理と同じ考え方です。要するに"自動 F5 連打"ですね。

AJAXでポーリングを行うCHATを作る場合、下記のような内容が考えられます。

* 対象ファイルのサイズ(Content-Length)、更新日(Last-Modified)などの情報を取得して最新かどうかを確認する。この場合のリクエストはGETではなくHEADが望ましい
* 最新である場合にはデータを取得する。直近のデータサイズを保持しておき、If-Modified-Since+Rangeヘッダ付きのGETで差分のみを取得することが望ましい(Range: bytes=開始位置-終了位置)

これはログデータをファイルとして管理する前提なので、データベースを用いる場合には一工夫必要になります。ポーリングの問題点は、問い合わせの間隔が長いとリアルタイム性が失われる事、問い合わせの間隔が短いとサーバ側の負荷が極めて高くなることです。

これがどのぐらい深刻な問題かと言うと、1000ユーザが同時接続している状態で、1秒に1度の間隔でポーリングを行うと、計算してみるとわかりますが月間で26億ヒットとなり、「なにもせずブラウザを開いているだけで」グーグルのページビュー(12億)を超えるアクセス(!!)が殺到することになります。
http://blog.japan.cnet.com/kenn/archives/003149.html

要するにたいていの AJAX は Asynchronous と言いつつも1秒おきだのでポーリングしてるわけですね。

http://d.hatena.ne.jp/shinichiro_h/20060409#1144563467

ということで、AJAXといいながら Asynchronous = 非同期通信 ではなかったりもします。


Cometによる実装

Cometとは、AJAXと同じように規格の名称ではなく特定の技術の利用方法についての名前です。はWeb アプリケーションでサーバプッシュを実装する場合の総称、と言えるようです。プッシュ技術ではクライアントからサーバにリクエストするのではなく、サーバからデータを送信するという考え方であるため、ポーリングすることなくリアルタイムにデータを取得することができます。Cometは擬似的にこのサーバプッシュを実現します。

Cometについては引用が手っ取り早いのでさくっと引用します。

Cometでは、まずブラウザ側があらかじめサーバに対してHTTPリクエストを発行しておき、サーバ側はそのリクエストに対してレスポンスを返さずにずっと掴んだままにしておきます。そして、別の経路でサーバがキック(メッセージを送信)されたら、それまで掴みっぱなしになっていた複数のリクエストに対して一斉にメッセージを乗せてレスポンスを返すことで、擬似的にサーバからのプッシュを実現するのです。そして、ブラウザはすぐさまリクエストを再発行してふたたび応答待ちの状態へと戻る。まさに逆転の発想なのです。

http://blog.japan.cnet.com/kenn/archives/003149.html

HTTPを使って、擬似的にサーバからのプッシュを実現する技術。サーバやネットワークへの負荷を抑えつつ、情報の更新をすぐにブラウザに反映させることができる。基本的な仕組みは以下の通り。

* ブラウザ側があらかじめHTTPリクエストを発行しておく。
* サーバは、そのリクエストにすぐにレスポンスを返さずに保持しておく。
* サーバで何かイベント(情報の更新など)が起きたら、保持していたリクエストに対して(新しい情報を含む)レスポンスを返す。
* ブラウザ側はレスポンスを処理し、すぐに次のリクエストを発行する。
* これを繰り返す。

http://d.hatena.ne.jp/keyword/Comet

Cometの実装にはいくつかの種類があります。

* long-pollでの実装

long-pollについても引用します。

クライアントからの要求をうけたサーバは、HTTPリクエストを一時停止(suspend)し、タイムアウトか非同期イベントが発生した後に、再開(resume)し、クライアントに応答します。HTTPリクエストを一時停止している間、クライアントはサーバからの応答を待つことになります。

サーバからの応答があった時点で、ポーリングのように再び要求を出すことで、HTTPコネクションをつかみっぱなしにしている状態を仮想化します
http://www.panet.co.jp/report/long_pollPush.htm


HTTP コネクションを永続的に張り続けるのではなく、サーバからレスポンスがあった場合にコネクションを張り直すものをlong-pollと呼ぶようです (?)。が、Comet = long-pollのように書かれているものもありちょっと混乱します。いずれは同義になるのかもしれません。おそらくlong-pollがCometの最も一般的な実装なのではないかと思いますが、そもそも現時点でCometが一般的ではありません。

* iframeによる実装

非表示にしたiframe要素に、元ページ(parent)にアクセスするscriptタグを徐々に出力することでサーバプッシュを実現する実装。多分この辺に書いてあると思いますが、あんまり興味ないので読んでいません。この方法だとブラウザはずっと読み込み中になるとのことです。

* multipart/x-mixed-replaceによる実装

multipart/x-mixed-replaceによる実装はFirefox依存らしいので調べていません。

※上記の三つの実装はWEB+DB PRESS Vol.34 の館野氏の記事で紹介されています。
イベントドリブン

Cometはサーバプッシュにてリアルタイム性を実現する技術であるため、サーバにデータ追加等の変化が発生した場合にクライアントに通知するような実装を行う必要があります。このように、ユーザや他のプログラムが実行した操作に対応して処理を行なうプログラムの実行形式をイベントドリブンと呼ぶようです。これには下記の種類があります。

* POE/Twisted/Jetty/dRuby/mpm_event_module
* SIGUSR1を使った実装

LingrはJettyを用いた実装、AJA CHAT(解説)はSIGUSR1をトラップする実装らしいです。

まだ調べてきれてはいませんが取りあえずのまとめでした。


※参考

・日経ソフトウエア 2007年1月号 Comet――プッシュ型のWebアプリケーションを作る 結城浩
・WEB+DB PRESS Vol.34 Comet - サーバプッシュ型Ajax 館野祐一
・Ajax 実装のための基礎テクニック
・多数のブログ

prototype.js の開発者向けメモ

http://www.imgsrc.co.jp/~kuriyama/prototype/prototype.js.html#toc

Ajaxアプリケーション開発における7つの大罪

7つの小罪

  1. 「戻る」ボタンの誤用--これは誰もが犯す過ちである。「戻る」ボタンは、さまざまなウェブアプリケー ションにおいてあって当然と思われているボタンだ。ところが、経験の浅い多くのAjax開発者はいくつかの理由から、「戻る」ボタンをAjaxアプリケー ションに組み入れてしまい、結果としてユーザーの期待を裏切ってしまうのである。この理由としてはまず、「戻る」ボタンの処理を行ううえで JavaScriptが最適の言語ではないということが挙げられる。次に、Ajaxの設計では新たな考え方が要求されるという理由がある。
    「戻る」ボタンは最適ではないということが、経験の浅いAjax開発者にとってすぐに判るとは限らない。「戻る」ボタンは、イベントに特化した「元に戻 す」機能を使いたい場合に、ページ更新のタイミングか、それよりも頻繁に必要となる機能である。この点について、コーディングを開始する前によく考えてお くべきである。さもなければ、同じことを2度行う羽目になってしまうはずだ。

  2. 何が起こっているかをユーザーに知らせない--Ajaxを使用すると、ブラウザが提供しているウェブユーザーインタフェースではページのロード状況を完全には把握できなくなる。このため、何が起こっているのかをユーザーに対して明示的に伝えるために、視覚的な手がかりを組み込んでおく必要があるのだ。

  3. リンクを設けない--これもAjaxで犯してしまいがちな過ちである。つまり、ユーザーがアプリケー ションの外でコピーアンドペーストできるようなURLを設けておかないという過ちだ。あなたも、URLをコピーして誰かに電子メールで送るという行為を何 度も行っているはずだ。Ajaxにおいて、ユーザーがコピーアンドペーストできるようなURLを提供する唯一の方法は、手作業でそれを提供することであ る。なぜだろうか?Ajaxアプリケーションでは「サーバが該当ページを応答してくるわけではない」からである。JavaScriptが動的に生成してい るのだ!ウェブアプリケーションサーバによって提供されることが当たり前になっているこの機能に対するユーザーの潜在的な需要を軽視してはいけない。サー バはURLを提供しないため、あなたが手間をかけてそれを提供する必要があるのだ。

  4. ページ制御のためにコンテンツ制御を犠牲にする--動的なコンテンツ制御を模索している場合、従来のよ うな方法でクライアントとサーバとの間のやり取りを行わなくてもよいという仕組みは、とてもありがたいものであるはずだ。しかし、これには弊害もある。 ユーザーのエクスペリエンスを洗練したものにするために、ページの特定の領域を再描画することで、きめの細かい制御を行えることは確かである。しかし、こ れによってあなたはもっと大きなものを見失ってしまうのだ。
    われわれは、ページの特定部分の処理に気を取られるあまり、そのページ全体がサーバによってリフレッシュされないということを忘れてしまいがち になる。こういったことにより、ページの断片化が起こったり、ユーザーの閲覧しているページ自体の情報が古くなるため、ユーザーエクペリエンスに混乱がも たらされたりすることもあるのだ!常にページ全体に気を配るようにし、動的なコンテンツ変更を引き起こすイベントによって、ユーザーの目に触れる部分すべ てが確実に変更されるようにしよう。

  5. スパイダを遮断する--Ajaxのメリットは、ページをリロードすることなしに膨大な量のテキストを フィードすることができる点にある。そしてこの点はAjaxのデメリットでもある。もしも検索エンジンに優しいアプリケーションを開発したければどうすれ ばよいのだろうか--あなたにも判るはずだ。ページの中身がどのようなものであれ、コンテンツを如実に物語るテキストを、スパイダが処理できるようにペー ジの上部にたくさん埋め込んでおくのである。

  6. 読めないテキストを生成する--Ajaxがサポートしている文字セットの数はそれほど多くはない。これ は生死にかかわる制限ではないものの、このことを忘れると大きな問題を引き起こすおそれがある。基本的な文字セットはUTF-8である。 JavaScriptが送信する内容がどのようなものであれ、適切にエンコードしておくことを忘れないようにしよう。また、サーバ側のコンテンツに文字 セットを設定しておくことも忘れないようにしよう。

  7. JavaScriptを使用していないユーザーに対して、何が起こっているのかを知らせない--JavaScriptを利用できないブラウザというものも存在しており、それが意味していることをすぐに理解できないようなユーザーも存在している。こういったユーザーに対して、何が起こっているのかが判るようなヒントを与えるようにしよう。