Flex amf3通讯协议实例

arthurcsh 12年前

服务端:

import java.io.BufferedOutputStream;     import java.io.BufferedReader;     import java.io.BufferedWriter;     import java.io.ByteArrayInputStream;     import java.io.ByteArrayOutputStream;     import java.io.DataInputStream;     import java.io.DataOutputStream;     import java.io.FileInputStream;     import java.io.FileNotFoundException;     import java.io.FileOutputStream;     import java.io.IOException;     import java.io.InputStreamReader;     import java.io.ObjectOutputStream;     import java.io.OutputStream;     import java.io.OutputStreamWriter;     import java.net.ServerSocket;     import java.net.Socket;     import java.util.HashMap;         import flex.messaging.io.SerializationContext;     import flex.messaging.io.amf.Amf3Input;     import flex.messaging.io.amf.Amf3Output;         public class AmfServer     {     public static void main(String args[])     {        SerializationContext serializationContext=new SerializationContext();               //序列化amf3对象        Amf3Output amfout=new Amf3Output(serializationContext);               //实现了一个输出流,其中的数据被写入一个 byte 数组。        ByteArrayOutputStream byteoutStream=new ByteArrayOutputStream();               //将byteoutStream产生的数组流导入到DataOutputStream流中        DataOutputStream dataoutstream=new DataOutputStream(byteoutStream);               //创建ServerSocket和Socket对象        ServerSocket serverSocekt;        Socket socket;               // 设置流的编码格式为amf3        amfout.setOutputStream(dataoutstream);               //创建Map对象、Double对象数组        HashMap map=new HashMap();        map.put("Event", "人物移动");        map.put("user", "闪刀浪子");        map.put("x", 100);        map.put("y", 100);                 try {         amfout.writeObject(map);//实际上是将map对象写入到dataoutstream流中         dataoutstream.flush();//清空缓存        } catch (IOException e) {         e.printStackTrace();        }               //将ByteArrayOutputStream流中转化成字节数组        byte[] messageBytes=byteoutStream.toByteArray();//amf3数据               OutputStreamWriter osw;//使用amf3格式将写入流中的数据编码成字节        BufferedWriter bwrite;//用来封装OutputStreamWriter,以提高效率               try {                 System.out.println("输出数组长度"+messageBytes.length);            serverSocekt=new ServerSocket(1028);//开启服务器进程            System.out.println("服务器已经启动。。。。。。。");            socket=serverSocekt.accept();            if(socket.isConnected())         {          System.out.println(">>>>>>>>>>客户端已连接");         }         //socket.         osw=new OutputStreamWriter(socket.getOutputStream());//将字符流转化为字节流         bwrite=new BufferedWriter(osw);//封装osw对象,提高写入的效率         socket.getOutputStream().write(messageBytes);//向流中写入二进制数据         socket.getOutputStream().flush();         socket.getOutputStream().close();                } catch (FileNotFoundException e) {           e.printStackTrace();        }        catch (IOException e) {           e.printStackTrace();        }     }     }          客户端:  var socket:Socket=new Socket();     socket.addEventListener(Event.CLOSE, closeHandler);     socket.addEventListener(Event.CONNECT, connectHandler);     socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);     socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);     socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);     socket.connect("localhost",1028);     var obj:Object=new Object();         addEventListener("recieved",recievedData);     function recievedData(evt:Event)     {     switch (obj.Event) {        case "人物移动" :         trace("把玩家:"+obj.user+" 移动到"+obj.x+","+obj.y);         break;        case "人物换装" :         trace("人物换装");         break;        case "消息广播" :         trace("系统信息");         break;        default :         break;     }         };         function closeHandler(event:Event):void {     trace("连接关闭");     }         function connectHandler(event:Event):void {     trace("连接成功");     }         function ioErrorHandler(event:IOErrorEvent):void {     trace("ioErrorHandler信息: " + event);     }         function securityErrorHandler(event:SecurityErrorEvent):void {     trace("securityErrorHandler信息: " + event);     }         function socketDataHandler(event:ProgressEvent):void {       trace("接收数据");    obj=socket.readObject();     this.dispatchEvent(new Event("recieved"));     }          压缩的AMF数据通讯协议    服务端:  上篇文章介绍和如何在java中将数据封装成flash可以直接读取的amf格式,amf虽然已经“压缩”过了(相对其他xml、json等,由于基于二进制而且比较少冗余数据,体积会小很多)。   但是还可以进一步压缩的,由于as3的bytearray支持compress和uncompress。所以我们可以在Java端将数据压缩,然后在flash端读取再解压缩,这样数据在传输过程中又会小很多。   下面就介绍使用方法,基于前篇文章的范例:     服务端:   import java.io.BufferedWriter;   import java.io.ByteArrayOutputStream;   import java.io.DataOutputStream;   import java.io.FileOutputStream;   import java.io.IOException;   import java.io.OutputStreamWriter;   import java.util.ArrayList;   import java.util.HashMap;   import java.util.zip.Deflater;   import java.util.zip.DeflaterOutputStream;   import java.util.zip.Inflater;   import java.util.zip.ZipFile;   import java.util.zip.ZipInputStream;     import flex.messaging.io.SerializationContext;   import flex.messaging.io.amf.Amf3Output;   import flex.messaging.log.Log;   import flex.messaging.messages.Message;       public class Test {     /**   * @param args   */   public static void main(String[] args)   {   SerializationContext serializationContext=new SerializationContext();   Amf3Output amfOut = new Amf3Output(serializationContext);       ByteArrayOutputStream outStream = new ByteArrayOutputStream();       DataOutputStream dataOutStream = new DataOutputStream(outStream);       amfOut.setOutputStream(dataOutStream);              HashMap<String, Object> map=new HashMap<String, Object>();       Double[] arr=new Double[10000];       for(int index=0;index<10000;index++)       {        arr[index]=Math.random();       }       map.put("arr", arr);       map.put("name", "weni");       map.put("age", "27");       try       {   amfOut.writeObject(map);   dataOutStream.flush();   } catch (IOException e)   {   e.printStackTrace();   }         byte[] messageBytes = outStream.toByteArray();                           try        {          FileOutputStream  os;          OutputStreamWriter  ow;          BufferedWriter  out;          os  =  new  FileOutputStream("D://test.txt");          ow  =  new  OutputStreamWriter(os);          out  =  new  BufferedWriter(ow);          os.write(messageBytes);         os.flush();         os.close();         messageBytes=compressBytes(messageBytes); //将数据进行压缩         System.out.println("OK");   }catch(Exception  e)    {   System.out.println("error  :"  +  e);                         }   }     private static int cachesize = 1024;   private static Inflater decompresser = new Inflater();   private static Deflater compresser = new Deflater();   public static byte[] compressBytes(byte input[])   {   compresser.reset();   compresser.setInput(input);   compresser.finish();   byte output[] = new byte[0];   ByteArrayOutputStream o = new ByteArrayOutputStream(input.length);   try   {   byte[] buf = new byte[cachesize];   int got;   while (!compresser.finished())   {   got = compresser.deflate(buf);   o.write(buf, 0, got);   }   output = o.toByteArray();   } finally   {   try   {   o.close();   } catch (IOException e)   {   e.printStackTrace();   }   }   return output;   }   public static byte[] decompressBytes(byte input[])   {   byte output[] = new byte[0];   decompresser.reset();   decompresser.setInput(input);   ByteArrayOutputStream o = new ByteArrayOutputStream(input.length);   try   {   byte[] buf = new byte[cachesize];     int got;   while (!decompresser.finished())   {   got = decompresser.inflate(buf);   o.write(buf, 0, got);   }   output = o.toByteArray();   }catch(Exception e)   {   e.printStackTrace();   }finally   {   try   {   o.close();   } catch (IOException e)   {   e.printStackTrace();   }   }   return output;   }   }         客户端:  public class AMF3Test extends Sprite   {   private var loader:URLLoader;   public function AMF3Test()   {   loader=new URLLoader();   loader.load(new URLRequest("D://test5.txt"));   loader.addEventListener(Event.COMPLETE,onComplete);   loader.dataFormat=URLLoaderDataFormat.BINARY;   }     private function onComplete(evt:Event):void   {   var start:Number=getTimer();   var byte:ByteArray=loader.data as ByteArray;   byte.uncompress() //将数据进行解压缩   var obj:Object=byte.readObject();   var end:Number=getTimer();   trace("耗时:"+(end-start)+"毫秒")   trace(obj.name,obj.age,obj.arr.length)   }   }