Channel APIによるクライアント=サーバー双方向通信 (1/5)
作成:2012-07-08 09:41
更新:2012-07-08 10:12
更新:2012-07-08 10:12
■Channel APIとは何か?
HTMLはさまざまな使われ方をされるようになってきていますが、しかし苦手なものというのはあります。その一つが「連続した接続を維持すること」でしょう。HTMLは、1回毎にサーバーにアクセスしては接続が切れる、といったことを繰り返していますので、サーバーとクライアントの間での通信を維持し続けることはできないのです。これができないと、いわゆるPUSH配信(サーバーから必要に応じてクライアントに送信をする方式)などが行えません。
Ajax技術の発達により、擬似的にPUSH通信を可能にするものも登場するようになりました。HTML5では、これを更に進めたServer-Sent Eventや、新たなプロトコルを利用するWeb Socketといった技術も登場しました。
が、こうした技術は、まだ完全には広まっていません。IEが対応していないということもありますし、Web SocketなどはHTTPサーバーとは別に専用サーバーを用意しなければならず、敷居の高いものになっています。
既存のブラウザやサーバー環境で、既存の技術を使って、擬似的にでも永続的な通信によるPUSH配信技術を確立する――こうした考えのもとに作られたのが、Google App Engineに搭載されている「Channel API」です。
Channel APIは、クライアントとサーバーの間で永続的な通信を擬似的に確立します。これはサーバー側のプログラムで使用するJavaのクラスライブラリと、クライアント側で利用されるJavaScriptライブラリによって構成されています。
この種の技術では、大きく分けて2つの重要な要素が必要となります。1つは、サーバーとクライアントの間で「どうやってお互いを識別するか」という問題。基本的にHTTPでは永続的な通信は行えないのですから、お互いにアクセスした際に「このアイテは誰か」をきちんとわかるようにする必要があります。そしてもう1つが「サーバーからクライアントへどのように送信をするか」という問題です。Channel APIは、これらをうまく解決する技術を提供してくれます。
用意されたライブラリで、チャンネルを利用するための仕組みは提供されますが、それをただ呼び出せばいいだけ、というわけではないので注意が必要です。両者の間を結びつけるための情報を正しく受け渡す方法も考える必要があります。
では、Channel APIによるクライアントとサーバーのやり取りがどのような形で行われるのが、その基本的な流れをざっと整理していきましょう。
1. クライアント側:チャンネルキーを用意
Channelによる通信では、両者をつなぐチャンネルを作成するのに「チャンネルキー」と呼ばれるものが必要となります。このキーごとにチャンネルが作成され割り当てられるわけです。ですから、まずはクライアント側でユニークなチャンネルキーを用意し、サーバー側にそれを知らせます。
2. サーバー側:ChannelServiceを作成する
クライアントから受け取ったチャンネルキーを使って、「ChannelService」というものを作成します。これがチャンネルを作成し、それを利用するサービスを管理します。ChannelServiceを作ると、そのチャンネルに固有の「トークン」が作成されます。
3. クライアント側:トークンを受け取る
このトークンはチャンネルごとに割り当てられるランダムな英数字の羅列のような値です。チャンネルキーが違えばトークンも変わります。つまり、あるチャンネルキーと、それによって作成されたチェンネルのトークンは対になっているわけです。これをクライアント側に渡します。これで、「クライアントが用意したチャンネルキー=それによってサーバー側で作られたチャンネル=それによって生成されクライアントに返されたトークン」という一連のやり取りが完了し、チャンネルの用意ができました。
4. クライアント側:goog.appengine.Channelを作成する
では、クライアント側からチャンネルへの接続をオープンします。これはライブラリで提供されているgoog.appengine.Channelというオブジェクトを作成して行います。サーバーから渡されたトークンを指定してgoog.appengine.Channelを作成することで、そのトークンのチャンネルとの接続が開始されます。後は、必要に応じてメッセージを送信したり受け取ったりするだけです。
5. メッセージ送信(クライアント側)
クライアントからサーバーへメッセージを送信するには、XMLHttpRequestオブジェクトを使います。そう、普通のAjax通信と同じなのです。ただし、このときに「どのチャンネルから送られたものか」がわかるように、チャンネルキーを受け渡すようにする必要があるでしょう。サーバー側は、普通にdoGetやdoPostで処理すればいいだけです。
6. メッセージ送信(サーバー側)
サーバーからクライアントへとメッセージを送るには、ChannelServiceの「sendMessage」というメソッドを呼び出します。このメソッドでは、送信するチャンネルを指定するためのチャンネルキーと送信メッセージをまとめた「ChannelMessage」というクラスのインスタンスを用意し、これを渡すようになっています。
受け取るクライアント側では、先にgoog.appengine.Channelオブジェクトを作成した時、このオブジェクトのonmessageイベントに割り当てられていたメソッドが呼び出されます。ここでメッセージを受け取った際の処理を用意すればいいわけです。
――以上、全体の流れがだいたいつかめたでしょうか。では、実際にコードを書きながらチャンネルを使ってみましょう。
Ajax技術の発達により、擬似的にPUSH通信を可能にするものも登場するようになりました。HTML5では、これを更に進めたServer-Sent Eventや、新たなプロトコルを利用するWeb Socketといった技術も登場しました。
が、こうした技術は、まだ完全には広まっていません。IEが対応していないということもありますし、Web SocketなどはHTTPサーバーとは別に専用サーバーを用意しなければならず、敷居の高いものになっています。
既存のブラウザやサーバー環境で、既存の技術を使って、擬似的にでも永続的な通信によるPUSH配信技術を確立する――こうした考えのもとに作られたのが、Google App Engineに搭載されている「Channel API」です。
Channel APIは、クライアントとサーバーの間で永続的な通信を擬似的に確立します。これはサーバー側のプログラムで使用するJavaのクラスライブラリと、クライアント側で利用されるJavaScriptライブラリによって構成されています。
この種の技術では、大きく分けて2つの重要な要素が必要となります。1つは、サーバーとクライアントの間で「どうやってお互いを識別するか」という問題。基本的にHTTPでは永続的な通信は行えないのですから、お互いにアクセスした際に「このアイテは誰か」をきちんとわかるようにする必要があります。そしてもう1つが「サーバーからクライアントへどのように送信をするか」という問題です。Channel APIは、これらをうまく解決する技術を提供してくれます。
用意されたライブラリで、チャンネルを利用するための仕組みは提供されますが、それをただ呼び出せばいいだけ、というわけではないので注意が必要です。両者の間を結びつけるための情報を正しく受け渡す方法も考える必要があります。
■チャンネルによるクライアント=サーバー通信の流れ
では、Channel APIによるクライアントとサーバーのやり取りがどのような形で行われるのが、その基本的な流れをざっと整理していきましょう。
1. クライアント側:チャンネルキーを用意
Channelによる通信では、両者をつなぐチャンネルを作成するのに「チャンネルキー」と呼ばれるものが必要となります。このキーごとにチャンネルが作成され割り当てられるわけです。ですから、まずはクライアント側でユニークなチャンネルキーを用意し、サーバー側にそれを知らせます。
2. サーバー側:ChannelServiceを作成する
クライアントから受け取ったチャンネルキーを使って、「ChannelService」というものを作成します。これがチャンネルを作成し、それを利用するサービスを管理します。ChannelServiceを作ると、そのチャンネルに固有の「トークン」が作成されます。
3. クライアント側:トークンを受け取る
このトークンはチャンネルごとに割り当てられるランダムな英数字の羅列のような値です。チャンネルキーが違えばトークンも変わります。つまり、あるチャンネルキーと、それによって作成されたチェンネルのトークンは対になっているわけです。これをクライアント側に渡します。これで、「クライアントが用意したチャンネルキー=それによってサーバー側で作られたチャンネル=それによって生成されクライアントに返されたトークン」という一連のやり取りが完了し、チャンネルの用意ができました。
4. クライアント側:goog.appengine.Channelを作成する
では、クライアント側からチャンネルへの接続をオープンします。これはライブラリで提供されているgoog.appengine.Channelというオブジェクトを作成して行います。サーバーから渡されたトークンを指定してgoog.appengine.Channelを作成することで、そのトークンのチャンネルとの接続が開始されます。後は、必要に応じてメッセージを送信したり受け取ったりするだけです。
5. メッセージ送信(クライアント側)
クライアントからサーバーへメッセージを送信するには、XMLHttpRequestオブジェクトを使います。そう、普通のAjax通信と同じなのです。ただし、このときに「どのチャンネルから送られたものか」がわかるように、チャンネルキーを受け渡すようにする必要があるでしょう。サーバー側は、普通にdoGetやdoPostで処理すればいいだけです。
6. メッセージ送信(サーバー側)
サーバーからクライアントへとメッセージを送るには、ChannelServiceの「sendMessage」というメソッドを呼び出します。このメソッドでは、送信するチャンネルを指定するためのチャンネルキーと送信メッセージをまとめた「ChannelMessage」というクラスのインスタンスを用意し、これを渡すようになっています。
受け取るクライアント側では、先にgoog.appengine.Channelオブジェクトを作成した時、このオブジェクトのonmessageイベントに割り当てられていたメソッドが呼び出されます。ここでメッセージを受け取った際の処理を用意すればいいわけです。
――以上、全体の流れがだいたいつかめたでしょうか。では、実際にコードを書きながらチャンネルを使ってみましょう。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
※関連コンテンツ
「Google App Engine for Java(GAE/J)プログラミング入門」に戻る