複数の閲覧者が1つのswfとcgiを介して、サーバー・クライアント型通信(ネットゲームとか)のような事が可能である。
ここでは、サンプルのチャットシステムを用いて、サーバー負荷を考えてCGIへのアクセスを極力少なくして通信する方法について解説する。
解説用サンプル ParaChat (take#9)
設置する方法については中のテキストファイルを参照。
CGI関連の各ファイルの説明は以下である。
pchat.cgi 実行ファイル。 ログファイルに文字列を追加する。 FLASHから渡す変数は以下である。実行されると、その時に時間ファイルを更新する。 処理が正常に終わると標準出力で result=1 を返す。
filename 対象のファイル名の元となる文字列。 これが「1」であれば、「1.dat」と「1.tim」が対象となる。 ParaChatでは部屋番号の数字をそのまま使っている。 act 実行内容。(数値) 1 … 新規作成 2 … 追記(ファイルが存在しない時は新規作成) 3 … 削除 4 … logフォルダの中のファイルを全削除する cmd 出力する文字列。 スプライトの中でこれらの変数を設定してからloadVariablesする。
1.dat 1番の部屋のログファイル。必要になった時に作成される。 ログとは、開始してから起こった事を書き連ねていった内容 の事である。
1.tim 1番の部屋の時間ファイル。必要になった時に作成される。 ログファイルに書き込みがされた時に、今の時間(Date.getTime()相当)を記録する。 最後に更新された時間という事になる。
実際の流れは以下である。
10秒ごとに、時間ファイルを読み込む。
↓
前回記録した内容と比べて値が違っていれば、更新があったという事なので、ログファイルを読み込む。
↓
ログファイルの内容を解析して、画面に反映させる。
ログファイルに追加するべき内容が出来たら、実行ファイル(CGI)に内容を送る。
↓
実行ファイルは、指定されたファイルに内容を追記し、時間ファイルを更新する。
ログファイルは、最初の状態で以下の内容である。
log=
これをFLASHで読み込むと、logという変数に読み込まれる事になる。
追加していく内容は、名前、名前の色(10進数)、今の時間(Date.getTime())、発言内容の4つである。
これを、この1組のデータの区切り文字を「///」、
データ間の区切り文字を「/#/」として、ひとまとめにしてのような形にし、この文字列を追記していく。
D4U/#/123456/#/111111/#/だから無理だって言ったんだ///
filename = "1"; act = 2; //追記 cmd = "D4U/#/123456/#/111111/#/だから無理だって言ったんだ///"; this.loadVariables("pchat.cgi","POST");
結果、ログファイルは以下のように大きくなっていく。
log=D4U/#/123456/#/111111/#/だから無理だって言ったんだ///D4U/#/123456/#/111111/#/今度こそ奴を仕留めてご覧に入れます///D4U/#/123456/#/111111/#/そのような事ぶっちゃけ有り得ませぬ///
ログファイルを読み、区切り文字でsplitして、最初から順番に処理する事で、内容を復元する事ができる。
logtxt = ""; a1 = log.split("///"); for(i=0;i<a1.length;i++){ a2 = a1[i].split("/#/"); t_name = a2[0]; t_clr = Number(a2[1]); t_mes = a2[3]; logtxt += t_name + " : " + t_mes + "<br>"; }
時間ファイルは、以下のような内容である。
upd=123456789
変数updに読み込まれる。
数値化 Number(upd) してから比較すること。
CGIでの処理が終わると、変数resultに結果に応じた文字が入る。
resultの値(文字) 1 ... 正常終了 2 ... ファイル名に異常があったので中止した 3 ... ファイルがオープン出来なかったので中止した 4 ... actの値が正しくない
これを利用して、処理が終わるまで待つ事が可能である。
result = ""; //通信前に空にしておくのを忘れずに ↓ this.loadVariables("pchat.cgi","POST"); //通信 ↓ if (result == "1") { //処理が終わった } if (result == "2" || result == "3") { //エラーだった }