* FACEsバナー
マルチユーザFlashバナーをあなたのページに貼ってみませんか このバナーを面白いと思う方 このページの意図に賛同してくれる方 自分のページに変わったアクセントがほしい方 クリエイター間のネットワークに興味がある方 バナーの設置は簡単です。以下のHTMLソースをあなたのページのHTMLに付け加えるだけです。 <ilayer src="http://faces.bascule.co.jp/banner.php?faces" width="468" height="60"> <nolayer> <iframe src="http://faces.bascule.co.jp/banner.php?faces" width="468" height="60" scrolling="no" frameborder="0" marginwidth="0" marginheight="0"></iframe> </nolayer> </ilayer> 注意と免責事項 Flash player5の場合、同一のマシン上で複数のブラウザウィンドウを立ち上げてこのバナーのあるページを開くと、ブラウザがフリーズしてしまうことがあります。MacOS Xでは特に可能性が高いです(Windows+IEではほぼ大丈夫ですが、ウィンドウを開きすぎるとかなり重くなります)。Flashプラグインの問題と思われますが現状では回避できないので十分ご注意ください。また、バナーの製作者である株式会社バスキュールは、このバナーの使用が原因となり発生した損失や損害については一切責任を負いません。
posted by at : 00:00 | パーマリンク
* fscommand + Visual Basicでマルチユーザ
サンプルパッケージダウンロード 目次 背景 fscommandとは flaのコード解説 VBのコード解説 背景 このページでは、Webからすこし離れて、FlashをWindowsアプリケーションのインターフェース構築に使う場合のマルチユーザ化について解説します。Windowsアプリケーションなど作る予定はない! という方は読む必要はありません。FlashムービーはWindowsのShockwave Flashコンポーネントを用いてWindowsアプリケーションから読み込むことができます。 読み込まれた後でもFlashのほとんどの機能はそのまま有効ですが、Flashの中でXMLSocketオブジェクトを使っている場合、XMLSocketの機能は使えなくなってしまいます。Windowsプログラムの枠を飛び越えてソケット接続を確立することはできないということです。そこで、XMLSocketを使っているFlashムービーをVisual Basic(以下VB)で読み込んだときに、ソケット機能とXML処理をVBで代替する例を以下で説明します。 このチュートリアルの筆者がなんでこんなことを試みたかというと、FACEsサーバの専用ゲームロビーとして、Windowsの常駐アプリケーションを用意しようという計画があるからです。目的はなんであれ、読まれた方のお役に立てば幸いです。 目次に戻る fscommandとは fscommandはFlashムービーがFlashのブラウザに対してメッセージをおくるためのActionScript関数です。パラメータとしてcommand, argumentsの二つを指定できます。Web上でFlashを使う場合はJavaScriptに対してメッセージを送る場合によく使用されますが、今回のサンプルでは、VBで制作したWindowsプログラムに対してメッセージを送ります。 目次に戻る flaのコード解説 以下はWindowsプログラムから読み込むサンプルFlashムービー内のActionScriptの解説です。このサンプルはFACEsサーバのダウンロードパッケージに含まれているtest.flaの内容とほとんど同じで、このムービー単独でもサーバに接続できますが、VBに埋め込まれてXMLSocketが機能しなくなったときにfscommandを使用するようになっているところが大きく違うところです。以下、test.flaとの違いについて主に解説していきます。 以下の二つのスクリプトはマウスにくっついて動く白丸用のスクリプトで、FACEsサーバパッケージ付属のtest.flaとおなじです。sendPosという関数を用意してマウスの位置を送信していますが、sendPosの機能は後で説明するように、Flashプレーヤー上とWindowsプログラムの中では動作が異なります。 1: onClipEvent (mouseMove) { 2: if (_root.selfname == "1") { 3: _root.sendPos("1", _root._xmouse, _root._ymouse); 4: } 5: } 1: onClipEvent (mouseMove) { 2: if (_root.selfname == "2") { 3: _root.sendPos("2", _root._xmouse, _root._ymouse); 4: } 5: } この関数は、test.flaにはありませんが、今回のサンプルはボタンを押したときにサーバへの接続を行うようになっているので、ボタンに対するコールバック関数として用意されています。 1: function startApp () { 2: str = "<QN app=\"test\"/>"; 3: sendStr(str); 4: } loadEnd関数はtest.flaと同じです。が、XMSocketオブジェクトはそのFlashムービーがWindowsプログラムから読み込まれている場合機能しないので、必ず接続に失敗します。なので、onConnectで呼ばれるコールバック関数の中で、接続に成功したかどうかをチェックしなければなりません。 1: function loadEnd () { 2: mySocket = new XMLSocket(); 3: mySocket.onConnect = checkConnect; 4: mySocket.connect("localhost", 8080); 5: mySocket.onClose = checkClose; 6: } checkConnect接続時のコールバック関数で、接続が失敗しても呼ばれるので、ここでSckという変数にXMLSocketでの接続が成功(Windowプログラムから呼ばれてない)したか失敗(Windowsプログラムから呼ばれている)したかの判定結果をBooleanでいれておきます。 1: function checkConnect (bOK) { 2: if (bOK) { 3: mySocket.onXML = getData; 4: Sck = new Boolean(true); 5: trace ("trueconnection"); 6: } else { 7: Sck = new Boolean(false); 8: trace ("falseconnection"); 9: } 10: } 接続が切断されたときのコールバック関数です。XMLSocketでの接続が成功している場合は接続をソケットをcloseする必要がありますが、失敗しているときはcloseしてもしょうがない(そもそもconnectしていない)ので、fscommandでquitというコマンドを外部に送っています。quitというコマンドはFlash Playerに対しては終了コマンドとして作用するので、Flash Playerでこのムービーを開いている場合は、Flash Player自体が終了します。 1: function closeSocket () { 2: if (Sck) { 3: mySocket.close(); 4: } 5: fscommand ("quit"); 6: trace ("closeSocket test\n"); 7: } XMLオブジェクトを送信する関数です。XMLSocketで接続されているときはtest.flaと同じですが、Windowsプログラムから呼ばれているときには、Sendというコマンドを定義してfscommandでXMLオブジェクトを構成する文字列を外部プログラムに送っています。 1: function sendStr (str) { 2: if (Sck) { 3: theXML = new XML(); 4: theXML.parseXML(str); 5: mySocket.send(theXML); 6: } else { 7: fscommand ("Send", str); 8: } 9: } 目次に戻る VBのコード解説 さてこんどはVBのコードの解説です。行番号は通しで付けています。このVBプログラムは、Project1というプロジェクト名になっていますがProject1には、4つのオブジェクトがあり、それぞれ、Form1(Form)、swfObj(ShockwaveFlash)、Timer1(Timer)、Winsock1(Winsock)という名前になっています(括弧内はコンポーネント名)。また参照設定を見ていただくとわかりますが、XML解析のために、MSXML 4.0というDLLを使用しています。ダウンロードはMicrosoftのサイト を参照してください。 4行目からのForm_Load()関数では、起動時の処理を行っています。vbtest.swf(vbtest.flaから生成されたSWFファイル) を読み込み、FACEsサーバプログラムが走っているマシンの名前とポート番号を指定し、接続を行っています。ここでは、サーバパッケージ付属のサンプルとおなじ、localhost、ポート8080に接続しています。 1: Option Explicit 2: Dim con As Integer 3: 4: Private Sub Form_Load() 5: Dim tPath As String 6: 7: tPath = CurDir & "\vbtest.swf" 8: swfObj.Movie = tPath 9: 10: Winsock1.RemoteHost = "localhost" 11: Winsock1.RemotePort = 8080 12: Winsock1.Connect 13: con = 1 14: End Sub 15: SWFファイルから発行されたfscommandを解釈します。quitというコマンドはFlash Playerではデフォルトで停止コマンドとして解釈されますが、この例はオリジナルアプリケーションですので、アプリケーションの終了処理を書く必要があります。あと、サーバへのXMLオブジェクト送信用にSendというコマンドを独自に定義して使用しているので、Send専用の処理を書いています。 16: Private Sub swfObj_FSCommand(ByVal tCmdstr As String, _ 17: ByVal tArgstr As String) 18: 19: If (tCmdstr = "quit") Then 20: Winsock1.Close 21: Winsock1.LocalPort = 0 22: Call EnableTimer 23: con = 0 24: ElseIf (tCmdstr = "Send") Then 25: SendStr tArgstr 26: End If 27: 28: End Sub 29: アプリケーション終了のタイミング調整にTimerを使っているので、その関連処理です。 30: Private Sub EnableTimer() 31: Timer1.Enabled = True 32: End Sub 33: 34: Private Sub Timer1_Timer() 35: Unload Me 36: End Sub 37: fscommandによってswfからSendコマンドが送られて来たときのために、SendStrという関数を用意しています。WinsockのSenddataメソッドで、文字列をFACEsサーバに送信しています。XMLSocket(とFACEsサーバ)は0バイト文字(VBではvbNullChar)をXMLオブジェクトの終端文字として解釈するので、送信時にvbNullCharを付加しています。 38: Private Sub SendStr(str As String) 39: If con = 1 Then 40: Winsock1.SendData str & vbNullChar 41: End If 42: End Sub 43: サーバからXMLオブジェクトを受信したときの処理です。Workという文字列変数に保存して、XMLオブジェクトとしての処理を次で定義しているProcessXMLという関数で行っています。 44: Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) 45: Dim Work As String 46: Winsock1.GetData Work 47: ProcessXML Work 48: End Sub 49: サーバから受信した文字列の処理を行っている関数です。引数文字列をXMLドキュメントとしてロード、パースし、ルートノードの名前と属性値に応じて処理を分岐しています。処理内容としては、test.flaのgetData関数で行っていることをそのまま代替しています。VBプログラム側からswfの関数を直接呼び出す方法がない(もしくは見つからない)ので、Shockwave Flashコンポーネントの、TSetPropertyメソッドとSetVariableメソッドを用いて同等の処理を実現しています。 50: Private Sub ProcessXML(str As String) 51: Dim xml As DOMDocument 52: Dim docRoot As IXMLDOMNode 53: Dim n As String 54: Dim x As Double 55: Dim y As Double 56: 57: Set xml = New DOMDocument 58: xml.loadXML str 59: Set docRoot = xml.documentElement 60: 61: If (StrComp(docRoot.nodeName, "P", vbTextCompare) = 0) Then 62: If docRoot.Attributes.getNamedItem("n").nodeTypedValue = "1" Then 63: swfObj.TSetProperty "_root.mouse1", 0, _ 64: docRoot.Attributes.getNamedItem("x").nodeTypedValue 65: swfObj.TSetProperty "_root.mouse1", 1, _ 66: docRoot.Attributes.getNamedItem("y").nodeTypedValue 67: ElseIf docRoot.Attributes.getNamedItem("n").nodeTypedValue = "2" Then 68: swfObj.TSetProperty "_root.mouse2", 0, _ 69: docRoot.Attributes.getNamedItem("x").nodeTypedValue 70: swfObj.TSetProperty "_root.mouse2", 1, _ 71: docRoot.Attributes.getNamedItem("y").nodeTypedValue 72: End If 73: ElseIf (StrComp(docRoot.nodeName, "N", vbTextCompare) = 0) Then 74: swfObj.SetVariable "_root.selfname", _ 75: docRoot.Attributes.getNamedItem("n").nodeTypedValue 76: ElseIf (StrComp(docRoot.nodeName, "D", vbTextCompare) = 0) Then 77: If docRoot.Attributes.getNamedItem("n").nodeTypedValue = "1" Then 78: swfObj.TSetProperty "_root.mouse1", 0, 0 79: swfObj.TSetProperty "_root.mouse1", 1, 0 80: ElseIf docRoot.Attributes.getNamedItem("n").nodeTypedValue = "2" Then 81: swfObj.TSetProperty "_root.mouse2", 0, 0 82: swfObj.TSetProperty "_root.mouse2", 1, 0 83: End If 84: End If 85: End Sub 目次に戻る
posted by at : 00:00 | パーマリンク
* サンプル2 コンテンツ
実際に作例であるチャットコンテンツを体験できます。まずENTERボタンをクリックしてください。ユーザー名を入力し、ユーザーカラーをスライドバーで決定します。LOGINボタンを押すと、ビジュアルチャットができます。 ショートカット ↑ :アバタが上に移動します。 ↓ :アバタが下に移動します。 ← :アバタが左に移動します。 → :アバタが右に移動します。 space + c : 吹出しの表示切り替えです。 space + y : イエス吹出しの表示切り替えです。 space + n : ノー吹出しの表示切り替えです。 space + a : 怒りパーツの表示切り替えです。 space + s : 笑顔パーツの表示切り替えです。 space + t : 涙パーツの表示切り替えです。
posted by at : 00:00 | パーマリンク
* チュートリアル
目次 XMLSocketで何ができるのか サーバプログラムをセットアップする サーバパッケージ付属サンプルのFlashファイルをサーバに接続させてみる サーバパッケージ付属サンプルの中身はどうなっているのか サンプル1(簡単な作例) サンプル2(チャット) poppinSoccer ver 1.01解説 fscommand+Visual Basicでマルチユーザ XMLSocketで何ができるのか XMLSocketは、Flashファイルと他のマシンとの間に、双方向の接続を確立し、XMLデータをやりとりするためのActionScriptのオブジェクトです。他のマシン(もしくはプログラム)との間に継続的な接続が必要な場合に使うもので、とくにマルチユーザコンテンツを製作するためだけにあるというわけではありませんが、目的として誰もが考えるのはやはりマルチユーザであろうということで、このサイトではFlashによるマルチユーザコンテンツの製作を扱います。 まず、わかりやすい例として、chatが挙げられます。chatといってもCGIを使っ たWeb chatの代替物ではなく、接続状態を保ったままの、IRCのようないわゆる普通のchatです。もちろんチャットだけではなくいろいろ可能性はあるのですが、 とりあえずわかりやすいのでchatを例にして説明します。まず、「マルチユーザ」という言葉を説明なしにいきなり使ってしまっていますが、ここでは、別々 のマシンを使っている複数のユーザ同士が、リアルタイムにアプリケーション 上の状態、情報を共有していることを指します。どうやって共有させるかというと、ここでXMLSocketがでてきます。まずFlashファイル(swfファイル)を置 いてあるWebサーバと同じマシン上にサーバプログラムを走らせる必要があります。サーバプログラムは、既に開発されているものもありますが、このペー ジでは独自開発のプログラムを用います。サーバプログラムのプログラミング 言語にはJavaを使用していますが、Javaの知識はここでは特に必要ありません(もちろんあればそれに越したことはありませんが)。 ブラウザにロードされたswfファイルはswfファイルのActionScript(のXMLSocketオブジェクト)内で指定されたサーバに接続を試み、接続が確立したあとは接続状態をキープし続けます。 chatであれば、ある一つのクライアントがメッセージをサーバに送ると、サーバはそのメッセージを全てのクライアントに配らなければなりません。 つまりリアルタイムに情報を共有するには、あるクライアントがサーバに 送った情報が即座に他の全てのクライアントに配分される必要があるのです。 Flash4まではFlashのActionScriptの機能の中に他のマシンとの接続を確立しキープする機能(ソケット)がなかったので、このようなことができませんでした。 このXMLSocketの機能を使えば、ネットワークゲームのようにネット上の 仮想空間をFlashで構築することも可能です。 とりあえず、XMLSocketを使ったサンプルを見てみたい、という方は、 この下についているFlashバナーをご覧ください。 あなたのインターネット環境で使われているファイヤウォールやルータの設定によっては、「サーバに接続できません」というエラーメッセージが出てしまうかもしれません(もしかしたらウチ(faces.bascule.co.jp)のサーバが落ちてるだけかも。。。そのときはごめんなさい!)が、あきらめることはありません。あとでサーバも手元のマシン(もしくは同じLAN内のマシン)でサーバを動かす方法を説明します。バナーのどこか一箇所をクリックすると、コックさんがでてきて、マウスでクリックされた場所に向かってトコトコ歩いていく姿が見られれば、サーバへの接続に成功しています。これは実は、クリックされた場所の情報をマルチユーザサーバ(faces.bascule.co.jp)に送って、サーバから送り返されてきた情報に基づいてコックさんを移動させているのです。この場合、何もソケットを使ってサーバに情報を送り付けなくても、マウスでクリックした位置に単に移動させればいいじゃないか、と思うかも知れません。そこで、マルチユーザ状態にするために、そばに空きマシンがもう一台ある方はそちらでも同じページにアクセスしてみてください。他にマシンがない方は、もう一つブラウザウィンドウを立ち上げて同じページ(このページ)にアクセスしてみてください。そうすると、もう一人コックさんがでてきます。どちらか片方のバナーでコックさんを移動させると、もう一つのバナーでもコックさんが同じように移動します。要するにこれがマルチユーザです。これがXMLSocketがでてくるまでFlashではできなかった。ネットゲームにはまっているような人には、「当たり前のことをなにクドクドいってるんだ」といわれそうですが、Flashでこれ(マルチユーザ)ができるとネットゲームを含むネットコンテンツ製作の裾野がひろがると思いませんか? 目次に戻る サーバプログラムをセットアップする では、Flashでこういうマルチユーザコンテンツを自分で作るにはどうしたらよいでしょうか。まず必要なのは、当たり前ですが、Macromedia Flash5です。XMLSocketはFlash5以降の機能なのでFlash4以前には含まれていません。次に必要なのが、サーバプログラム(とそれを動かすマシン環境)です。Flash用のサーバプログラムは、商用、フリー含めていくつか種類がありますが(リンク集)、ここではこのサイト(FACEs)オリジナルのFACEs Serverを使って説明します。FACEs ServerはJavaで書かれていますが、とりあえずJavaやプログラミングの知識は必要ありません。FACEs Serverは100% Pure Javaで書かれており、JRE(Java Runtime Environment)1.3以上が動く環境が必要です。現状で動作を確認しているOSはMicrosoft Windows(2000,98,95,NT4.0), Linux(RedHat6.2, RedHat7.0.1J, RedHat7.1), Solaris2.6です。FACEs Serverの開発、運営はLinuxで行っていますが、ここを読んでいる方の手元にある可能性の高いOSとしてとりあえずWindowsを例にとって手順を説明します。あなたが普段Windows版のFlash5を使用しているのであれば、その同じマシンで結構です。 まずダウンロード ダウンロードページにログインし、zipパッケージ(faces0_1_7.zip)をダウンロードしてください。 Java2 SDKのインストール 実は、FACEsサーバを動かすだけならJava2 SDK(Software Development Kit)は必要ないのですが、JREだけインストールしてあとでSDKが必要になると二度手間ですから、思い切ってインストールしてしまいましょう。30MB近いパッケージをダウンロードするのは厳しい、という人は、Java関連雑誌のCD-ROMを利用することもできます。 まずインストールパッケージをSunのサイトからダウンロード 展開、インストールします。詳細はJava(TM)2 SDK Standard Edition インストールガイドにあります。 PATH変数を更新します。上記のインストールガイドに詳細が書いてありますが、以下Windows2000の場合を示します。 [スタート]から[設定]、[コントロールパネル]、[システム]の順に選択し、[詳細]タブを選択します。 [ユーザ環境変数]と[システム環境変数]で"PATH"を探します。 "PATH"の最初(先頭)にパスを追加します。パスは、JDKをインストールした場所が例えばC:\j2sdk1.4.0であれば、 C:\j2sdk1.4.0\bin になります。 [ユーザ環境変数]と[システム環境変数]で"CLASSPATH"を探します。 カレントディレクトリ(".")にCLASSPATHが通っていなければ、カレントディレクトリ(".")を追加します。 例えば、CLASSPATHの変数値が、 c:\windows\java\classes; となっていたら、カレントディレクトリにパスが通っていないので、 c:\windows\java\classes;. というように、最後に"."を追加します。 JAXPのインストール(J2SEのバージョン1.4以上をインストールした方はJAXPのインストールの必要はありません) JAXP(Java API for XML Processing)をインストールします。JAXPはJava XML Packに含まれています。以下手順です。 zipアーカイブ(java_xml_pack-spring02-dev.zip)をダウンロード Winzip等で解凍、展開する。 <展開したフォルダ>\java_xml_pack-spring02-dev\jaxp-1.2-ea2フォルダを開く。 中にある.jarファイル全てをを<Java2 SDKをインストールしたフォルダ>\jre\lib\extフォルダにコピーする。Java2 SDKをインストールしたフォルダがC:\jdk1.3.1_02であれば、 C:\jdk1.3.1_02\jre\lib\ext に.jarファイル全てをコピーします。 FACEs Serverの起動 最初にダウンロードしたfaces0_1_7.zipを解凍、展開します(facesという名前のフォルダができます)。 コマンドプロンプトを起動します。Windows2000であれば、[スタート]から[プログラム]、[アクセサリ]、[コマンド プロンプト]の順に選択すれば起動します。 解凍してできたfacesというフォルダに移動します。展開した場所がC:\であれば、 C:\>cd faces などとすれば移動できます。 FACEs Serverを起動します。コマンドプロンプトで C:\faces>java jp.faces.FacesServer 8080 のようにすれば起動できます。最後の数字は、FACEsサーバが指定するポート番号で、1024以上の数字を指定してください。 [2002/05/20 13:27:37] starting server... [2002/05/20 13:27:37] server started on port 8080 のように表示されれば、起動は成功です。 ここで、 [2001/05/20 13:27:37] Exception in thread "main" java.lang.NoClassDefFoundError: jp/faces/FacesServer などのように表示されて起動できない場合は、もう一度、CLASSPATHとPATHの設定を確認してください。 目次に戻る サーバパッケージ付属サンプルのFlashファイルをサーバに接続させてみる faces\sampleにあるtest.flaをFlash5でオープンします。 ムービエクスプローラを開きます。 [actions for frame1]とある所をダブルクリックしてフレームアクションを開きます。 上から4行目の mySocket.connect("localhost", 8080); とあるところに注目しましょう。 もし、サーバプログラムを起動したマシンが、Flash5を起動しているマシンと同一のマシンで、かつポート番号を8080で起動してあるならば、何も変更する必要はありません。もし、サーバプログラムを起動したマシンがLAN内の他のマシンであれば、localhostとなっているのところをそのマシンのマシン名かローカルIPアドレスに置き換えてください。たとえば mySocket.connect("10.0.0.2", 8080); のように修正します。 [ファイル]、[ムービーの書き出し]を選択して、test.swfというファイルを生成します。 test.swfを2つ起動して、マウスの動きに白い円がくっついてきて、二つのウィンドウで動きが共有されていれば接続成功です。 目次に戻る サーバパッケージ付属サンプルの中身はどうなっているのか このtest.flaは、とりあえず手元で立ち上げたサーバプログラムが動作しているかどうかを調べるための、ほとんど最小限の機能しかもたないFlashサンプルですが、同時にXMLSocketを用いてマルチユーザFlashコンテンツを作るための本質的な手法を含んでいるので、XMLSocketの説明と併せてtest.flaのActionScriptの中身をざっと解説します(もうちょっと具体的なコンテンツサンプルはまたあとで説明します) まずActionScriptのXMLSocketオブジェクトの特徴について、Flash5付属のActionScript辞書から引用します。 ------------------------------------------------------------------------ XMLメッセージは、全二重TCP/IPストリームソケット接続を介して送られます。 各XMLメッセージは、ゼロバイトで終了された完全なXMLドキュメントです。 無数のXMLメッセージは、1つのXMLSocket接続を介して送受信することができます。 ------------------------------------------------------------------------ 1の言い回しはなんだか妙に大げさですが、全二重というのは送信と受信を同時に行うことができるということで、TCP/IPはインターネットの標準プロトコルで、ソケットにはストリームソケットとデータグラムソケットがあって、、、というような説明はまた別の機会にするとして、要するにXMLSocketはTCPというプロトコルをつかって双方向通信を行うということです。 2は、XMLSocketオブジェクトでやりとりするメッセージはXMLドキュメントであるということです。実はXMLでない普通のテキストも送受信できますが、ここでは詳しく触れません(詳しく知りたい方は検索エンジンでXMLSocket onDataのキーワードで調べてみるとわかるかも知れません。)。Flash5でXMLドキュメントを扱うXMLオブジェクトについてはまた別に説明したいと思いますが、詳しく知りたい方はWEBのお仕事あたりが分かりやすそうです。ゼロバイトというのは、サーバプログラム(Java)上で"\0"というように表記されていますが、ActionScriptを書く上では意識する必要はありません(送信時にはFlashが自動的に付加する)。 3は、要するに一つXMLSocketオブジェクトのインスタンスを生成しておけば、サーバとの接続にはずっとそのXMLSocketを使い回すことができ、メッセージごとに生成する必要はないということです。 このXMLSocketオブジェクトには以下のメソッドがあります。 以下の表もActionScript辞書からの引用です。 メソッド 説明 close 開いているソケット接続を閉じます。 connect 指定されたサーバーへの接続を確立します。 onClose XMLSocketの接続が閉じられたときに呼び出される関数。 onConnect XMLSocketの接続が確立されたときに呼び出される関数。 onXML XMLオブジェクトがサーバーから着信したときに呼び出される関数。 send XMLオブジェクトをサーバーに送ります。 「~たときに呼び出される関数」というのは、コールバック関数とよばれ、プログラムから直接呼び出すのではなく、なにか特定のイベントが起きたときに呼び出されるように指定するものです。これらの6つのメソッドは全てtest.flaの中にでてくるので、そのつど説明します(ちょっと触れたように、Flash5において正式に仕様には書かれていないonDataというメソッドがありますが、ちゃんとテストしていないので別の機会に触れます。)。もういちどtest.flaを開きましょう。 faces\sampleにあるtest.flaをFlash5でオープンします。 ムービエクスプローラを開きます。 [actions for frame1]とある所をダブルクリックしてフレームアクションを開きます。 function xxxxx(){ ........... } というかたちで関数の定義が最初から最後までずらっと並んでいます。これらの関数はすべて他のムービクリップオブジェクトのインスタンスやボタンから呼び出すために用意したものです。上から順にそれぞれの関数を説明します。説明の便宜のために、各行の頭にその関数内での行番号をつけています(実際のスクリプトには行番号は入っていません)。 loadEnd関数 サーバへの接続時に呼ぶ関数です。このサンプルではloadactionというインスタンスがロードされた瞬間に呼ばれます。 1: function loadEnd () { 2: mySocket = new XMLSocket(); 3: mySocket.onConnect = checkConnect; 4: mySocket.connect("localhost", 8080); 5: mySocket.onClose = checkClose; 6: } 2行目でXMLSocketオブジェクトのコンストラクタを呼び出し、XMLSocketオブジェクトを作成しています。 3行目でサーバとの接続が確立されたときに呼ばれるコールバック関数(ここではcheckConnect)を設定しています。 4行目はconnectメソッドの1つめの引数で接続先のサーバの名前、2つめの引数でポート番号を指定しています。 1つめの引数はここではlocalhostになっていますが、これはサーバとクライアントが同じマシンにある場合にのみ有効な記述です。普通にWeb上でクライアントを公開する場合は、FACEsサーバプログラムの走っているマシンの名前をいれます。サーバプログラムは、クライアントになるSWFファイルの置いてあるWWWサーバと同じマシンか、もしくは同じサブドメイン内のマシン上で動いていないと接続できません。これはFlashセキュリティ上の制限です。例えば、FACEsサーバプログラムがwww.faces.jpというマシンの8080番ポートで走っているなら、 mySocket.connect("www.faces.jp", 8080); という記述になります。この場合、クライアントのSWFファイルはwww.faces.jp, もしくはfaces.jpドメインに属するマシン(例: www2.faces.jp, hogehoge.faces.jpなど)に置かれていなければ、サーバに接続できないということになります。 5行目でサーバから接続が閉じられたときに呼ばれるコールバック関数(ここではcheckClose)を設定しています。 checkClose関数 サーバから接続が閉じられたときに呼ばれるコールバック関数です。デバッグ用に文字列を出力する以外は何もしていません。 1: function checkClose () { 2: trace ("disconnected"); 3: } closeSocket関数 サーバとの接続を切る関数です 1: function closeSocket () { 2: mySocket.close(); 3: trace ("closeSocket test\n"); 4: } 2行目でXMLSocketオブジェクトのcloseメソッドを呼び出してサーバとの接続を閉じています。 checkConnect関数 サーバとの接続が確立するときに呼ばれるコールバック関数です。引数には、ソケットが正常に確立されたかどうかを示すブール値(trueかfalse)が入ります。 1: function checkConnect (bOK) { 2: if (bOK) { 3: mySocket.onXML = getData; 4: trace ("trueconnection"); 5: sendStr("<QN app=\"test\"/>"); 6: } 7: else { 8: trace ("falseconnection"); 9: } 10: } if~else文で接続が確立された場合(bOKがtrue)とそうでない場合(bOKがfalse)に分岐しています。接続が確立された場合にXMLドキュメントの文字列がサーバから着信したときに呼び出される関数を設定し(3行目)、サーバにsendStr関数(下で説明します)でXMLオブジェクトを送っています(5行目)。QNという名前のタグは、FACEs Serverに対して自分(クライアント)固有の番号をリクエストするためにFACEs Server用に定義されています。appという属性で指定されたパラメータ(ここでは"test")は、コンテンツの名称(複数種類のマルチユーザコンテンツが一つのサーバに接続する場合にコンテンツを識別するためにある)を指定しています。このリクエストに対してサーバはNという名前のタグのついたノードを返すことによってクライアント番号を発行します。このようなFACEs Server固有のXMLの取り決めは別にまとめて説明します。 getData関数 一つのXMLオブジェクトを構成する文字列が着信するたびに、呼び出される関数です。サーバから送られてくるXMLデータを解釈し、内容に対応した処理を行っています。引数には、受信したXMLオブジェクトが入ります。 1: function getData (receiveXML) { 2: var e = receiveXML.firstChild; 3: if (e != null && e.nodeName == "P") { 4: if (e.attributes.n == "1") { 5: setProperty ("_root.mouse1", _x, e.attributes.x); 6: setProperty ("_root.mouse1", _y, e.attributes.y); 7: } 8: else if (e.attributes.n == "2") { 9: setProperty ("_root.mouse2", _x, e.attributes.x); 10: setProperty ("_root.mouse2", _y, e.attributes.y); 11: } 12: } 13: else if (e != null && e.nodeName == "N") { 14: selfname = e.attributes.n; 15: trace ("selfname="+selfname+"\n"); 16: } 17: else if (e != null && e.nodeName == "D") { 18: disconnectedname = e.attributes.n; 19: if (e.attributes.n == "1") { 20: setProperty ("_root.mouse1", _x, 0); 21: setProperty ("_root.mouse1", _y, 0); 22: } 23: else if (e.attributes.n == "2") { 24: setProperty ("_root.mouse2", _x, 0); 25: setProperty ("_root.mouse2", _y, 0); 26: } 27: trace ("disconnectedname="+disconnectedname+"\n"); 28: } 29: } 2行目で受信したXMLオブジェクトのルート要素を変数eに取り出します。 3行目、13行目、17行目は、ルート要素の要素名に応じて処理を分岐するため にXMLオブジェクトのnodeNameプロパティを読みだして判定を行っています。3 行目なら、「変数e(ルート要素の入ったXMLオブジェクト)がnull(空)でなく且 つ要素名が"P"だったら」ということです。PというXML要素名は FACEs Server用に定義された要素名ではなく、このサンプルでマウスポインタ の位置をやりとりするために定義した要素です。NとDはFACEs Serverで定義さ れており、NはQN要素をサーバに送信したときの返信としてサーバから帰って くる要素、Dは他のクライアントがサーバとの接続を断ったときにサーバから送られてくる要素の名前です。 4行目と8行目の、e.attributes.nというのはXMLオブジェクト(eという変数)の、全ての属性のコレクション(attributes)の中の、nという属性で指定された文字列と言う意味です。P要素のnという属性はこのサンプルではこの要素を送信したクライアントの固有の番号を指定しているので、n属性が1か2かで分岐しているということは、このサンプルはサーバを最初から2人で独占してそれぞれ1番と2番をサーバから振られている状態を前提にしていることが分かります(サーバは他のクライアントに使われていない最も小さな番号をクライアントに振るようになっています。通常クライアントは自分に与えられる番号を予測できないので、これはサーバ立ち上げ時のテスト用に特殊な状況を想定していると思ってください)。 5,6行目のsetProperty関数(ActionScriptで元々定義されている)で、mouse1インスタンスのx座標とy座標を指定しています。 8,9行目のsetProperty関数で、mouse2インスタンスのx座標とy座標を指定しています。 13行目から16行目はN要素のn属性で自分(クライアント)の固有の番号を振られた場合の処理を記述しています。n属性の数値をselfnameという変数に格納しています。 17行目から28行目は自分以外の他のクライアントがサーバとの接続を絶ったときにサーバから送られてくるD要素を受信したときの処理を記述しています。ここでは接続を断ったクライアントのマウスポインタの位置に対応するインスタンス(mouse1かmouse2)の位置をx、y座標ともに0にしています。ちなみにこのサンプルの中に数箇所出てくるtrace関数は、単にデバッグや動作追跡の便利のために挟んであるだけなので、動作には直接関係ありません。 sendPos関数 マウスが動くときに呼び出している関数です。1番目の引数は自分(クライアント)固有の番号、2番目はx座標値、3番目はy座標値です。 1: function sendPos (name, x, y) { 2: str = "<P n=\""+name+"\" x=\""+x+"\" y=\""+y+"\"/>"; 3: sendStr(str); 4: } 2行目で sendStr関数 引数で指定されたXMLドキュメント文字列をXMLオブジェクトに変換して、XMLSocketのsendメソッドでサーバに送信します。 1: function sendStr (str) { 2: theXML = new XML(); 3: theXML.parseXML(str); 4: mySocket.send(theXML); 5: } 2行目ではXMLオブジェクトのコンストラクタを呼び出し、XMLオブジェクトを作成しています。 3行目では、XMLオブジェクトのparseXMLメソッドでXML文字列を解析し、XMLオブジェクトにXMLツリーを設定します。 4行目では、XMLSocketオブジェクトのsendメソッドで、作成したXMLオブジェクトをサーバに送信します。 以上がこのサンプルで定義されている関数の説明です。 次に、マウスにくっついて動くムービクリップのインスタンス用のActionScriptについて見てみます。 ムービエクスプローラで[action_mouse, (mouse1)]の[actions for action mouse]とあるところをダブルクリックしてオブジェクトアクションを開きます。 1: onClipEvent (mouseMove) { 2: if (_root.selfname == "1") { 3: _root.sendPos("1", _root._xmouse, _root._ymouse); 4: } 5: } マウスが移動したときに、マウスのx,y座標を、frame1で定義したsendPos関数で送信します。自分のクライアント固有の番号が1のときにその番号とx座標とy座標の値を引数に取ってP要素を構築してサーバに送信します。これが自分も含めた全て(といってもこの場合最大2つですが)のクライアントに配られて解釈され、白丸オブジェクトの動きが共有されることになります。[action_mouse, (mouse1)]の方も同様で、自分の番号が2の場合のための記述です。 次は、ロード時にloadEnd関数を実行するためのダミーインスタンス用のActionScriptを見てみます。 ムービエクスプローラで[action_mouse, (loadaction)]の[actions for action mouse]とあるところをダブルクリックしてオブジェクトアクションを開きます。 1: onClipEvent (load) { 2: _root.loadEnd(); 3: } このインスタンスがロードされたときに、frame1で定義したloadEnd関数を呼び出し、サーバへの接続を行います。 最後にボタンのActionScriptを見てみます。 黄色地に黒の"d"ボタンをクリックしたときに、サーバとの接続を切断するようにしています。 1: on (release) { 2: textBox = "disconnected"; 3: this.closeSocket(); 4: } 3行目でframe1で定義したcloseSocket関数を呼び出し、サーバとの接続を切っています。 目次に戻る まだまだ説明の足りないところ(特にXMLオブジェクトについてとFACEsサーバ固有のの取り決め)や用語の不適切なところがあるかと思いますので、この文書は随時アップデートしていきます。またもっと具体的なコンテンツの作例も紹介していきたいと思います。 サンプル1(簡単な作例) サンプル2(チャット)
posted by at : 00:00 | パーマリンク