[AS3]BaseSocket类-可以提升Socket数据传输效率

需要Flash Player 9.0或更高版本的支持

原理就是结合AMF3和ByteArray的特性对原来数据进行压缩后再传输,这样就可以大大提高数据传输效率。

我现在把客户端方法进行优化,现在写成一个BaseSocket类来方便调用。



BaseSocket类

  1. /** 
  2. * @author Kinglong 
  3. * @link kinglong@gmail.com 
  4. * @builddate 20081121 
  5. * @flashplayerversion 9+ 
  6. * @version 0.1 
  7. */  
  8.   
  9. package com.klstudio.socket {     
  10.       
  11.     import flash.events.*;  
  12.     import flash.net.Socket;  
  13.     import flash.net.ObjectEncoding;  
  14.     import flash.system.Security;  
  15.     import flash.utils.ByteArray;  
  16.   
  17.     public class BaseSocket extends EventDispatcher{  
  18.           
  19.         private var _host:String;  
  20.         private var _port:uint;  
  21.         private var _socket:Socket;  
  22.           
  23.         public function BaseSocket(host:String, port:uint = 80) {  
  24.             this._host = host;  
  25.             this._port = port;  
  26.             this._socket = new Socket();  
  27.             this._socket.objectEncoding = ObjectEncoding.AMF3;            
  28.             Security.loadPolicyFile("xmlsocket://" + this.host + ":" + this.port);  
  29.             this._socket.addEventListener(Event.CONNECT, handler);  
  30.             this._socket.addEventListener(Event.CLOSE, handler);  
  31.             this._socket.addEventListener(IOErrorEvent.IO_ERROR, handler);  
  32.             this._socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler);  
  33.             this._socket.addEventListener(ProgressEvent.SOCKET_DATA, handler);  
  34.         }  
  35.           
  36.         public function get host():String {  
  37.             return _host;  
  38.         }  
  39.           
  40.         public function get port():uint {  
  41.             return _port;  
  42.         }  
  43.           
  44.         public function get connected():Boolean {  
  45.             return this._socket.connected;  
  46.         }  
  47.           
  48.         public function connect():void {  
  49.             this._socket.connect(host, port);  
  50.         }  
  51.           
  52.         public function close():void {  
  53.             this._socket.close();  
  54.         }  
  55.           
  56.         public function send(params:Object=null):void {  
  57.             if(!this.connected || params == null){  
  58.                 return;  
  59.             }  
  60.             var bytes:ByteArray = new ByteArray();  
  61.             bytes.writeObject(params);  
  62.             bytes.compress();  
  63.             this._socket.writeBytes(bytes);  
  64.             this._socket.flush();  
  65.             this.dispatchEvent(new BaseSocketEvent(BaseSocketEvent.SENDING, params));             
  66.         }  
  67.           
  68.         private function received():void {                
  69.             var bytes:ByteArray = new ByteArray();  
  70.             while (this._socket.bytesAvailable > 0) {  
  71.                 this._socket.readBytes(bytes, 0this._socket.bytesAvailable);  
  72.             }  
  73.             try{                  
  74.                 bytes.uncompress();  
  75.                 this.dispatchEvent(new BaseSocketEvent(BaseSocketEvent.RECEIVED, bytes.readObject()));  
  76.             }catch (error:Error) {  
  77.                 this.dispatchEvent(new BaseSocketEvent(BaseSocketEvent.DECODE_ERROR));  
  78.             }  
  79.         }  
  80.           
  81.         private function handler(event:Event):void {  
  82.             switch(event.type) {  
  83.                 case Event.CLOSE:  
  84.                     this.dispatchEvent(new BaseSocketEvent(BaseSocketEvent.CLOSE));  
  85.                     break;  
  86.                 case Event.CONNECT:                   
  87.                 case IOErrorEvent.IO_ERROR:  
  88.                 case SecurityErrorEvent.SECURITY_ERROR:  
  89.                     this.dispatchEvent(new BaseSocketEvent(event.type));  
  90.                     break;  
  91.                 case ProgressEvent.SOCKET_DATA:  
  92.                     this.received();  
  93.                     break;  
  94.             }  
  95.         }  
  96.     }  
  97. }  


BaseSocketEvent类


  1. /** 
  2. * @author Kinglong 
  3. * @link kinglong@gmail.com 
  4. * @builddate 20081121 
  5. * @flashplayerversion 9+ 
  6. * @version 0.1 
  7. */  
  8.   
  9. package com.klstudio.socket {  
  10.           
  11.     import flash.events.*;  
  12.   
  13.     public class BaseSocketEvent extends Event {  
  14.           
  15.         public static const SECURITY_ERROR:String = SecurityErrorEvent.SECURITY_ERROR;  
  16.         public static const IO_ERROR:String = IOErrorEvent.IO_ERROR;  
  17.         public static const DECODE_ERROR:String = "decode_error";  
  18.         public static const RECEIVED:String = "received";  
  19.         public static const SENDING:String = "sending";  
  20.         public static const CLOSE:String = Event.CLOSE;  
  21.         public static const CONNECT:String = Event.CONNECT;  
  22.           
  23.         private var _data:Object;  
  24.           
  25.         public function BaseSocketEvent(type:String, data:Object = null) {  
  26.             super(type, true);  
  27.             this._data = data;            
  28.         }  
  29.           
  30.         public function get data():Object {  
  31.             return _data;  
  32.         }  
  33.           
  34.         override public function toString():String {  
  35.             return formatToString("BaseSocketEvent""type""bubbles""cancelable""data");  
  36.         }  
  37.           
  38.         override public function clone():Event {  
  39.             return new BaseSocketEvent(type, data);  
  40.         }  
  41.     }  
  42.       
  43. }  


