2009年5月28日、Googleのデベロッパーカンファレンス「Google I/O 2009」のキーノートにおいて大々的に発表されたGoogle Waveは、聴衆に熱狂を持って迎えられました。そのキーノートにおいてスピーカーは「Google WaveはProductであり、Platformであり、Protocolだ」と述べました(編注)。
本連載ではその3つのPの内の2つ目、PlatformとしてのGoogle Waveについて説明します。
なお、Google Waveは現在も急ピッチで開発が進められているプロダクトであり、本連載に掲載する画面遷移・ソースコードなどは最新ではない可能性があります。記事に沿って作業していて違和感を覚えた場合にはGoogleの公開しているドキュメントを適宜参照してください。
API概観
私たち開発者から見えるPlatformとしてのGoogle Waveは3種類のAPIからなります。
Robots API |
Extensions |
Waveを拡張するためのAPI |
Gadgets API |
Wave Embed API |
Waveの機能を外部から利用するためのAPI |
APIごとの違いを大まかに説明すると以下のようになります。
- Robots API
- Waveでの入力をサーバ側で処理をするためのAPI。例:チャットボット(人工無能)
- Gadgets API
- クライアント側でWave内のイベントを処理をするためのAPI。JavaScriptで記述することが多い。例:Google Mapガジェット
- Wave Embed API
- Google Wave以外のサービスにGoogle Waveの機能を組み込むためのAPI
3つのうちRobots APIとGadgets APIはGoogle Wave自体に機能を追加するAPIとしてExtensionsと呼ばれ、Wave Embed APIとは区別されています。
連載第1回目の今回は、上記3つのうちExtensionsに所属するGadgets APIについて説明します。公式ドキュメントではRobots APIが先に説明されていますが、Gadgets APIはGoogle Waveの大きな特徴の一つであるリアルタイム通信を扱うAPIであることと、Robots APIがGadgets APIを操作することもできるAPIであることから、Gadgets APIを先に説明した方がわかりやすいでしょう。
Gadgets API
シンプルなガジェット
ガジェットとはHTML、CSS、JavaScriptなどをXMLで包みiGoogleやOpenSocial等のコンテナに機能を追加するための仕組みで、Google Waveのガジェットも基本的にはiGoogleやOpenSocial等と全く同じです。これは実際にソースコードを見た方が早いでしょう。公式ドキュメントから引用してみます。
<Require feature="rpc" /> タグでRPCコールの使用を宣言している部分と、<Content>タグ内部でwave.jsスクリプトを読み込んでいる部分が特徴的ですが、このシンプルな例ではiGoogleなどのガジェットと何ら変わるところがないことが理解できるでしょう。
ガジェットの実行
それではガジェットを実際にWave上で実行してみましょう。ガジェットのXMLにはグローバルなURIが必要ですが、本XMLはすでにhttp://gadget-doc-examples.googlecode.com/svn/trunk/wave/hello.xmlに用意されていますので、このURIをそのまま使います。
まずは真ん中のWaveにある「New Wave」ボタンを押下して新規にWaveを開きます。
画面右上の、ユーザー名の隣にある「Debug」ボタンを押下します。
メニューから「Add Gadget」を選択すると「Gadget gallery」が開きます。
Gadget galleryの一番下にある「URL of gadget module XML」テキストフィールドにガジェットXMLのURIを入力し、「Add by XML」ボタンを押下すると、先ほど作成したWaveに指定したガジェットが挿入されます。
挿入されたガジェットに先ほどXMLで指定した Hello, Wave! が表示されていることを確認してください。
Shared Stateを使用したガジェット
ここまでで非常にシンプルながらWave上に自作のガジェットを表示することに成功しました。しかしこのままでは何かが足りないと思いませんか?
そうです。まだこのガジェットにはWave参加者のリアルタイムなやり取りが実装されていません。参加者同士でリアルタイムにデータをやり取りするにはShare Stateと呼ばれるKey-Value型のオブジェクトを使用します。これもまずは公式ドキュメントの例を見てみましょう。
上記のソースで赤くなっている部分がそのShared Stateを扱っている箇所です。3種類の関数しか使われていないので抜き出してみます。
- wave.setStateCallback(FUNCTION)
- Shared Stateが変更したときに呼び出されるコールバック関数として、FUNCTIONを設定する
- wave.getState().submitDelta({KEY: VALUE})
- Shared StateにKEYに対応する値としてVALUEを設定する
- wave.getState().get(KEY)
- Shared StateからKEYに対応する値を取得する
全体の流れとしては、以下のとおりです。
- wave.getState().get(KEY)関数を使って変更された状態を処理するハンドラを作成する(例ではstateUpdated関数)
- 作成したハンドラをwave.setStateCallback(FUNCTION)関数でShared State変更時のコールバックに登録しておく
- 何らかのイベントが発生してwave.getState().submitDelta({KEY: VALUE})関数が呼び出されたときに全参加者のコールバック関数が実行される
では、前項の手順にしたがってWave上にガジェットを追加し、実行してみましょう。
ある参加者がボタンをクリックすると、全ての参加者のガジェットでカウンタの表示がインクリメントされました。このようにWaveガジェットでは Shared Stateを使って非常に簡単にCometを利用した参加者同士のリアルタイムなやりとりが実装できます。
そして、Shared Stateを使う利点はこれだけではありません。今度はWave上部の「Playback」(再生)ボタンを押下してみましょう。
ツールバーが変更され、巻き戻し・早送りボタンとスライダが表示されました。スライダを移動したりボタンを押下するとWaveの状態が巻き戻されて、今回の場合であればカウンタの値が減って行きます。このようにWaveではShared Stateの変更はすべて履歴に保存されていて、ガジェット開発者がなにも意識しなくてもPlayback機構は正しく動作します。
まとめ
基本的なガジェットの作成方法は以上のようになります。いかがでしょうか? iGoogle、OpenSocialなどでガジェットを作成したことのある人であれば、リアルタイム通信やプレイバックなどのWaveの機能を利用するWaveガジェットも非常に簡単に作れることが分かると思います。またガジェット未経験の方も、ガジェットは結局のところはHTML、CSS、JavaScriptなどの既存のWebページと同じ構成要素をXMLで包んだだけのものであって、特に心配する必要はないことが分かったでしょう。
Waveは現在デベロッパープレビューとして公開されていますが、Developer Sandboxもまだこちらのサイトでアカウントのリクエストが開始されたばかりで、実際にアクセスできる人のほとんどいない、謎の多いサービスだと思います。
本連載がその疑問に少しでも答えられるものになっていると嬉しく思います。
次回はもう一つのExtensions、Robots APIについて説明します。お楽しみに。