封装自己的Flex工具_SocketTool
Flex的sdk中已经有Socket类,虽然用起来比较方便,但真正的项目用起来未免有些繁琐了,所以我们有必要对其进行必要的改造下,让Socket更灵敏,更好用!
Flex的Socket可以向其写入Object,本次的工具着重完成写入Object,并且读取SocketServer返回的Object!
1.创建class,SocketTool
public class SocketTool{}
2.为SocketTool添加socket:Socket属性并注册好一些默认的事件监听,将来就靠此属性来完成通信任务!
添加bytes:ByteArray属性,用于将来解压从服务器获取到的字节,之后将解压后的字节读取为Object
再次添加2个状态属性,
_usable,辨别socket是否可以用,
_status,存放socket的状态信息
public class SocketTool
{
private var socket:Socket = new Socket();
private var bytes:ByteArray;
private var byteArrayTool:ByteArrayTool = new ByteArrayTool();
private var _usable:Boolean = false;
private var _statusInfo:String = "状态未知";
public function SocketTool(host:String,port:uint)
{
socket.connect(host,port);
socket.addEventListener(Event.CLOSE,onClose);
socket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
socket.addEventListener(Event.CONNECT,onConn);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);
socket.addEventListener(IOErrorEvent.IO_ERROR,onIoError);
}
//默认 事件
private function onClose(e:Event){
usable = false;
statusInfo = "Socket关闭";
trace("Socket Already Closed");
}
private function onSocketData(e:ProgressEvent){
if(socket.bytesAvailable){
var r:String = socket.readMultiByte(socket.bytesAvailable,"gbk");
usable=true;
statusInfo = "Socket可用";
trace("Receive Server's Data"+r);
}
}
private function onConn(e:Event){
trace("Socket connect complete");
statusInfo = "获取安全信息,Socket不可用";
sendTestInfo();
function sendTestInfo(){
socket.writeMultiByte("<policy-file-request/>","gbk");
socket.flush();
}
}
private function onSecurityError(e:SecurityErrorEvent){
usable = false;
statusInfo = "安全错误,Socket不可用";
trace("SecurityError,check Server's [Cross Domain]");
}
private function onIoError(e:IOErrorEvent){
usable = false;
statusInfo = "io错误,Socket不可用";
trace("IoError");
}
//----
public function get statusInfo():String{
return _statusInfo;
}
public function set statusInfo(_statusInfo:String){
this._statusInfo = _statusInfo;
}
public function get usable():Boolean{
return _usable;
}
public function set usable(_usable:Boolean):void{
this._usable = _usable;
}
//关闭事件
public function addCloseEvent(closeHandler:Function):void{
removeCloseEvent(closeHandler);
socket.addEventListener(Event.CLOSE,closeHandler);
}
public function removeCloseEvent(closeHandler:Function):void{
socket.removeEventListener(Event.CLOSE,closeHandler);
}
//连接ok事件
public function addConnectEvent(connHandler:Function):void{
removeConnectEvent(connHandler);
socket.addEventListener(Event.CONNECT,connHandler);
}
public function removeConnectEvent(closeHandler:Function):void{
socket.removeEventListener(Event.CONNECT,closeHandler);
}
//安全失败事件
public function addSecurityErrorEvent(securityHandler:Function):void{
removeSecurityErrorEvent(securityHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityHandler);
}
public function removeSecurityErrorEvent(securityHandler:Function):void{
socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,securityHandler);
}
//io error
public function addIoErrorEvent(ioHandler:Function):void{
removeIoErrorEvent(ioHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,ioHandler);
}
public function removeIoErrorEvent(ioHandler:Function):void{
socket.removeEventListener(IOErrorEvent.IO_ERROR,ioHandler);
}
//收到 数据事件
public function addSocketDataEvent(socketDataHandler:Function):void{
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
function circle(e:TimerEvent){
if(usable){
removeSocketDataEvent(onSocketData); //移除默认事件
socket.addEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
statusInfo = "Socket已可用";
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
}
public function removeSocketDataEvent(socketDataHandler:Function):void{
socket.removeEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
}
//添加上connect方法,便于将来再次连接服务器
//连接服务器
public function connect(host:String,port:uint){
socket.connect(host,port);
}
ok,到目前为止,初始化的任务完成,重要的方法就要开始.
任务1.让socket发送Object,如果服务器响应了,触发某个回调
/**
* 通过回调方式完成一次发送与接收
* @send:要发送的对象
* @compress:是否要将发送对象压缩
* @receiverHandler: 接收的回调
* */
public function sendAndReceive(send:Object,receiverHandler:Function,compress:Boolean=false):void{
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
function circle(e:TimerEvent){
if(usable){
writeObject(send,compress);
addSocketDataEvent(receiverHandler);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
}
任务2.让socket发送Object,如果服务器响应了,触发回调,并且将服务器返回的Object放入回调
/**
* 通过回调方式完成一次发送对象与接收对象
* @send:要发送的对象
* @compress:是否要将发送对象压缩
* @receiverObjectHandler: 接收对象的回调
* */
public function sendAndReceiverObject(send:Object,receiverObjectHandler:Function,compress:Boolean=false):void{
var timeout:Boolean = true;
var time:uint = 0;
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
var timer2:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,timeoutCircle);
function circle(e:TimerEvent){
if(usable){
writeObject(send,compress);
addSocketDataEvent(receive);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
function timeoutCircle(e:TimerEvent){
if(!timeout || time >6){//完毕
timer2.stop();
timer2.removeEventListener(TimerEvent.TIMER,timeoutCircle);
}
if(timeout){
time ++;
}
if(time > 6){
Main.statusItem = new ObjectProxy({name:'服务器响应超时'});
}else{
Main.statusItem = new ObjectProxy({name:'数据获取时间:'+time});
}
}
function receive(e:ProgressEvent){
timeout = false;
var resp:Object = readObject(true);
receiverObjectHandler(resp);
removeSocketDataEvent(receive);
}
}
ok,到此今天的任务就完成了,我们利用socket的writeObject,readObject方法与服务器进行通信,用socket以amf3完成Object方式完成通信!
以下是此类的完成代码
=======================================================================
类.SocketTool
package org.sk.tools
{
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.utils.Timer;
import mx.utils.ObjectProxy;
/**
* Socket工具
* */
public class SocketTool
{
private var socket:Socket = new Socket();
private var bytes:ByteArray;
private var byteArrayTool:ByteArrayTool = new ByteArrayTool();
private var _usable:Boolean = false;
private var _statusInfo:String = "状态未知";
public function SocketTool(host:String,port:uint)
{
socket.connect(host,port);
socket.addEventListener(Event.CLOSE,onClose);
socket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
socket.addEventListener(Event.CONNECT,onConn);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);
socket.addEventListener(IOErrorEvent.IO_ERROR,onIoError);
}
//默认 事件
private function onClose(e:Event){
usable = false;
statusInfo = "Socket关闭";
trace("Socket Already Closed");
}
private function onSocketData(e:ProgressEvent){
if(socket.bytesAvailable){
var r:String = socket.readMultiByte(socket.bytesAvailable,"gbk");
usable=true;
statusInfo = "Socket可用";
trace("Receive Server's Data"+r);
}
}
private function onConn(e:Event){
trace("Socket connect complete");
statusInfo = "获取安全信息,Socket不可用";
sendTestInfo();
function sendTestInfo(){
socket.writeMultiByte("<policy-file-request/>","gbk");
socket.flush();
}
}
private function onSecurityError(e:SecurityErrorEvent){
usable = false;
statusInfo = "安全错误,Socket不可用";
trace("SecurityError,check Server's [Cross Domain]");
}
private function onIoError(e:IOErrorEvent){
usable = false;
statusInfo = "io错误,Socket不可用";
trace("IoError");
}
//----
public function get statusInfo():String{
return _statusInfo;
}
public function set statusInfo(_statusInfo:String){
this._statusInfo = _statusInfo;
}
public function get usable():Boolean{
return _usable;
}
public function set usable(_usable:Boolean):void{
this._usable = _usable;
}
//关闭事件
public function addCloseEvent(closeHandler:Function):void{
removeCloseEvent(closeHandler);
socket.addEventListener(Event.CLOSE,closeHandler);
}
public function removeCloseEvent(closeHandler:Function):void{
socket.removeEventListener(Event.CLOSE,closeHandler);
}
//连接ok事件
public function addConnectEvent(connHandler:Function):void{
removeConnectEvent(connHandler);
socket.addEventListener(Event.CONNECT,connHandler);
}
public function removeConnectEvent(closeHandler:Function):void{
socket.removeEventListener(Event.CONNECT,closeHandler);
}
//安全失败事件
public function addSecurityErrorEvent(securityHandler:Function):void{
removeSecurityErrorEvent(securityHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityHandler);
}
public function removeSecurityErrorEvent(securityHandler:Function):void{
socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR,securityHandler);
}
//io error
public function addIoErrorEvent(ioHandler:Function):void{
removeIoErrorEvent(ioHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,ioHandler);
}
public function removeIoErrorEvent(ioHandler:Function):void{
socket.removeEventListener(IOErrorEvent.IO_ERROR,ioHandler);
}
//收到 数据事件
public function addSocketDataEvent(socketDataHandler:Function):void{
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
function circle(e:TimerEvent){
if(usable){
removeSocketDataEvent(onSocketData); //移除默认事件
socket.addEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
statusInfo = "Socket已可用";
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
}
public function removeSocketDataEvent(socketDataHandler:Function):void{
socket.removeEventListener(ProgressEvent.SOCKET_DATA,socketDataHandler);
}
//连接服务器
public function connect(host:String,port:uint){
socket.connect(host,port);
}
/**
* 通过回调方式完成一次发送与接收
* @send:要发送的对象
* @compress:是否要将发送对象压缩
* @receiverHandler: 接收的回调
* */
public function sendAndReceive(send:Object,receiverHandler:Function,compress:Boolean=false):void{
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
function circle(e:TimerEvent){
if(usable){
writeObject(send,compress);
addSocketDataEvent(receiverHandler);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
}
/**
* 通过回调方式完成一次发送对象与接收对象
* @send:要发送的对象
* @compress:是否要将发送对象压缩
* @receiverObjectHandler: 接收对象的回调
* */
public function sendAndReceiverObject(send:Object,receiverObjectHandler:Function,compress:Boolean=false):void{
var timeout:Boolean = true;
var time:uint = 0;
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
var timer2:Timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER,timeoutCircle);
function circle(e:TimerEvent){
if(usable){
writeObject(send,compress);
addSocketDataEvent(receive);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
function timeoutCircle(e:TimerEvent){
if(!timeout || time >6){//完毕
timer2.stop();
timer2.removeEventListener(TimerEvent.TIMER,timeoutCircle);
}
if(timeout){
time ++;
}
if(time > 6){
Main.statusItem = new ObjectProxy({name:'服务器响应超时'});
}else{
Main.statusItem = new ObjectProxy({name:'数据获取时间:'+time});
}
}
function receive(e:ProgressEvent){
timeout = false;
var resp:Object = readObject(true);
receiverObjectHandler(resp);
removeSocketDataEvent(receive);
}
}
/**
* 从Socket中读取压缩对象
* @uncompress:是否解压
* */
private function readObject(uncompress:Boolean=false):Object{
if(socket.bytesAvailable){
bytes = new ByteArray();
socket.readBytes(bytes,0,socket.bytesAvailable);
try{
if(uncompress){
bytes.uncompress();
}
var obj:Object = bytes.readObject();
return obj;
}catch(e){
var str:String = bytes.readMultiByte(socket.bytesAvailable,'gbk');
trace(str);
}
}
return null;
}
/**
* 向Socket中写入对象
* @compress:是否需要压缩
* */
private function writeObject(obj:Object,compress:Boolean=false):void{
var timer:Timer = new Timer(400);
timer.addEventListener(TimerEvent.TIMER,circle);
timer.start();
function circle(e:TimerEvent){
if(usable){
bytes = new ByteArray();
bytes.writeObject(obj);
if(compress)
bytes.compress();
socket.writeBytes(bytes,0,bytes.length);
socket.flush();
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,circle);
}
}
}
/**
* 自动分段 传递对象
* @obj:as对象
* @compress:是否压缩
* @size:每段字节个数
* */
public function writeParticalObjectAuto(obj:Object,compress:Boolean=false,size:uint=1){
if(socket){
bytes = new ByteArray();
bytes.writeObject(obj);
if(compress)
bytes.compress();
arr = byteArrayTool.split(bytes,size);
if(arr){
socket.removeEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
socket.addEventListener(ProgressEvent.SOCKET_DATA,autoReceive);
autoSend(); //开始发送
}
}
var index:uint = 0; //当前的位置索引
var arr:Array;
//自动发送
function autoSend(){
var o:ByteArray = arr[index];
//生成 部分对象
var part:Object ={};
part.partical = o;
part.pos = index;
part.len = arr.length;
writeObject(part);
}
//自动接收
function autoReceive(e:ProgressEvent){
if(socket.bytesAvailable){
var obj:Object = readObject(true);
if(obj.next == "next"){
index ++;
autoSend();
}else if(obj.next == "done"){
socket.removeEventListener(ProgressEvent.SOCKET_DATA,autoReceive);
socket.addEventListener(ProgressEvent.SOCKET_DATA,onSocketData);
trace("对象序列全部发送完毕");
}
}
}
}
}
}
2.类 ByteArrayTool
package org.sk.tools
{
import flash.utils.ByteArray;
/*
* 字节数组工具
*/
public class ByteArrayTool
{
public function ByteArrayTool()
{
}
/**
* 将ByteArray拆分成若干段ByteArray,存入数组
* @bytes : ByteArray
* @size : 每组的最多的字节个数
* */
public function split(bytes:ByteArray,size:uint=1):Array{
var arr:Array = [];
if(bytes.length < size){
arr.push(bytes);
return arr;
}
var len:uint = bytes.length / size;
var remain:uint = bytes.length % size;
for(var i:uint = 0;i < len; i++){
var tmp:ByteArray = new ByteArray();
tmp.writeBytes(bytes,i*size,size);
arr.push(tmp);
}
if(remain > 0){
var tmp:ByteArray = new ByteArray();
tmp.writeBytes(bytes,len * size ,remain);
arr.push(tmp);
}
return arr;
}
/**
* @size : size 组
* */
public function split2(bytes:ByteArray,groupSize:uint):Array{
var arr:Array = [];
var count:uint = bytes.length / groupSize; //每组的字节数
var remain:uint = bytes.length % groupSize;
for(var i:uint = 0;i<groupSize;i++){
var tmp:ByteArray = new ByteArray();
tmp.writeBytes(bytes,i*groupSize,count);
if(i == (groupSize-1)){
if(remain > 0){
tmp.writeBytes(bytes,groupSize * count,remain);
}
}
arr.push(tmp);
}
return arr;
}
}
}