调用实例

  1. /** 
  2. * ... 
  3. * @author Kinglong 
  4. * @version 0.1 
  5. */  
  6.   
  7. package project.test {  
  8.       
  9.     import flash.display.*;  
  10.     import flash.events.*;  
  11.     import flash.text.TextField;  
  12.       
  13.     import com.klstudio.data.Map;  
  14.     import com.klstudio.socket.BaseSocket;  
  15.     import com.klstudio.socket.BaseSocketEvent;  
  16.       
  17.     public class TestGame extends Sprite {    
  18.         private var _socket:BaseSocket;  
  19.         private var _id:uint;  
  20.         private var _lists:Map;  
  21.         private var _info:TextField;  
  22.         public function TestGame() {              
  23.             _info = new TextField();  
  24.             _info.selectable = false;             
  25.             _info.text = "未连接";  
  26.             addChild(_info);          
  27.               
  28.             stage.addEventListener(MouseEvent.MOUSE_UP, stageHandler);            
  29.             _lists = new Map();  
  30.             _socket = new BaseSocket("localhost"110);  
  31.             configureListeners(_socket);  
  32.             _socket.connect();            
  33.         }     
  34.           
  35.         private function configureListeners(dispatcher:IEventDispatcher):void {  
  36.             dispatcher.addEventListener(BaseSocketEvent.CLOSE, handler);  
  37.             dispatcher.addEventListener(BaseSocketEvent.CONNECT, handler);  
  38.             dispatcher.addEventListener(BaseSocketEvent.IO_ERROR, handler);  
  39.             dispatcher.addEventListener(BaseSocketEvent.SECURITY_ERROR, handler);  
  40.             dispatcher.addEventListener(BaseSocketEvent.SENDING, handler);  
  41.             dispatcher.addEventListener(BaseSocketEvent.RECEIVED, handler);  
  42.             dispatcher.addEventListener(BaseSocketEvent.DECODE_ERROR, handler);  
  43.         }  
  44.           
  45.         private function handler(event:BaseSocketEvent):void {  
  46.             switch(event.type) {  
  47.                 case BaseSocketEvent.RECEIVED:  
  48.                     receive(event.data);  
  49.                     break;  
  50.                 case BaseSocketEvent.CLOSE:  
  51.                     debug("连接关闭");  
  52.                     removeAll();  
  53.                     break;  
  54.                 case BaseSocketEvent.CONNECT:  
  55.                     debug("连接中...");  
  56.                     _socket.send( { event:"init" } );  
  57.                     break;  
  58.                 case BaseSocketEvent.IO_ERROR:  
  59.                 case BaseSocketEvent.SECURITY_ERROR:  
  60.                     debug("连接失败");  
  61.                     break;  
  62.                 case BaseSocketEvent.DECODE_ERROR:  
  63.                     debug("解码失败");  
  64.                     break;    
  65.             }  
  66.         }  
  67.           
  68.         private function stageHandler(event:MouseEvent):void {  
  69.             _socket.send( { event:"move", x:this.mouseX, y:this.mouseY } );  
  70.         }  
  71.           
  72.         private function receive(object:Object):void {  
  73.             switch(object.event) {  
  74.                 case "init":  
  75.                     init(object.id);  
  76.                     for (var i:uint = 0; i < object.list.length; i++ ) {  
  77.                         var item:Object = object.list[i];  
  78.                         add(item.id, item.x, item.y);  
  79.                     }  
  80.                     break;  
  81.                 case "move":  
  82.                     move(object.id, object.x, object.y);                      
  83.                     break;  
  84.                 case "remove":  
  85.                     remove(object.id);                    
  86.                     break;  
  87.                 case "add":  
  88.                     add(object.id);  
  89.                     break;  
  90.             }  
  91.         }  
  92.           
  93.         private function init(id:uint):void {  
  94.             this._id = id;  
  95.             add(id);  
  96.         }  
  97.           
  98.         private function add(id:uint, x:Number = undefined, y:Number = undefined):void {              
  99.             x = x || stage.stageWidth / 2;  
  100.             y = y || stage.stageHeight / 2;  
  101.             if (_lists.containsKey(id)) {  
  102.                 return;  
  103.             }  
  104.             var role:GameRole = new GameRole(id,_id == id);  
  105.             role.move(x,y);  
  106.             addChild(role);  
  107.             _lists.put(id, role);  
  108.         }  
  109.           
  110.         private function move(id:uint, x:Number, y:Number):void {  
  111.             if (_lists.containsKey(id)) {  
  112.                 var role:GameRole = _lists.get(id);  
  113.                 role.to(x, y);  
  114.             }  
  115.         }  
  116.           
  117.         private function remove(id:uint):void {  
  118.             if (_lists.containsKey(id)) {  
  119.                 var role:GameRole = _lists.remove(id);  
  120.                 trace(role);  
  121.                 if (this.contains(role)) {  
  122.                     removeChild(role);                    
  123.                 }  
  124.                 role = null;  
  125.             }  
  126.         }  
  127.           
  128.         private function removeAll():void {  
  129.             var keys:Array = _lists.keys;  
  130.             for (var i:uint = 0; i < keys.length; i++ ) {  
  131.                 var role:GameRole = _lists.remove(keys[i]);               
  132.                 if (this.contains(role)) {  
  133.                     removeChild(role);  
  134.                 }  
  135.                 role = null;                  
  136.             }  
  137.         }  
  138.           
  139.         private function debug(msg:String):void {  
  140.             _info.text = msg;  
  141.             trace(msg);  
  142.         }  
  143.           
  144.     }  
  145.       
  146. }