Wowza Media Serverの使い方(実装編)
2008.02.19 / actionscript
またまたWowza Media Serverについて。前回のつづき。今回はサーバサイドで独自のロジックを組み立てるときのお約束だったり、ASとの連携方法などについての話です。
Wowza IDE
サーバサイドの開発を行いやすくするために、EclipseベースのIDEで、Wowza IDE (Bata2)なるものがあります。手っ取り早くサーバサイドの開発を行うにはこれを使うと便利。
- Wowza Media Serverとの連携
- メソッドのスケルトンの自動生成
- 自前のクラスファイルをAntタスクによって自動的にjarに固めてlibフォルダに配置
まで一気に行ってくれます。
ただし、このIDEには罠もあって、今のところWindowsとMacのバージョンしかありません。Macでの運用+開発、という場合は問題ないでしょうが、Linuxでのサーバ運用を考えている場合はWindowsでビルドしたjarファイルをLinux側に再配置する必要があり、実際にところは「めちゃめちゃ便利!Wowza IDE++!!」なんてことまでは言い切れません。(そもそもIDEのインストール時にサーバの場所を聞かれるのですが、Windows側からLinux側のサーバを指定することができなさげだったので、そもそも連携は難しそう、というか考えられていない模様) なので、実際はWindowsでローカルに開発用としてサーバをインストールし、IDEと連携をさせることになると思います。
また、もう一つの罠として、Eclipseのプラグインの形としては提供されていない、という点です。Subversionなど慣れ親しんだプラグインをいろいろ導入している人にとっては、ここもやや微妙に思う点かもしれません。(実際、僕もここはイケてない点だと思います)
いやいや、俺はやっぱり慣れたEclipseでコード書きたいよ、なんて話も出そうですが、それも頑張ればできそうです。基本的にコンパイルが通る状態にだけ持って行ければいい、という話であれば、Wowza Media Serverのlibディレクトリ以下のjarファイルをビルドパスに通してあげればいいはず。(未確認ですが)あとは、指定のフォルダにビルドしてできたjarをコピーすればOKです。おそらく。
プロジェクトの設定
では、実際にプロジェクトを作成してみます。File > New > Wowza Media Server Pro Project を選択するとProject, ソースフォルダ、クラスファイル出力フォルダの場所を入力します。
package,作成するクラス名を入力します。またASから呼び出されるカスタムメソッド(NetConnection#callで呼び出されるメソッド)を定義したい場合は「Custom Method」の箇所にメソッド名を入力します。一番下のMethod Eventsには、NetConnectionの接続に関するイベントが起こったときの処理を扱いたいものにチェックを入れます。基本的にはデフォルトのままでOKです。
処理はすべてイベントベース
Wowza IDE(Wowza Media Server)での開発はすべてイベントドリブンなもので、指定されたメソッドをimplementすることでサーバサイドの実装をすることになります。このあたりはRed5なんかも同じですね。基本的には
- onAppStart : アプリケーションの初期化
- onConnect : swfからの接続時に伴う処理
- onConnect : swfからの切断時に伴う処理
の3種類を押さえておけばいいと思います。 スケルトンコードが自動的にできあがるのでそれにあわせて必要なコードを追加していくことになります。コードを保存すると、自動的にjarファイルまで出来上がっているので、Wowza Media Serverを再起動させます。
swfからのパラメータの受け取り方
swfからパラメータを受け取るとき、たとえばNetConnection#connectの第二引数や、カスタムメソッドの第三引数でswfは自由なオブジェクトをサーバに渡すことができます。たとえばNetConnection#connectの例で言うと、次のようなAS3のコードがあるとします。
var nc:NetConnection = new NetConnection(); nc.addEventListener(NetStatusEvent.NET_STATUS, this.netStatusListener); nc.objectEncoding = ObjectEncoding.AMF0; nc.connect("rtmp://localhost/livetest/", "my_name");
Java側でonConnectメソッドにおいてmy_nameを取得するためには次のようなコードになります。
public void onConnect(IClient client, RequestFunction function, AMFDataList params) { String userID = getParamString(params, PARAM1); getLogger().info("onConnect from : " + userID); }
getParam*メソッドがModuleBaseクラスのメソッドとして定義されてあるので、それを利用します。今回はStringがくることが予想されてあったのでgetParamStringを利用しました。AS3側からObject、たとえば {user:“katsuma”} な無名Objectが渡ってくると予想される場合は次のようなコードになります。
public void onConnect(IClient client, RequestFunction function, AMFDataList params){ AMFDataObj paramObj = (AMFDataObj)getParam(params, PARAM1); String userID = paramObj.getString("user")); }
まずAMFDataObjオブジェクトとして取得し、その後にAMFDataObj#getString(String key)で値を取り出すことになります。
少し扱いがは面倒くさいものの、AS3のオブジェクトを生で扱えるのがメリットでもあります。あと引数に1つだけ値を渡したからgetParamの引数として「PARAM1」を渡しているわけですが、これはちょっとナンセンスかもしれませんね。
JSONでデータを渡してあげたほうが便利な気がする
AS3から送られた情報をJavaとだけやりとりを行うのならいいのですが、この情報をRDBにストアしたり、JavaScriptと連携を考えた場合、AS側でJSONの形式にencodeさせておいて、文字列としてJava側に送った方がいろんな場面で扱いやすいことも多いと思います。
AS3でJSONを扱うためにはcorelibパッケージを利用するのが良いと思います。解凍してできたcorelib.swcファイルを$FLEX_SDK_HOME/frameworks/libs以下に保存すれば、JSONライブラリが扱えます。扱い方はJSON.encode(obj:Object) または、JSON.decode(str:String)です。上の例で言うと次のようにサーバ側に渡しておきます。
var jsonData:String = JSON.encode( {user : "my_name"} ); nc.connect("rtmp://localhost/livetest/", jsonData);
するとサーバ側で次のように取得できますね。
public void onConnect(IClient client, RequestFunction function, AMFDataList params) { String jsonData = getParamString(params, PARAM1); JSONObject obj = JSONValue.parse(jsonData); getLogger().info("onConnect from : " + obj.get('user')); }
ここでは一番簡単なjson.simpleのパッケージの利用を想定しています。(Javaで手軽にJSON - org.json.simple )JSONで値を渡しておけば、何かと応用は効いてくるので直接オブジェクトを渡すよりも、もしかすると便利かもしれませんね。
まとめ
長くなったので、とりあえずこのあたりで一度終わっておきます。あとSharedObjectの扱いやASの関数呼び出しなんかの話もあるのですが、また別の機会に><