当前位置: 首页 > 工具软件 > AMF > 使用案例 >

AMF(Action Message Format)简介

淳于慎之
2023-12-01

1、AMF简介

(1)简介

       AMF(Action Message Format),即操作消息格式,基于http方式传输,是一种二进制的数据格式。主要用于数据交互和远程过程调用。它的设计是为了把actionscript里面的数据(包括Object, Array, Boolean, Number等)序列化成二进制数据,然后把这段数据随意发送给其他接收方程序,比如发给远程的服务器,在远程服务器那边,可以把这段数据给还原出来,以此达到一个数据传输的作用。

(2)AMF0和AMF3的历史

       AMF引进于2001年的FlashPlayer6,并且在引入AS2.0的FlashPlayer7和FlashPlayer8中没有改变的保留了。这个版本的AMF参考于AMF0(查阅[AMF0])。在FlashPla yer9中,AS3.0同新的AS虚拟机(AVM+)一起被引进—新的数据类型和语言特性的改进致使AMF升级成为可能,给了一个发布新的AMF版本的机会,新版本的AMF在序列化数据的时候做了一些优化,使得编码格式去除了一些冗余信息。升级后的AMF版本便是AMF3。

       第一个版本的AMF,即AMF0,支持在避免了在对象图中发送冗余的实例的通过引用发送复杂的对象。他也允许端点存储对象关系,并且支持避免一些问题,在序列化时无穷的递归的情况下的循环引用。新版本的AMF,即AMF3,与AS3.0(ActionScript 动作脚本)版本保持一致,在通过引用发送除对象实例外的对象特性和字符串做了改进。AMF3也支持在AS3.0中的一些新的数据类型。

       那么AMF3出来之后AMF0是不是可以退休了?答案也是否定的。大家现在接触到的AMF3消息流基本上都是在AMF3外面包了一层AMF0, 也就是说我们看到的所有AMF数据流都是AMF0的,当数据流中的某个数据的type=0×11时,才表示这个数据应该属于AMF3的数据,在这个时候就会切换到AMF3的模式来处理这个数据。处理完之后当然还是继续回到AMF0的模式处理数据。

2、为什么要用AMF

       通常情况下我们使用JSON或者XML来做数据的传输,他们的好处是文本数据易读、容易修改,坏处在于文本数据体积较大,而且数据的组织有其局限性。同样是轻量级数据交换协议,同样是通过调用远程服务,同样是基于标准的HTTP和HTTPS协议, Flash Remoting为什么选择了使用AMF而放弃了SOAP与Flash 播放器通信呢? 有如下原因:

  • SOAP将数据处理成XML格式,相对于二进制的AFM太冗长了。
  • AMF能更有效序列化数据。因为AMF的初衷只是为了支持Flash ActionScript的数据类型,而SOAP却致力于提供更广泛的用途。
  • AMF在对Flash Player 6 的浏览器支持上AMF只需要4KB左右(压缩后)的大小,而SOAP就大多了;SOAP的一些头部文件请求在Flash Player 6 不支持。
  • AMF最大的特色在于可直接将Flash内置对象,例如Object, Array, Date,XML,传回服务器端,并且在服务器端自动进行解析成适当的对象。

3、AMF格式

       AMF分成两种:AMF0,基本的数据转换规则;AMF3,是AMF0的扩展。

(1)AMF0

// AMF0数据类型;
typedef enum
{
    AMF_NUMBER = 0,         // 数字(double);
    AMF_BOOLEAN,            // 布尔;
    AMF_STRING,             // 字符串;
    AMF_OBJECT,             // 对象;
    AMF_MOVIECLIP,          // 保留,未使用;
    AMF_NULL,               // null;
    AMF_UNDEFINED,          // 未定义;
    AMF_REFERENCE,          // 引用;
    AMF_ECMA_ARRAY,         // 数组;
    AMF_OBJECT_END,         // 对象结束;
    AMF_STRICT_ARRAY,       // 严格的数组;
    AMF_DATE,               // 日期;
    AMF_LONG_STRING,        // 长字符串;
    AMF_UNSUPPORTED,        // 未支持;
    AMF_RECORDSET,          // 保留,未使用;
    AMF_XML_DOC,            // xml文档;
    AMF_TYPED_OBJECT,       // 有类型的对象;
    AMF_AVMPLUS,            // 需要扩展到AMF3;
    AMF_INVALID = 0xff      // 无效的;
}AMFDataType;

(2)AMF3

// AMF3数据类型;
typedef enum
{
    AMF3_UNDEFINED = 0,     // 未定义;
    AMF3_NULL,              // null;
    AMF3_FALSE,             // false;
    AMF3_TRUE,              // true;
    AMF3_INTEGER,           // 数字int;
    AMF3_DOUBLE,            // double;
    AMF3_STRING,            // 字符串;
    AMF3_XML_DOC,           // xml文档;
    AMF3_DATE,              // 日期;
    AMF3_ARRAY,             // 数组;
    AMF3_OBJECT,            // 对象;
    AMF3_XML,               // xml;
    AMF3_BYTE_ARRAY         // 字节数组;
} AMF3DataType;

(3)AMF自定义的字符串

// AMF自定义的字符串;
typedef struct AVal
{
    char *av_val;
    int av_len;
} AVal;

(4)AMF对象

// AMF对象, 就是由一系列的属性构成的;
typedef struct AMFObject
{
    int o_num;                          // 属性数目;
    struct AMFObjectProperty *o_props;  // 属性数组;
} AMFObject;

AMFObject表示AMF对象,o_num 代表 o_props的个数, 一个对象内部可以包含N个对象属性;

(5)AMF对象的属性

// AMF对象的属性;
typedef struct AMFObjectProperty
{
    AVal p_name;            // 属性名称;
    AMFDataType p_type;     // 属性类型;
    union
    {
        double p_number;
        AVal p_aval;
        AMFObject p_object;
    } p_vu;                 // 属性数值;
    int16_t p_UTCoffset;    // UTC偏移;
} AMFObjectProperty;

AMFObjectProperty表示AMF对象属性,即key-value键值对。p_name表示key;p_type表示value的类型;p_vu表示value的数值。p_vu设置为联合体的目的:

  • 当p_type为number时, m_vu取值double类型 p_number;
  • 当p_type为string时,    m_vu取值AVal类型 p_aval;
  • 当p_type为object时,   m_vu取值AMFObject类型 p_object。

(6)AMF的初始化和字符串比较

// AVal的快速初始化;
#define AVC(str)        {str, sizeof(str)-1}
// 比较AVal字符串;
#define AVMATCH(a1,a2)  ((a1)->av_len == (a2)->av_len && !memcmp((a1)->av_val,(a2)->av_val,(a1)->av_len))

4、AMF的内容处理流程

       AMF协议是基于Http协议的,它的内容处理过程大致是这样:

  • 从客户端获取Http请求(Request)流;
  • 对流进行解串行化(Deserialize),得到服务器端程序能够识别的数据,并建立一个响应(Response)消息;
  • Debug开始;
  • 对流进行各种处理(记录、许可、服务)得到返回值;
  • 对响应流进行串行化;
  • 发送Http响应给客户端;

 

 类似资料: