作成日

17 November 2009

必要条件

この記事に必要な予備知識

Flash Builderの使用経験があれば役立ちますが、必須ではありません。この記事のサンプルアプリケーションはFlash Builder 4beta 2、Flex SDK 3.4およびAIR 2.0 SDK betaで作成しています。

ユーザーレベル

すべて

その他の要件

この記事を最大限に活用するには、次のソフトウェアが必要です。

  • Flash Builder 4 beta 2
  • AIR 2.0 SDK beta

ソースコードの取得

SORAAIは、AIR 2.0の新API利用サンプルとして参照できるようにソースコードを公開しています。

重要: このサンプルアプリケーションは、AIR 2 betaの機能を体験するために作成されています。お試しになる場合は、AIR 2 beta ランタイムを先にインストールする必要があります。なお、既にAIR 1.xのランタイムがOSにインストールされている場合は、上書きされてしまいますのでご注意ください。元に戻す場合は、AIR 2 beta ランタイムをアンインストールし、AIR 1.5.2 ランタイムをインストールします。詳細はリリースノート(英語) をご覧ください。

はじめに

AIR 2.0 beta版が、今月リリースされました。AIR 2.0新API(以降、新APIと呼ぶ)として加わる新しいネットワーキング機能のサポート、ネイティブアプリ起動、デフォルトアプリで開くなどにより、AIRアプリケーションの可能性はAIR 1.xに比べ飛躍的に向上します。

この記事では、新APIである新しいネットワーキング機能のサポートを利用したサンプルアプリケーションSORAAI(そらあい)のコードを交えて、新APIを解説します。

SORAAIのコンセプト

楽しい時間は早く過ぎ、つまらない時間は長く感じる。逆であって欲しいですよね。勉強会もそうじゃないですか?

今回開発したSORAAIは、勉強会、講演など時間制限のあるイベントで活用できるタイマー機能、スピーカー/オーディエンス間のリアルタイムコミュニケーション機能を持つツールです。オーディエンスの「楽しい」「つまらない」という反応を「へぇ」「ぶぅ」プロトコルに変換し、ネットワークを通じてタイマーの残り時間に反映します。

スピーカーには、リアルタイムにオーディエンスの反応が伝わる恐ろしくも楽しいツールとなるでしょう。

機能について

コンセプトでも書いたように、SORAAIにはタイマー機能、スピーカー/オーディエンス間のコミュニケーション機能があります。

・タイマー機能

勉強会、講演などのセッションの残り時間を計測する機能です。
セッション中に、残り時間を表示し(カウントダウン)、残り時間がゼロとなった時にスクリーンに表示している画面を覆い隠し、強制的にセッションを打ち切ります。セッションには、ボーナス時間というオーディエンスのセッションに対する反応によって変動する時間枠を設定できます。例えば、セッション時間30分、ボーナス時間5分と設定すると、オーディエンスの反応次第でセッション時間は25分~30分の幅で変動します。オーディエンスがセッションに対して感じた「へぇ」「ぶぅ」のフィードバックが、このボーナス時間の増減によってセッション時間に反映されることになります。

・コミュニケーション機能

オーディエンスのセッションに対する反応をスピーカーの元へとリアルタイムに伝達する機能です。
楽しければ「へぇ」、つまらなければ「ぶぅ」という反応にコメントをプラスして送信します。この機能は、新API(新しいネットワーキング機能のサポート)を利用して実現しています。さらに、ネットワーク構成の影響により新API(新しいネットワーキング機能のサポート)が対応できないケースを考慮して、twitterのtweetからもスピーカーはオーディエンスのフィードバックを受け取れます。

SORAAIを使用するユーザーには、スピーカーとオーディエンスという2つの役割があります。その役割に合わせて、サンプルアプリケーションのモードを使い分けることになります。

・スピーカーモード

