AMF是Adobe独家开发出来的通信协议,它采用二进制压缩,序列化、反序列化、传输数据,从而为Flash 播放器与Flash Remoting网关通信提供了一种轻量级的、高效能的通信方式。如下图所示:
[img]http://dl.iteye.com/upload/attachment/177238/a4c46908-53b4-3cb8-8347-6176710cfa9c.gif[/img]
AMF(Action Message Format)是一种 binary format的资料型态,透过 AMF overHTTP的方式将flash端资料编码后传回server,server端的remotingadaptor接收到资料后则会译码回正确的native对象,交给正确的程序处理。
AMF最大的特色在于可直接将Flash内置对象,例如Object, Array, Date, XML,传回服务器端,并且在服务器端自动进行解析成适当的对象,这就减轻了开发人员繁复工作,同时也更省了开发时间。由于AMF采用二进制编码,这种方式可以高度压缩数据,因此非常适合用来传递大量的资料。数据量越大,Flash Remoting的传输效能就越高,远远超过Web Service。至于XML, LoadVars和loadVariables() ,它们使用纯文本的传输方式,效能就更不能与Flash Remoting相提并论了。
注意:Flash Remoting需要浏览器支持Binary POST,Flash 播放器在Netscape 6.x.环境下运行Flash Remoting会不起作用(Flash Remoting调用没有效果也不返回错误), Netscape 7已经纠正了这个bug 。对于早期Safari和Chimera版的苹果机也有这个问题。
下面是一个[color=red]flex amf socket连接例子[/color]:
java服务器代码:
Flex端的代码如下:
[img]http://dl.iteye.com/upload/attachment/177238/a4c46908-53b4-3cb8-8347-6176710cfa9c.gif[/img]
AMF(Action Message Format)是一种 binary format的资料型态,透过 AMF overHTTP的方式将flash端资料编码后传回server,server端的remotingadaptor接收到资料后则会译码回正确的native对象,交给正确的程序处理。
AMF最大的特色在于可直接将Flash内置对象,例如Object, Array, Date, XML,传回服务器端,并且在服务器端自动进行解析成适当的对象,这就减轻了开发人员繁复工作,同时也更省了开发时间。由于AMF采用二进制编码,这种方式可以高度压缩数据,因此非常适合用来传递大量的资料。数据量越大,Flash Remoting的传输效能就越高,远远超过Web Service。至于XML, LoadVars和loadVariables() ,它们使用纯文本的传输方式,效能就更不能与Flash Remoting相提并论了。
注意:Flash Remoting需要浏览器支持Binary POST,Flash 播放器在Netscape 6.x.环境下运行Flash Remoting会不起作用(Flash Remoting调用没有效果也不返回错误), Netscape 7已经纠正了这个bug 。对于早期Safari和Chimera版的苹果机也有这个问题。
下面是一个[color=red]flex amf socket连接例子[/color]:
java服务器代码:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package sockeserver;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import flex.messaging.io.*;
import flex.messaging.io.amf.*;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.DeflaterOutputStream;
/**
*
* @author mumuyu99
*/
public class socketServer implements Runnable {
public static void main(String[] args) {
start();
} //****************************************************************//
private static boolean isRunning = false; //服务器运行标志
ServerSocket ss = null; //socket连接
int userIndexNumber; //用户索引号
int userCount; //房间人数
//Iterator it=null; //迭代器
//*************************消息协议*********************************//
private byte type; //消息类型
private byte mainCmd; //消息主命令
private byte subCmd; //消息子命令
private byte[] data; //消息数据
private SerializationContext context = new SerializationContext();
public static void start() {
socketServer server = new socketServer();
// server.heardHeart();
new Thread(server).start();
System.out.println("服务器打开");
}
public void run() {
try {
isRunning = true;
try {
ss = new ServerSocket(9999);
} catch (IOException ex) {
System.out.println(ex.toString());
}
Socket socket;
while (isRunning) {
socket = ss.accept();
handleCmd(socket);
}
} catch (IOException ex) {
System.out.println(ex.toString());
}
}
private void handleCmd(Socket inComing) {
try {
DataInputStream dis = new DataInputStream(inComing.getInputStream());
DataOutputStream dos = new DataOutputStream(inComing.getOutputStream());
System.out.println("准备好接收数据!");
byte[] lang = new byte[dis.available()];
dis.read(lang);
System.out.println(new String(lang, "utf-8"));
Amf3Output out = new Amf3Output(context);
DeflaterOutputStream stream = new DeflaterOutputStream(dos);
out.setOutputStream(stream);
Map map = new HashMap();
String[] arr = "1,2,3,4,5".split(",");
map.put("datas", arr);
map.put("userName", "mumuyu99");
map.put("fullName", "最新消息");
out.writeObject(map);
stream.finish();
dos.writeUTF("你好啊");
dos.flush();
} catch (IOException ex) {
System.out.println(ex.toString());
}
}
}
Flex端的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
>
<fx:Script>
<!--[CDATA[
import flash.net.Socket;
import mx.controls.Alert;
private static var socket:Socket;
private var byteaa:ByteArray;
private function connectSocket():void{
socket=new Socket("localhost",9999)
//socket.objectEncoding=ObjectEncoding.AMF3;
var byteArray:ByteArray=new ByteArray();
var s:String="hello word!"
byteArray.writeUTFBytes(s);
socket.writeBytes(byteArray,0,byteArray.length);
socket.writeMultiByte(s,"UTF-8");
socket.flush();
byteaa=new ByteArray();
socket.addEventListener(ProgressEvent.SOCKET_DATA,loaderHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,errorIO);
socket.addEventListener(Event.CONNECT,connectStart);
}
private function connectStart(event:Event):void{
Alert.show("连接成功!");
}
private function errorIO(event:IOErrorEvent):void{
Alert.show("连接不到数据源!");
}
private function loaderHandler(event:ProgressEvent):void {
// var intervalId:uint = setTimeout(laoderInit,100);
laoderInit();
}
private function laoderInit():void{
var start:Number=getTimer();
while(socket.bytesAvailable>0){
socket.readBytes(byteaa);
}
byteaa.uncompress();
var obj:Object = byteaa.readObject();
Alert.show(obj.fullName);
var end:Number=getTimer();
Alert.show("耗时:" + (end - start) + "毫秒");
}
protected function button1_clickHandler(event:MouseEvent):void
{
connectSocket();
}
]]-->
</fx:Script>
<s:Button x="190" y="370" label="连接" enabled="true" click="button1_clickHandler(event)"/>
</s:Application>