templates/as3/org/rubyforge/dango/DangoClientFramework.as in dango_generator-0.2.5 vs templates/as3/org/rubyforge/dango/DangoClientFramework.as in dango_generator-0.2.6

- old
+ new

@@ -28,28 +28,34 @@ private var dispatcher:EventDispatcher; // Event送出用 private var is_debug:Boolean; // Debugモードかどうかのフラグ private var is_connect:Boolean = false; // 接続完了しているかどうか - private var receve_count:uint = 0; // データ受信回数 private var frame_rate:uint = 24; // デフォルトのフレームレート(想定値) - private var receive_cache:Array = []; // 受信データの一時保管用のキャッシュ - private var recv_not_yet_size:uint = 0; // データ受信時のキャッシュサイズ - private var recv_not_yet_str:String = ""; // データ受信時のキャッシュデータ - private var polling_timer:Timer; // ポーリング(ハートビート)用タイマーの設定 private var polling_timer_msec:uint = 5000; // ポーリング(ハートビート)用タイマーのミリ秒 private var delay_send_timer:Timer; // 遅延送信用のタイマーの設定 private var delay_send_timer_msec:uint = 1500; // 遅延送信用のタイマーのミリ秒 private var delay_send_cache:Array = []; // 遅延送信用のキャッシュ - private var recv_timer_msec:uint; // 受信用タイマーの実行間隔 - private var recv_timer:Timer; // 受信用タイマーの追加 - private var recv_last_date:Date = new Date(); // 受信用処理落ちチェック用 + private var receve_count:uint = 0; // データ受信回数 + private var receive_row_cache:Array = []; // 受信データの一時保管用のキャッシュ + private var recv_not_yet_size:uint = 0; // データ受信時のキャッシュサイズ + private var recv_not_yet_str:String = ""; // データ受信時のキャッシュデータ + + private var recv_wait_do_cache:Array = []; // 実行待ち受信キャッシュ + private var recv_cache_timer_msec:uint; // 受信キャッシュ用タイマーの実行間隔 + private var recv_cache_timer:Timer; // 受信キャッシュ用タイマーの追加 + + private var recv_do_count_no:uint = 0; // 受信実行の回数 + private var recv_do_timer_msec:uint; // 受信実行用タイマーの実行間隔 + private var recv_do_timer:Timer; // 受信実行用タイマーの追加 + private var recv_do_last_date:Date = new Date(); // 受信キャッシュ用処理落ちチェック用 + public var server_time:String = ""; // サーバーの時計 // private var server_host:String = "172.31.1.74"; // private var server_host:String = "localhost"; // private var server_port:int = 15000; @@ -134,17 +140,24 @@ // 遅延送信用タイマーの設定 var delay_send_timer:Timer = new Timer(delay_send_timer_msec, 0); // タイマーの追加 delay_send_timer.addEventListener(TimerEvent.TIMER, delay_send_callback); // イベントリスナーの発行 delay_send_timer.start(); // タイマーの作動開始 - // fps用タイマーの設定(3フレームごとに動かすよう変更) - recv_timer_msec = uint((1000 * 3) / frame_rate); - if(is_debug){ trace("DangoClientFramework:recv_timer_msec:" + recv_timer_msec); } - recv_timer = new Timer(recv_timer_msec, 0); // タイマーの追加 - recv_timer.addEventListener(TimerEvent.TIMER, recv_callback); // イベントリスナーの発行 - recv_timer.start(); // タイマーの作動開始 + // 受信キャッシュ用タイマーの設定(4フレームごとに動かすよう変更) + recv_cache_timer_msec = uint((1000 * 4) / frame_rate); + if(is_debug){ trace("DangoClientFramework:recv_cache_timer_msec:" + recv_cache_timer_msec); } + recv_cache_timer = new Timer(recv_cache_timer_msec, 0); // タイマーの追加 + recv_cache_timer.addEventListener(TimerEvent.TIMER, recv_cache_callback); // イベントリスナーの発行 + recv_cache_timer.start(); // タイマーの作動開始 + // 受信実行用タイマーの設定(2フレームごとに動かすよう変更) + recv_do_timer_msec = uint((1000 * 2) / frame_rate); + if(is_debug){ trace("DangoClientFramework:recv_do_timer_msec:" + recv_do_timer_msec); } + recv_do_timer = new Timer(recv_do_timer_msec, 0); // タイマーの追加 + recv_do_timer.addEventListener(TimerEvent.TIMER, recv_do_callback); // イベントリスナーの発行 + recv_do_timer.start(); // タイマーの作動開始 + // 接続完了のときに接続完了をサーバーに通知するためのハートビート送信 var hb_id:String = make_heartbeat(); this.send_action("_notice_heart_beat", { "_hb_id": hb_id}, true); // ハートビート送信 } @@ -187,49 +200,18 @@ var msg:String = "DangoClientFramework:ioErrorHandler:" + DangoUtil.now2str(); if(is_debug){ trace(msg); } this.dispatchEvent(new DangoErrorEvent("DangoError", DangoErrorCode.IOError, msg)); } -/* - //プログレスイベントの処理(呼び出し用イベントのディスパッチ) - private function socketDataHandler(evt:ProgressEvent):void { - receve_count ++; - if(is_debug){ trace("DangoClientFramework:socketDataHandler:" + receve_count); } - var receive_data:Object = this.receive_notice(); - - if(recv_not_yet_size == 0){ // 未受信データが無ければ - if(receive_data != {}){ // データが空なら無視する - var notice_name:String = receive_data["notice"]; - - if(notice_name == "_notice_sid"){ // 接続直後のsid通知なら - this.sid = receive_data["_sid"]; -// if(is_debug){ trace("DangoClientFramework:this.sid=" + this.sid + ":" + DangoUtil.now2str()); } - if(is_debug){ trace("DangoClientFramework:this.sid=" + this.sid + ":" + receve_count); } - - } else if(notice_name == "_heart_beat"){ // heart beat通知なら - if(is_debug){ trace("DangoClientFramework:_heart_beat:" + receve_count); } - - } else { // 通常のデータならイベント発生 - if(is_debug){ trace("DangoClientFramework:dispatchEvent:dango_" + notice_name + ":" + receve_count); } - this.dispatchEvent(new DangoReceiveEvent("dango_" + notice_name, receive_data)); - } - } else { // データが空なら -// if(is_debug){ trace("DangoClientFramework:receive_data is empty." + DangoUtil.now2str()); } - if(is_debug){ trace("DangoClientFramework:receive_data is empty."); } - } - } - } -*/ - // プログレスイベントの処理(呼び出し用イベントのディスパッチ) // とにかくキャッシュに入れるだけ private function socketDataHandler(evt:ProgressEvent):void { receve_count ++; if(is_debug){ trace("DangoClientFramework:socketDataHandler:" + receve_count + ":start:" + DangoUtil.now2str()); } var byte_array:ByteArray = new ByteArray; socket.readBytes(byte_array, 0, socket.bytesAvailable); - receive_cache.push([byte_array, receve_count]); + receive_row_cache.push([byte_array, receve_count]); } // Event送出用 public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, @@ -251,68 +233,82 @@ return dispatcher.willTrigger(type); } /** - * recv_callback - * フレームレート単位で動く処理(キャッシュにデータがあればデータ受信) + * recv_cache_callback + * 受信データの再構成とキャッシュをする * * @param evt:TimerEvent * @return void */ - public function recv_callback(evt:TimerEvent):void { -// if(is_debug){ trace("DangoClientFramework:recv_callback:" + DangoUtil.now2str()); } + public function recv_cache_callback(evt:TimerEvent):void { +// if(is_debug){ trace("DangoClientFramework:recv_cache_callback:" + DangoUtil.now2str()); } + if(receive_row_cache.length > 0){ + if(is_debug){ trace("DangoClientFramework:recv_cache_callback:receive_row_cache.length=" + receive_row_cache.length + ":" + DangoUtil.now2str()); } + var arr:Array = receive_row_cache.shift(); // Queueとして取り出し + var byte_array:ByteArray = arr[0]; + var recv_c:uint = arr[1]; +// if(is_debug){ trace("DangoClientFramework:recv_c=" + recv_c); } + var receive_data:Array = this.parse_notice(byte_array); + + if(recv_not_yet_size == 0){ // 未受信データが無ければ、ひとつのデータ受信が完了とみなす + if(receive_data != []){ // データが空じゃなければ処理開始 + for(var i:uint = 0; i < receive_data.length; i++){ + var notice_name:String = receive_data[i]["notice"]; + var recv_server_time:String = receive_data[i]["server_time"]; + + if(is_debug){ trace("DangoClientFramework:push recv_wait_do_cache:dango_" + notice_name + ": recv_c:" + recv_c + ":" + i + " recv_server_time:" + recv_server_time); } + recv_wait_do_cache.push([notice_name, receive_data[i], recv_server_time, recv_do_count_no]); + + recv_do_count_no ++; + } + } else { // データが空なら +// if(is_debug){ trace("DangoClientFramework:receive_data is empty." + DangoUtil.now2str()); } + if(is_debug){ trace("DangoClientFramework:receive_data is empty."); } + } + } + } + } + + /** + * recv_do_callback + * 受信データの実行する処理 + * + * @param evt:TimerEvent + * @return void + */ + public function recv_do_callback(evt:TimerEvent):void { +// if(is_debug){ trace("DangoClientFramework:recv_do_callback:" + DangoUtil.now2str()); } + // 前回から時間がかかりすぎている(処理落ちしかけている場合は)スキップ var start_date:Date = new Date(); -// if(is_debug){ trace("DangoClientFramework:recv_last_date.time=" + recv_last_date.time + " start_date.time=" + start_date.time); } - if(recv_last_date.time > start_date.time - (recv_timer_msec * 1.5)){ - if(receive_cache.length > 0){ -// while(receive_cache.length > 0){ - if(is_debug){ trace("DangoClientFramework:recv_callback:receive_cache.length=" + receive_cache.length + ":" + DangoUtil.now2str()); } - var arr:Array = receive_cache.shift(); // Queueとして取り出し - var byte_array:ByteArray = arr[0]; - var recv_c:uint = arr[1]; - if(is_debug){ trace("DangoClientFramework:recv_c=" + recv_c); } - var receive_data:Array = this.receive_notice(byte_array); + if(recv_do_last_date.time > start_date.time - (Number(recv_do_timer_msec) * 1.3)){ + if(recv_wait_do_cache.length > 0){ + var recv_arr:Array = recv_wait_do_cache.shift(); + var notice_name:String = recv_arr[0]; + var recv_data:Object = recv_arr[1]; + server_time = recv_arr[2]; + var count_no:uint = recv_arr[3]; - if(recv_not_yet_size == 0){ // 未受信データが無ければ、ひとつのデータ受信が完了とみなす - if(receive_data != []){ // データが空じゃなければ処理開始 - for(var i:uint = 0; i < receive_data.length; i++){ - var notice_name:String = receive_data[i]["notice"]; - server_time = receive_data[i]["server_time"]; - - if(notice_name == "_notice_sid"){ // 接続直後のsid通知なら - this.sid = receive_data[i]["_sid"]; - if(is_debug){ trace("DangoClientFramework:this.sid=" + this.sid + " recv_c:" + recv_c + " server_time:" + server_time); } - - } else { // 通常のデータならイベント発生 - if(is_debug){ trace("DangoClientFramework:dispatchEvent:dango_" + notice_name + ": recv_c:" + recv_c + ":" + i + " server_time:" + server_time); } - this.dispatchEvent(new DangoReceiveEvent("dango_" + notice_name, receive_data[i])); - } - } - } else { // データが空なら - // if(is_debug){ trace("DangoClientFramework:receive_data is empty." + DangoUtil.now2str()); } - if(is_debug){ trace("DangoClientFramework:receive_data is empty."); } - } + if(notice_name == "_notice_sid"){ // 接続直後のsid通知なら + this.sid = recv_data["_sid"]; + if(is_debug){ trace("DangoClientFramework:this.sid=" + this.sid + " server_time=" + server_time); } + + } else { // 通常のデータならイベント発生 + if(is_debug){ trace("DangoClientFramework:dispatchEvent:dango_" + notice_name + " server_time=" + server_time); } + this.dispatchEvent(new DangoReceiveEvent("dango__before_filter", recv_data, count_no)); + this.dispatchEvent(new DangoReceiveEvent("dango_" + notice_name, recv_data, count_no)); } - -/* - // 処理に時間がかかりすぎている場合は、スキップさせる(while用) - if(is_debug){ trace("DangoClientFramework:recv_callback:end_date:" + DangoUtil.now2str()); } - var end_date:Date = new Date(); - if(start_date.time < end_date.time - recv_timer_msec){ - if(is_debug){ trace("DangoClientFramework:break"); } - break; - } -*/ } } - recv_last_date = new Date(); + recv_do_last_date = new Date(); // 前回の実行の終了時間の保持 } + /** * polling_callback * ハートビート用タイマーコールバック * * @param evt:TimerEvent @@ -355,11 +351,11 @@ var send_obj_dup:Array; var i:uint; for (i = 0; i < 5; i++) { if(delay_send_cache.length == 0) { break; } - send_obj_dup = delay_send_cache.pop(); + send_obj_dup = delay_send_cache.shift(); // データをすぐ送信 this.send_data_to_server(send_obj_dup); if(is_debug){ trace("DangoClientFramework:delay_send_callback:sent:" + DangoUtil.now2str()); } } } @@ -437,16 +433,16 @@ // if(is_debug){ trace("DangoClientFramework:send_obj_str:" + send_obj_str + ":" + DangoUtil.now2str()); } } /** * receive data from server. - * フレームワーク側のデータ受信の一般処理 + * データ受信のデータのパースなど * * @return Object */ - public function receive_notice(byte_array:ByteArray):Array { - if(is_debug){ trace("DangoClientFramework:receive_notice:" + DangoUtil.now2str()); } + public function parse_notice(byte_array:ByteArray):Array { + if(is_debug){ trace("DangoClientFramework:parse_notice:" + DangoUtil.now2str()); } // 変数定義 var recv_data_orig:String = ""; // まず読めるデータをすべてByteArrayに入れる @@ -531,7 +527,17 @@ recv_not_yet_str += recv_data_orig; return([]); } } + /** + * dango_before_filter の雛形 + * すべてのdango通知の前処理用のメソッド + * over writeすべし + * + * @param evt:DangoReceiveEvent + * @return void + protected function dango__before_filter(evt:Object):void { + } + */ } }