スピーカーが使用するモードです。このモードでは、セッションの間、画面の最前面にセッション残時間を表すタイムラインと、オーディエンスからの「へぇ」「ぶぅ」という反応がリアルタイムに表示されます。セッション終了後には、セッションの間に受け取った「へぇ」「ぶぅ」の集計結果を確認できます。

・オーディエンスモード

オーディエンスが使用するモードです。このモードでは、スピーカーが行っているセッションに対して、「へぇ」「ぶぅ」のフィードバックを送ることができます。送った「へぇ」「ぶぅ」のフィードバックは、スピーカーの画面上にリアルタイムに表示され、セッションの残時間の増減に反映されます。

使用したAPIの解説

SORAAIの開発で使用した新APIは主にNetworkInfoというネットワークインターフェイス情報を取得するためのAPIと、 DatagramSocket、ServerSocketという2つのソケット接続用APIです。DatagramSocketおよび ServerSocketが追加されたことで、AIRアプリケーションはサーバーとして別アプリケーションからの接続を待ち受けることができるようになりました。
ビルドに関しては、AIRファイルのインストーラーではなく、OSネイティブなインストーラー(ネイティブインストーラー)を作成できるようになっています。

・NetworkInfo

意外にも、AIR 1.5までのアプリケーションでは、OSに割り振られたローカルアドレスといったネットワークインターフェイスの情報を取得することができませんでした。AIR2.0からは、NetworkInfoとそれに付随する新しいクラス群によって様々なネットワークインターフェイス情報を取得することが可能となりました。

SORAAIではNetworkInfoクラスからネットワークインターフェイス情報を取得することで、スピーカー/オーディエンスの接続設定をスムーズに行えるようにしています。

・DatagramSocket

DatagramSocketを用いることで、AIRアプリケーション同士、またはUDP通信機能を実装した他のアプリケーションとUDPプロトコルを用いた相互通信を行うことが可能となります。
SORAAIでは、オーディエンス側のアプリケーションが検索用データをDatagramSocketを用いてブロードキャストで送信し、同一LAN内にいるスピーカー側のアプリケーションを自動的に探索します。
(詳細、およびソースコードを交えた解説は後ほど行います。)

・ServerSocket

ServerSocketはTCPプロトコルを用いてアプリケーション間の通信を可能にするクラスです。DatagramSocket(UDPプロトコル)との違いは、データを送信したら受信を確認しないDatagramSocketと異なり、ServerSocketを用いた通信は相手とデータの受け渡しを確認しながら行うため確実なデータ通信を可能にします。
SORAAIではスピーカー側のアプリケーションがServerSocketを用いたサーバーとして動作しています。

・ネイティブインストーラー

ADT Toolを使用することで、Windows用、Mac用のネイティブインストーラーを作成できるようになりました。Windows用であればEXE形式のインストーラー、Mac用であればDMG形式のインストーラーを作成します。なお、インストーラーの作成の際に使用するADT Toolは、作成したいインストーラーと同じOS用のものでなければならないという制限があります。

機能と該当ソースコードによる解説

ここではAIR2.0の新APIの使用方法を、SORAAIのソースコードを参考に紹介していきます。
(新APIの使用方法を説明する上で不要なエラー処理などの部分は省略してあります。)

・NetworkInfo

下記のソースコードでは、NetworkInfoのfindInterfacesメソッドを呼び、ネットワークインターフェイスの一覧を取得しています。
(net.fxug.hokuriku.chocolat.model.NetworkInterfaceManager.as getNetworkInterfaceDataList()メソッド内)

var networkInfo:NetworkInfo = NetworkInfo.networkInfo; var networkInterfaceList:Vector.<NetworkInterface> = networkInfo.findInterfaces();

NetworkInfoクラスは、上記以外にCHANGEイベントでネットワークインターフェイス情報が変更されたことを取得する用途に用いることができます。ネットワークインターフェイス情報は、無線LAN、有線LAN、仮想マシンの仮想ネットワークが複数存在することがあるため、Vectorとして返されます。NetworkInterfaceクラスからはネットワークインターフェイス情報として、IPアドレスのほか、MTU値、ネットワーク名、 MACアドレスなどが取得できます。

