スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

FLASHでSocket通信プログラム(Read)

次にFLASHでSocket通信のReadです。
このチャットシステムでは、一つの発言や、コマンドは、改行によって区切られて、行ごとにまとまっています。
したがって、Readでは、まず送られてきたデータを改行で区切ります。
そして、それぞれをJavaScriptに渡すことになります。


private function receive_data(event:ProgressEvent):void
{
try
{
var av:uint = socket.bytesAvailable;
var byteArray:ByteArray = new ByteArray();
socket.readBytes(byteArray, 0, av);
var str:String = byteArray.readUTFBytes(byteArray.length);
var arr:Array = str.split(/\n/)
for (var i:int = 0; i < arr.length; i++) {
var str2:String = arr[i];
callJS("recv", str2);
}
}
catch ( e:Error )
{
}
}



この関数は、プログラムの最初で
socket.addEventListener(ProgressEvent.SOCKET_DATA, receive_data);
によってSocket受信時に呼ばれるように登録されています。
callJSはJavascriptを呼び出す関数です。
これについてはまた後ほど。

http://chattera.net/
http://chattera.net/chaberilist.php

スポンサーサイト

FLASHでSocket通信プログラム

やや備忘録的ですが、FLASHでSocket通信の方法を書いておきます。
まず、package内で
import flash.net.Socket;
をしてSocketを使えるようにします。
クラスには
var socket:Socket = new Socket();
でSocketObjectを生成します。

クラスのコンストラクタで
socket.addEventListener( Event.CONNECT, connectHandler );
socket.addEventListener(ProgressEvent.SOCKET_DATA, receive_data);
socket.addEventListener( IOErrorEvent.IO_ERROR, ioErrorHandler);
socket.addEventListener( Event.CLOSE, socketCloseHandler);
のようにしてSocket関係のEventを受けられるようにします。

接続は
socket.connect(flashvars["serverip"], flashvars["serverport"]);
で行います。

Socketの接続が完了したときには、connectHandle()が呼ばれますが今は何もしていません。
SocketがCloseしたときは、socketCloseHandler()が呼ばれますが、これも何もしていません。
データの送受信についてはまた別の機会に。

http://chattera.net/
http://chattera.net/chaberilist.php



Flashでの接続のポリシーファイル

チャットは、ブラウザのFLASHがチャットサーバにSocket接続して通信します。
FLASHはSocketでサーバに接続する際にはポリシーファイルが必要になります。
動作としてはFLASHからサーバの843ポートに接続して
<policy-file-request/>
を送るので、その返事として
<cross-domain-policy>
<allow-access-from domain="chattera.net" to-ports="from-to" />
</cross-domain-policy>
のような応答を返す必要があります。
つまり常駐プロセス1個つくってポート843を1つあけないといけないです・・
とりあえずは、FLASHのサイトからflashpolicyd.plというperlのスクリプトを落としてきて
起動していますが、ちゃんとつくらないといけないんですかね。。

http://chattera.net/
http://chattera.net/chaberilist.php

ユーザのID

チャットサーバに接続してチャットする人には、IDをつけて識別しています。
IDは64bitの整数で連番で作成しています。
実装はPostgreSQLのsequenceを使っています。

IDはCookieから取得できるようにしておいて、次のアクセスでは、
新規にIDを振らなくてもいいようにしています。
そうしないとIDの意味がないですからね。
(この仕組みの詳細は別途にします)

ただ、ロボットやクローラはCookieを使わないので、アクセスするたびにIDが消費されていきます・・
今のところ一日に100のオーダーくらいのID数の消費ですんでいるので、
年間で数万のIDで済むので、とりあえずこれは、放置しています。

http://chattera.net/
http://chattera.net/chaberilist.php

入室音と発言音

だれかが入室したときや、発言がしばらくなかったあとで発言があったときに、
音を鳴らすようにしています。
これはFLASHで鳴らすようにして、Javascriptから呼んでいます。
もちろん、音を鳴らさないようにする設定もできます。

入室音は誰かが入室したときにならせばいいのですが、
発言がしばらくなかったというのをどのくらいに設定すればいいのか悩みますね。
今は、画面にFocusがある場合と、ない場合で音を鳴らす時間間隔を分けています。
画面にFocusがない場合の方が短い時間で鳴るようにしています。
まあ、音のファイルも適当なデータなので、何かいい素材がないですかね。


http://chattera.net/
http://chattera.net/chaberilist.php

ブラウザクラッシュしたら

最近、ある特定のPCでChromeがよくクラッシュします。
そういう場合、なぜかSocketの接続がきれないままとサーバが認識していることがあります。
今は、同じIDで同じ部屋に入るのは禁止しているので
この状態では、はいれませんね。。
ただ、TCPのkeepaliveを短くセットしたり、TCP受信時のretriesを少なくしたりして
なるべく早く検知して、SocketのClose処理をするようにしています。

ところが、このPCでは、それをやってもClose検知してくれない。。。
ChromeのWindowは全部閉じているはずなのに・・
そうおもってTaskManagerを見るとChromeのプロセスがいっぱいいるんですよね。。
クラッシュして画面はなくてもプロセスがある状態なんですね。。
そこで、TaskManagerでChromeのプロセスを全部終了するとめでたくCloseを検知して
部屋にはいっているIDは退出しました。

普通はこんなことなかなか思いつかないですよね。
一応発言なしで3時間で強制退出するんですが、そんなに待てないですよね。
そのときは、とりあえずシークレット(プラーベート)ブラウジングにして
ゲストで入ってくださいね。

http://chattera.net/
http://chattera.net/chaberilist.php
プロフィール

chattera.net

Author:chattera.net
フリーでソフト開発の仕事をしています。
自作したこのチャットシステムは、何か世の中に役に立つこともあるかと思いますので、お呼びがかかるとうれしいですね。

連絡先は chatteranet@gmail.com です。

また、ソフト開発関連のお誘いもうけたまわっております。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。