[AS3]BaseSocket类-可以提升Socket数据传输效率
需要Flash Player 9.0或更高版本的支持
原理就是结合AMF3和ByteArray的特性对原来数据进行压缩后再传输,这样就可以大大提高数据传输效率。
我现在把客户端方法进行优化,现在写成一个BaseSocket类来方便调用。
BaseSocket类
- /**
- * @author Kinglong
- * @link kinglong@gmail.com
- * @builddate 20081121
- * @flashplayerversion 9+
- * @version 0.1
- */
- package
com.klstudio.socket { - import
flash.events.*; - import
flash.net.Socket; - import
flash.net.ObjectEncoding; - import
flash.system.Security; - import
flash.utils.ByteArray; - public
class
BaseSocket extends
EventDispatcher{ - private
var _host:String; - private
var _port:uint; - private
var _socket:Socket; - public
function BaseSocket(host:String, port:uint = 80
) { - this
._host = host; - this
._port = port; - this
._socket = new
Socket(); - this
._socket.objectEncoding = ObjectEncoding.AMF3; - Security.loadPolicyFile("xmlsocket://"
+ this
.host + ":"
+ this
.port); - this
._socket.addEventListener(Event.CONNECT, handler); - this
._socket.addEventListener(Event.CLOSE, handler); - this
._socket.addEventListener(IOErrorEvent.IO_ERROR, handler); - this
._socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handler); - this
._socket.addEventListener(ProgressEvent.SOCKET_DATA, handler); - }
- public
function get host():String { - return
_host; - }
- public
function get port():uint { - return
_port; - }
- public
function get connected():Boolean { - return
this
._socket.connected; - }
- public
function connect():void
{ - this
._socket.connect(host, port); - }
- public
function close():void
{ - this
._socket.close(); - }
- public
function send(params:Object=null
):void
{ - if
(!this
.connected || params == null
){ - return
; - }
- var bytes:ByteArray = new
ByteArray(); - bytes.writeObject(params);
- bytes.compress();
- this
._socket.writeBytes(bytes); - this
._socket.flush(); - this
.dispatchEvent(new
BaseSocketEvent(BaseSocketEvent.SENDING, params)); - }
- private
function received():void
{ - var bytes:ByteArray = new
ByteArray(); - while
(this
._socket.bytesAvailable > 0
) { - this
._socket.readBytes(bytes, 0
, this
._socket.bytesAvailable); - }
- try
{ - bytes.uncompress();
- this
.dispatchEvent(new
BaseSocketEvent(BaseSocketEvent.RECEIVED, bytes.readObject())); - }catch
(error:Error) { - this
.dispatchEvent(new
BaseSocketEvent(BaseSocketEvent.DECODE_ERROR)); - }
- }
- private
function handler(event:Event):void
{ - switch
(event.type) { - case
Event.CLOSE: - this
.dispatchEvent(new
BaseSocketEvent(BaseSocketEvent.CLOSE)); - break
; - case
Event.CONNECT: - case
IOErrorEvent.IO_ERROR: - case
SecurityErrorEvent.SECURITY_ERROR: - this
.dispatchEvent(new
BaseSocketEvent(event.type)); - break
; - case
ProgressEvent.SOCKET_DATA: - this
.received(); - break
; - }
- }
- }
- }
- /**<br/>*
- @author Kinglong<br/>* @link kinglong@gmail.com<br/>*
- @builddate 20081121<br/>* @flashplayerversion 9+<br/>*
- @version 0.1<br/>*/
<br/><br/>package
- com.klstudio.socket { <br/> <br/> import
- flash.events.*;<br/> import
flash.net.Socket;<br/> import
- flash.net.ObjectEncoding;<br/> import
- flash.system.Security;<br/> import
- flash.utils.ByteArray;<br/><br/> public
class
BaseSocket - extends
EventDispatcher{<br/> <br/> private
var - _host:String;<br/> private
var _port:uint;<br/> private
var - _socket:Socket;<br/> <br/> public
function - BaseSocket(host:String, port:uint = 80
) {<br/> this
._host = - host;<br/> this
._port = port;<br/> this
._socket = new
- Socket();<br/> this
._socket.objectEncoding = ObjectEncoding.AMF3; - <br/> Security.loadPolicyFile("xmlsocket://"
+ this
.host + ":"
+ - this
.port);<br/> this
._socket.addEventListener(Event.CONNECT, - handler);<br/> this
._socket.addEventListener(Event.CLOSE, - handler);<br/>
- this
._socket.addEventListener(IOErrorEvent.IO_ERROR, - handler);<br/>
- this
._socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, - handler);<br/>
- this
._socket.addEventListener(ProgressEvent.SOCKET_DATA, - handler);<br/> }<br/> <br/> public
function get - host():String {<br/> return
_host;<br/> }<br/> - <br/> public
function get port():uint {<br/> return
- _port;<br/> }<br/> <br/> public
function get - connected():Boolean {<br/> return
- this
._socket.connected;<br/> }<br/> <br/> public
- function connect():void
{<br/> this
._socket.connect(host, - port);<br/> }<br/> <br/> public
function close():void
- {<br/> this
._socket.close();<br/> }<br/> <br/> - public
function send(params:Object=null
):void
{<br/> - if
(!this
.connected || params == null
){<br/> return
;<br/> - }<br/> var bytes:ByteArray = new
ByteArray();<br/> - bytes.writeObject(params);<br/> bytes.compress();<br/>
- this
._socket.writeBytes(bytes);<br/> - this
._socket.flush();<br/> this
.dispatchEvent(new
- BaseSocketEvent(BaseSocketEvent.SENDING, params)); <br/>
- }<br/> <br/> private
function received():void
{ <br/> - var bytes:ByteArray = new
ByteArray();<br/> while
- (this
._socket.bytesAvailable > 0
) {<br/> - this
._socket.readBytes(bytes, 0
, - this
._socket.bytesAvailable);<br/> }<br/> try
{ <br/> - bytes.uncompress();<br/> this
.dispatchEvent(new
- BaseSocketEvent(BaseSocketEvent.RECEIVED,
- bytes.readObject()));<br/> }catch
(error:Error) {<br/> - this
.dispatchEvent(new
- BaseSocketEvent(BaseSocketEvent.DECODE_ERROR));<br/> }<br/>
- }<br/> <br/> private
function handler(event:Event):void
- {<br/> switch
(event.type) {<br/> case
- Event.CLOSE:<br/> this
.dispatchEvent(new
- BaseSocketEvent(BaseSocketEvent.CLOSE));<br/> break
;<br/> - case
Event.CONNECT: <br/> case
IOErrorEvent.IO_ERROR:<br/> - case
SecurityErrorEvent.SECURITY_ERROR:<br/> - this
.dispatchEvent(new
BaseSocketEvent(event.type));<br/> - break
;<br/> case
ProgressEvent.SOCKET_DATA:<br/> - this
.received();<br/> break
;<br/> }<br/> }<br/> - }<br/>}
BaseSocketEvent类
- /**
- * @author Kinglong
- * @link kinglong@gmail.com
- * @builddate 20081121
- * @flashplayerversion 9+
- * @version 0.1
- */
- package
com.klstudio.socket { - import
flash.events.*; - public
class
BaseSocketEvent extends
Event { - public
static
const
SECURITY_ERROR:String = SecurityErrorEvent.SECURITY_ERROR; - public
static
const
IO_ERROR:String = IOErrorEvent.IO_ERROR; - public
static
const
DECODE_ERROR:String = "decode_error"
; - public
static
const
RECEIVED:String = "received"
; - public
static
const
SENDING:String = "sending"
; - public
static
const
CLOSE:String = Event.CLOSE; - public
static
const
CONNECT:String = Event.CONNECT; - private
var _data:Object; - public
function BaseSocketEvent(type:String, data:Object = null
) { - super
(type, true
); - this
._data = data; - }
- public
function get data():Object { - return
_data; - }
- override public
function toString():String { - return
formatToString("BaseSocketEvent"
, "type"
, "bubbles"
, "cancelable"
, "data"
); - }
- override public
function clone():Event { - return
new
BaseSocketEvent(type, data); - }
- }
- }
- /**<br/>*
- @author Kinglong<br/>* @link kinglong@gmail.com<br/>*
- @builddate 20081121<br/>* @flashplayerversion 9+<br/>*
- @version 0.1<br/>*/
<br/><br/>package
- com.klstudio.socket {<br/> <br/> import
- flash.events.*;<br/><br/> public
class
BaseSocketEvent - extends
Event {<br/> <br/> public
static
const
- SECURITY_ERROR:String = SecurityErrorEvent.SECURITY_ERROR;<br/>
- public
static
const
IO_ERROR:String = IOErrorEvent.IO_ERROR;<br/> - public
static
const
DECODE_ERROR:String = "decode_error"
;<br/> - public
static
const
RECEIVED:String = "received"
;<br/> public
- static
const
SENDING:String = "sending"
;<br/> public
static
const
- CLOSE:String = Event.CLOSE;<br/> public
static
const
- CONNECT:String = Event.CONNECT;<br/> <br/> private
var - _data:Object;<br/> <br/> public
function - BaseSocketEvent(type:String, data:Object = null
) {<br/> - super
(type, true
);<br/> this
._data = data; <br/> - }<br/> <br/> public
function get data():Object {<br/> - return
_data;<br/> }<br/> <br/> override public
- function toString():String {<br/> return
- formatToString("BaseSocketEvent"
, "type"
, "bubbles"
, "cancelable"
, - "data"
);<br/> }<br/> <br/> override public
function - clone():Event {<br/> return
new
BaseSocketEvent(type, - data);<br/> }<br/> }<br/> <br/>}
调用实例
- /**
- * ...
- * @author Kinglong
- * @version 0.1
- */
- package
project.test { - import
flash.display.*; - import
flash.events.*; - import
flash.text.TextField; - import
com.klstudio.data.Map; - import
com.klstudio.socket.BaseSocket; - import
com.klstudio.socket.BaseSocketEvent; - public
class
TestGame extends
Sprite { - private
var _socket:BaseSocket; - private
var _id:uint; - private
var _lists:Map; - private
var _info:TextField; - public
function TestGame() { - _info = new
TextField(); - _info.selectable = false
; - _info.text = "未连接"
; - addChild(_info);
- stage.addEventListener(MouseEvent.MOUSE_UP, stageHandler);
- _lists = new
Map(); - _socket = new
BaseSocket("localhost"
, 110
); - configureListeners(_socket);
- _socket.connect();
- }
- private
function configureListeners(dispatcher:IEventDispatcher):void
{ - dispatcher.addEventListener(BaseSocketEvent.CLOSE, handler);
- dispatcher.addEventListener(BaseSocketEvent.CONNECT, handler);
- dispatcher.addEventListener(BaseSocketEvent.IO_ERROR, handler);
- dispatcher.addEventListener(BaseSocketEvent.SECURITY_ERROR, handler);
- dispatcher.addEventListener(BaseSocketEvent.SENDING, handler);
- dispatcher.addEventListener(BaseSocketEvent.RECEIVED, handler);
- dispatcher.addEventListener(BaseSocketEvent.DECODE_ERROR, handler);
- }
- private
function handler(event:BaseSocketEvent):void
{ - switch
(event.type) { - case
BaseSocketEvent.RECEIVED: - receive(event.data);
- break
; - case
BaseSocketEvent.CLOSE: - debug("连接关闭"
); - removeAll();
- break
; - case
BaseSocketEvent.CONNECT: - debug("连接中..."
); - _socket.send( { event:"init"
} ); - break
; - case
BaseSocketEvent.IO_ERROR: - case
BaseSocketEvent.SECURITY_ERROR: - debug("连接失败"
); - break
; - case
BaseSocketEvent.DECODE_ERROR: - debug("解码失败"
); - break
; - }
- }
- private
function stageHandler(event:MouseEvent):void
{ - _socket.send( { event:"move"
, x:this
.mouseX, y:this
.mouseY } ); - }
- private
function receive(object:Object):void
{ - switch
(object.event) { - case
"init"
: - init(object.id);
- for
(var i:uint = 0
; i < object.list.length; i++ ) { - var item:Object = object.list[i];
- add(item.id, item.x, item.y);
- }
- break
; - case
"move"
: - move(object.id, object.x, object.y);
- break
; - case
"remove"
: - remove(object.id);
- break
; - case
"add"
: - add(object.id);
- break
; - }
- }
- private
function init(id:uint):void
{ - this
._id = id; - add(id);
- }
- private
function add(id:uint, x:Number = undefined, y:Number = undefined):void
{ - x = x || stage.stageWidth / 2
; - y = y || stage.stageHeight / 2
; - if
(_lists.containsKey(id)) { - return
; - }
- var role:GameRole = new
GameRole(id,_id == id); - role.move(x,y);
- addChild(role);
- _lists.put(id, role);
- }
- private
function move(id:uint, x:Number, y:Number):void
{ - if
(_lists.containsKey(id)) { - var role:GameRole = _lists.get(id);
- role.to(x, y);
- }
- }
- private
function remove(id:uint):void
{ - if
(_lists.containsKey(id)) { - var role:GameRole = _lists.remove(id);
- trace(role);
- if
(this
.contains(role)) { - removeChild(role);
- }
- role = null
; - }
- }
- private
function removeAll():void
{ - var keys:Array = _lists.keys;
- for
(var i:uint = 0
; i < keys.length; i++ ) { - var role:GameRole = _lists.remove(keys[i]);
- if
(this
.contains(role)) { - removeChild(role);
- }
- role = null
; - }
- }
- private
function debug(msg:String):void
{ - _info.text = msg;
- trace(msg);
- }
- }
- }
- /**<br/>*
- ...<br/>* @author Kinglong<br/>* @version
- 0.1<br/>*/
<br/><br/>package
project.test {<br/> - <br/> import
flash.display.*;<br/> import
- flash.events.*;<br/> import
flash.text.TextField;<br/> - <br/> import
com.klstudio.data.Map;<br/> import
- com.klstudio.socket.BaseSocket;<br/> import
- com.klstudio.socket.BaseSocketEvent;<br/> <br/> public
- class
TestGame extends
Sprite { <br/> private
var - _socket:BaseSocket;<br/> private
var _id:uint;<br/> private
- var _lists:Map;<br/> private
var _info:TextField;<br/> - public
function TestGame() { <br/> _info = new
- TextField();<br/> _info.selectable = false
; <br/> - _info.text = "未连接"
;<br/> addChild(_info); <br/> <br/> - stage.addEventListener(MouseEvent.MOUSE_UP, stageHandler); <br/>
- _lists = new
Map();<br/> _socket = new
BaseSocket("localhost"
,