NetworkInterfaceクラスを用いた実装は以下のようになります。
(net.fxug.hokuriku.chocolat.model.NetworkInterfaceManager.as getNetworkInterfaceDataList()メソッド内)

for each (var networkInterface:NetworkInterface in networkInterfaceList) { // ネットワークインターフェイスがアクティブなら if (networkInterface.active) { // アドレス一覧を取得 var addressList:Vector.<InterfaceAddress> = networkInterface.addresses; for each (var address:InterfaceAddress in addressList) { //(省略、データをまとめる処理) } } }

上記コードでは有効なネットワークインターフェイスからIPアドレスを取得しています。AIR2.0ではIPv6のサポートがされているのですが、SORAAIでは諸所の事情もありIPv4のみを扱うこととしました。IPアドレスがIPv6の形式か、IPv4の形式かどうかはInterfaceAddressクラスのipVersionプロパティから取得可能です。 ipVersionプロパティには、6や4といったIPアドレスのバージョン情報が入っています。

・DatagramSocket

SORAAIでは、オーディエンス側のアプリケーションがスピーカー側のアプリケーションを探索するために、DatagramSocketを用いてブロードキャストを行っています。その基本的な利用方法とブロードキャストの解説を行います。

以下のようなソースコードで、アプリケーションはbindメソッドに渡した引数localPortのポート番号、localAddressで渡したIPアドレスで接続を待ち受けることが可能になります。他のアプリケーションからデータを受けた場合は、 DatagramSocketDataEvent.DATAイベントが呼び出されます。このlocalPortとlocalAddressの値が分かれば、他のアプリケーションはこのアプリケーションとの通信が可能になります。
(net.fxug.hokuriku.chocolat.service.Sonar.as receive()メソッド内)

var datagramSocket:DatagramSocket = new DatagramSocket(); datagramSocket.bind(localPort, localAddress); datagramSocket.addEventListener(DatagramSocketDataEvent.DATA,dataReceivedEventHandler); datagramSocket.receive();

以下はDatagramSocketを用いてデータを送信するソースコードです。sendメソッドでデータ送信先のremoteAddress とremotePortを指定しています。送信するデータはString型ではなくByteArray型を用いているところに注意してください。
(net.fxug.hokuriku.chocolat.service.Sonar.as ping()メソッド内)

var datagramSocket:DatagramSocket = new DatagramSocket(); var_message:ByteArray = new ByteArray(); message.writeUTFBytes(“Hello”); datagramSocket.send(message, 0, 0, remoteAddress, remotePort);

DatagramSocketの説明の最後に、もう一度待ち受け側にもどって、送られてきたデータの取得方法を確認してみましょう。
(net.fxug.hokuriku.chocolat.service.Sonar.as dataReceivedEventHandler()メソッド内)

private function dataReceivedEventHandler(event:DatagramSocketDataEvent):void { var message:String = event.data.readUTFBytes(event.data.bytesAvailable); (以下省略)

DatagramSocketを用いてデータを送信する側が、writeUTFBytesメソッドでByteArray型に変換していたのに対して、受信する側はreadUTFBytesを用いてString型に戻しています。
以上がDatagramSocketの基本的な使い方です。

SORAAIでは、ブロードキャストの仕組みを使って、オーディエンス側のアプリケーションはネットワーク内からスピーカー側のアプリケーションを探索しています。
ブロードキャストアドレスは、先ほど説明しましたNetworkInfoクラスから取得できるInterfaceAddress.broadcastパラメーターから取得できます。アプリケーションを実行しているマシンのIPアドレスが192.168.1.24の場合、おそらくbroadcastの値は 192.168.1.255になっているでしょう。このIPアドレス(192.168.1.255)を宛先にすることで、同じローカルネットワーク内のすべてのマシンにデータを送信することが可能になります。その中の待ち受け状態にあるスピーカー側のアプリケーションが、ブロードキャストを行ったオーディエンス側のアプリケーションにデータを返すことでお互いのネットワークインターフェイス情報を取得、確立するというのがSORAAIのブロードキャストを用いた仕組みです。

・ServerSocket

SORAAIでは、オーディエンス側のアプリケーションはブロードキャストを用いてスピーカー側のアプリケーションを見つけた後は、ServerSocketを用いて通信を行います。その基本的な利用方法の解説を行います。

ServerSocketの待ち受け処理のソースコードは下記のようになります。DatagramSocketの待ち受け処理と似ていることが見て取れると思います。
(net.fxug.hokuriku.chocolat.service.SocketServer.as start()メソッド内)

var serverSocket = new ServerSocket(); serverSocket.addEventListener(Event.CONNECT, this.serverSocketConnectEventHandler); serverSocket.bind(localPort, localAddress); serverSocket.listen();

ServerSocketに対する送信側で利用するクラスはServerSocketクラスではなくSocketクラスです。これはAIR2.0以前から存在するクラスですが、AIR2.0でいくつかの拡張がなされています。

SocketからServerSocketへの接続は以下のように行います。bindメソッドの引数の並びはポート番号, IPアドレス、connectメソッドの引数の並びはIPアドレス, ポート番号のように、順番が逆なので注意が必要です。
(net.fxug.hokuriku.chocolat.service.SocketClient.as connectServer()メソッド内)

var socket = new Socket(); socket.addEventListener(Event.CLOSE, this.socketCloseEventHandler); socket.addEventListener(Event.CONNECT, this.serverConnectEventHandler); socket.addEventListener(IOErrorEvent.IO_ERROR, this.serverConnectIOError); socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorEventHandler); socket.connect(remoteAddress, remotePort);

次は、ServerSocketクラスで待ち受けしているスピーカー側のアプリケーションに対して、オーディエンス側のアプリケーションから接続が来た場合の処理を見てみます。
(net.fxug.hokuriku.chocolat.service.SocketServer.as serverSocketConnectEventHandler()メソッド内)

private function serverSocketConnectEventHandler(event:ServerSocketConnectEvent):void { var socket:Socket = Socket(event.socket); socket.addEventListener(ProgressEvent.SOCKET_DATA, this.socketProgressEventHandler);

上記のようにServerSocketで待ち受けを行っていた側は、ServerSocketConnectEventから接続元のSocketを取得し、 ServerSocketとSocket間で通信が可能になります。UDPプロトコルを利用するDatagramSocketクラスと異なり、TCPプロトコルを利用するServerSocketクラスの場合、接続元へ要求の結果を返すために返答先となるSocketが必要になります。

・ネイティブインストーラー

ネイティブインストーラーをビルドする方法は2つあります。

  • ソースファイルをベースにしてビルドする方法
  • AIRファイルあるいはAIRIファイルをベースにしてビルドする方法

今回は2番目のAIRファイルをベースにしてビルドする方法を実施します。ベースとなるAIRファイルはFlash Builder 4の「リリースビルドのエクスポート」により作成済みという前提です。

AIRファイルは既に署名済みのため、ADTコマンドを以下のような構文で実行するだけでネイティブインストーラーを作成できます。なお、adtコマンドを実行するには、[Flex SDKインストールフォルダ/bin]をPATHに指定しておく必要があります。

adt -package -target native installer_file air_file [Mac OSXの場合] adt -package -target native SORAAI.dmg SORAAI.air [Windowsの場合] adt -package -target native SORAAI.exe SORAAI.air

サンプルアプリケーションの使い方

ここでは、SORAAIの主要機能であるタイマー機能に関して使い方を紹介します。

ただし、タイマー機能といっても単純なタイマーではありません。このタイマーにオーディエンスからスピーカーへのフィードバックインターフェイスが現在2つ準備されています。1つはSocketServer を利用したスピーカー/オーディエンスモード、もう一つはTwitterを利用したTwitterモードです。

オーディエンス側はこれら2つのインターフェイスを利用してプレゼン中のスピーカーにフィードバックを行います。スピーカーはオーディエンスのフィードバックによってその評価がダイレクトに画面上に通知されるだけでなく、セッション時間に反映され、設定したボーナス時間が増減する事になります。

サンプルアプリケーションの紹介

タイマー機能

SORAAIが起動すると、スピーカーモード(S)/オーディエンスモード(A)の選択画面になります。セッションでプレゼンテーションを行われる方はスピーカーモードを、それ以外の方はオーディエンスモードを選択してください。

スピーカーモードの設定画面(S)
スピーカーモードの設定画面では以下の設定を行います。

・Network - スピーカー受信設定 -
スピーカー受信設定の一覧には、待ち受け可能なネットワークインターフェイスの一覧が自動で検出されます。複数表示された場合はオーディエンスからの待ち受けで利用するインターフェイスを選択してください

※自動でNetworkの設定が検出されない場合、手動で設定を行うことが可能です。

・twitter
Twitter検索を行う場合にキーとなる値であるハッシュタグ(#AIRDAY)とセッションタグ($SORAAI)を指定します。なお、ハッシュタグとセッションタグを設定しない場合はTwitterモードは起動されず、LANモードのみでオーディエンスのフィードバックを受け付ける事になります。

Twitterに関しては皆さんご存知かと思いますが、詳細はこちらを参照ください。
セッションタグはSORAAI独自の概念で、イベント毎に設けられるハッシュタグよりさらに細かく、セッション毎に設けられるタグのことを指します。セッション開始前に、スピーカーとオーディエンスの間で共有しておく必要があります。

・セッション時間(時:分:秒)
セッションの時間を設定します。

・ボーナス時間(分:秒)
オーディエンスの要求によって増減する範囲時間を設定します。ユーザーフィードバッグを受けた場合にこの値の範囲でセッション時間の増減が行われます。

オーディエンスモードの設定画面(A)

オーディエンスモードの設定画面では、自分自身の表示名を設定します。Network設定はSORAAIが自動で検出するようになっていますので、ユーザ自身での設定は原則不要です。

・スピーカーモードのタイマー画面(S)
画面下部にタイムラインが表示され経過時間が表示されます。
スピーカーからのフィードバックが画面左右に通知され、その内容によってタイムラインが増減します。

・オーディエンスモードの投票画面(A)
コメントを入力し、へぇ/ぶぅボタンを押下することで、スピーカーに感想を伝える事が出来ます。

また、スピーカーモードはTwitterを監視していますので、Twitterを利用してコメントを行っても内容が反映されます。Twitterでコメントを行う際は、スピーカーモードで設定されたハッシュタグとセッションタグをつけたうえで、「へぇ」の場合には#goodを「ぶぅ」の場合には#badを設定して投稿を行います。

・タイムアップ画面と結果画面(S)
15秒前からカウントダウンが始まり、タイマーが0になると画面上にTimeUpが表示されます。TimeUp後はスピーカーが画面を操作出来なくなります。セッションを終わらせたくなければ、みんなでがんばって「へぇ」を送るようにしましょう。

なお、Time Up!をクリックすると、最後に統計結果が表示されSORAAIから批評が行われます。

■まとめ - 開発プロジェクトと現状、今後

SORAAIは、AIR 2.0新APIを利用したサンプルアプリケーションとして開発しました。現在、Flex User Groupの北陸のメンバーが連携して開発を進めており、勉強会/イベントに役立つツールを目指して進展中です。ATNDとの連携による勉強会/イベントの開催前のサポート、twitterとの連携による開催中のサポート、SlideShareとの連携による開催後のサポートができないか模索中です。