Red5与flex客户端通信的RTMP数据解析


一.Flex向Red5服务端发送消息

这里有一个程序是群聊,那么现在其中有一个人像其他人发送以短消息,如“vvvvv”,我们来解析这个过程。

客户端的方法代码

protected functionsendMessage(event:MouseEvent):void

  {

   // TODO Auto-generated method stub

   var sendString:String = txt_yousay.text;

   //varsendTo:String=users.selectedItem.userName==null?"":users.selectedItem.userId;

   var sendTo:String=userList.selectedItem.label;   

   txt_yousay.text = "";

   conn.call("sayToAll", null,sendTo,sendString);

  }

当我们输入完消息,点击发送的时候,就会调用这个方法,其中sendTo使我们要发送的对象,这个程序里的值应该是“All”,sendString的值就是我们输入的消息,这里应该是“vvvvvv”,这些无关紧要,我们只需要知道它的值就行了。

客户端调用conn.call("sayToAll",null,sendTo,sendString);给服务端发送一个消息,表示我们需要调用服务端的一个函数,函数名叫做"sayToAll",还有剩下三个参数,第一个参数是用来保存从服务端返回的数据,这里不需要服务端返回数据,所以设为null,第二第三个参数使我们要给服务端的消息,服务端获取这些数据后,进行处理。

我用wireshark工具截获了rtmp包,下图就是我们发送服务端的RTMP报的内容,我们来分析一下。


上图蓝色区域就是RTMP报的内容,它包括一个包头和包身。

RTMP Header,从43到11这8个字节是包头,来列一张表

RTMP Header

数据

解释

43

01.. .... = Format: 1

..00 0011 = Chunk Stream ID: 3

00 16 9e

Timestamp delta: 5790

00 00 24

Body size: 36

11

Type ID: AMF3 Command (0x11)

 

 

Rtmp包头网上有很多解释,这里不详细说了,说明一下,

43的前两位为01说明包头是8字节的,最后一个字节11说明这个包的类型是FLEX_MESSAGE

下面来看一下包体。列张表:

RTMP Body

数据

解释

02

00 08

73 61 79 54 6f 41 6c 6c

String 'sayToAll'

02  AMF type: String (2)

00 08  String length: 8

73 61 79 54 6f 41 6c 6c  String: sayToAll

00

00 00 00 00 00 00 00 00

AMF type: Number (0)

Number: 0

05

AMF type: Null (5)

02

00 03

41 6c 6c

String 'All'

02  AMF type: String (2)

00 03  String length: 3

41 6c 6c  String: All

02

00 05

76 76 76 76 76

String 'vvvvv'

02  AMF type: String (2)

00 05  String length: 5

76 76 76 76 76  String: vvvvv

这里我们来分析一下,RTMP头就不说了,我们来看RTMP包的包体,这需要和我们发送的消息关联。conn.call("sayToAll",null,sendTo,sendString);

那么包体的第一部分数据是一个字符串“sayToAll”,说明要调用的服务端的方法,对应方法里的第一个参数;

第二部分数据是一个number型,CallID (double)

第三部分数据为null,说明我们的responder为null,对应方法里的第二个参数

第四部分数据是一个字符串“All”,对应方法里的第三个参数

第五部分数据是一个字符串,对应方法里的第四个参数

。。这里说明一下,如果数据是字符串,那么第一个字节是02表示AMF类型是字符串,后面紧跟的两个字节表示字符串的长度,然后后面是这个长度个字节的字符串类容。

如果数据时number类型的,固定第一个字解释00,表示AMF类型是number,后面跟8字节的值。

 

 

二.Red5向Flex客户端发送invoke

服务端要做的事情呢就是向其他所有聊天室的人转发第一个客户发送的消息,服务端需要考苏其他所有客户端调用一个方法,这个方法在自己客户端的页面上显示这条消息。服务端当然还需要传给客户端参数,是谁发的消息,消息内容是什么。

现在服务端循环遍历所有客户端,并且调用下列方法:

sc.invoke("showMessage", newObject[]{clientName+" to All:"+sayWhat});

这个方法里面,"showMessage"是客户端需要调用的方法,new Object[]{clientName+" toAll:"+sayWhat}是服务端传给客户端的参数,在我的实验里,这个参数的值其实就是“ddddto All:vvvvv”。

下面是我们截取的RTMP包,我们来分析一下包。

 

这个包和我们上面看的包类似的

RTMP Header

数据

解释

43

01.. .... = Format: 1

..00 0011 = Chunk Stream ID: 3

00 00 00

Timestamp delta: 0

00 00 2c

Body size: 44

14

Type ID: AMF3 Command (0x14)

 

 

这里要注意的是最后一个字节 14,根据AMFType,我们调用的是invoke。

0×14   Invoke like remoting call, used for stream actions too.

看下包体

RTMP Body

数据

解释

02

00 0b

73 68 6f 77 4d 65 73 73 61 67 65

String ' showMessage '

02  AMF type: String (2)

00 08  String length: 11

73 68 6f 77 4d 65 73 73 61 67 65  String: showMessage

00

40 10 00 00 00 00 00 00

AMF type: Number (0)

Number: 4

05

AMF type: Null (5)

11

AMF type: Switch to AMF3 (17)

06 23

64 64 64 64 20 74 6f 2041 6c 6c 3a 76 76 76 76 76

06 23

不是很清楚,剩下的字节是

String 'dddd to All:vvvvv'

联系我们的服务端调用的方法,数据的第一部分数据String' showMessage '

就是我们的方法的第一个参数,后面Number:4 为CallID,然后Null似乎是个固定的,没有深究,最后的字符串就是方法里的第二个参数。

 

到这里flex,red5的通信就分析完了,附上一些有用的url

http://wiki.gnashdev.org/RTMP_Messages_Decoded

http://blog.csdn.net/cssmhyl/article/details/8052794

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值