(BACK)

複数の閲覧者による非リアルタイム通信の例

07/9/9 take#9用に修正
複数の閲覧者が1つのswfとcgiを介して、サーバー・クライアント型通信(ネットゲームとか)のような事が可能である。
ここでは、サンプルのチャットシステムを用いて、サーバー負荷を考えてCGIへのアクセスを極力少なくして通信する方法について解説する。

解説用サンプル ParaChat (take#9)
設置する方法については中のテキストファイルを参照。

実行の流れ
CGI関連の各ファイルの説明は以下である。
pchat.cgi
実行ファイル。
ログファイルに文字列を追加する。

FLASHから渡す変数は以下である。
filename
 対象のファイル名の元となる文字列。
 これが「1」であれば、「1.dat」と「1.tim」が対象となる。
 ParaChatでは部屋番号の数字をそのまま使っている。

act
 実行内容。(数値)
 1 … 新規作成
 2 … 追記(ファイルが存在しない時は新規作成)
 3 … 削除
 4 … logフォルダの中のファイルを全削除する

cmd
 出力する文字列。

スプライトの中でこれらの変数を設定してからloadVariablesする。
実行されると、その時に時間ファイルを更新する。 処理が正常に終わると標準出力で result=1 を返す。
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") { //エラーだった }

Written by D4U