音视频

RTMP握手协议

2017-08-15  本文已影响296人  Alfie20

作者原创,转载请联系作者

RTMP简介

Real Time Messaging Protocol(实时消息传送协议协议)是Adobe Systems公司为Flash Player和服务器之间音频,视频和数据传输开发的私有协议,adobe目前提供了一个并不完整的rtmp specification给大众使用,所以在使用rtmp协议时需要按flash player返回的包进行解析.
目前rtmp有以下几个变种:

包结构

rtmp消息包使用的是二进制数据流,它们使用AMF0/AMF3进行编码.与其它协议一样,rtmp消息也是也包括消息头与消息体,而消息头又可以分为basic header,chunk header,timestamp.

握手协议

在rtmp连接建立后,服务端与客户端需要通过3次交换报文完成握手.
握手其他的协议不同,是由三个静态大小的块,而不是可变大小的块组成的,客户端与服务器发送相同的三个chunk,客户端发送c0,c1,c2 chunk,服务端发送s0,s1,s2 chunk.
-发送顺序
握手开始时,客户端将发送c0,c1 chunk,此时客户端必须等待,直到收到s1 chunk,才能发送c2 chunk.
此时服务端必须等待,直到已收到c0后才能发送s0和s1,当然也可能会等到接收c1后才发送.
当服务器收到c2后才能再发送的其他数据,同理,当客户端收到s2后才能发送其它数据.

  1. c0与s0格式


    c0和s0包是一个1字节,可以看作是一个byte
    目前rtmp版本定义为3,0-2是早期的专利产品所使用的值,现已经废弃,4-31是预留值,32-255是禁用值(这样做是为了区分基于文本的协议,因为这些协议通常都是以一个可打印的字符开始),如果服务端不能识别客户请求的版本,那么它应该发送3的响应,客户端这时可以选择下降到版本3,也可以放弃这次握手.

  2. c1与s1格式


    c1与s1长度为1536个字节,它们由以下字段组成
    时间戳:该字段占4字节,包含了一个时间戳,它是所有从这个端点发送出去的将来数据块的起始点,它可以是零,或是任意值,为了同步多个数据块流,端点可能会将这个字段设成其它数据块流时间戳的当前值.
    0:此标记位占4字节,并且必须是0
    随机数:该字段占1528字节,可以是任意值,因为每个端点必须区分已经初始化的握手和对等端点初始化的握手的响应,所以这个数据要足够的随机,当然这个也不需要密码级的随机或是动态值.

  3. c2与s2格式


    c2和s2包长都是1536字节,几乎是s1和c1的回显.
    time1:该字段占4字节,包含有对方发送过来s1或c1的时间戳
    time2:该字段占4字节,包含有对方发送过来的前一个包(s1或者c1)的时间戳
    随机数回显:该字段占1528字节,包含有对方发送过来的随机数据字段,每个通信端点可以使用time和time2字段,以及当前的时间戳,来快速估计带宽和/或连接延时,但这个数值基本上没法用.

  1. 版本发送完成:客户端和服务端在未初始化状态之后都进入到版本发送完成状态,客户端等待包s1,而服务端等待包c1,在收到相应的包后,客户端发送包c2,而服务端发磅包s2,状态变成询问发送完成.
  2. 询问发送完成:客户端和服务端等待s2和c2.
  3. 握手完成:客户端和服务端开始交换消息.

代码示例

其中处理NGX_RTMP_HANDSHAKE_DONE的回调如前文所ngx_rtmp_relay_module模块中注册的回调:ngx_rtmp_relay_handshake_done。其主要做三部分工作:
1)将自己的chunk发送给对方:ngx_rtmp_send_chunk_size
2)将ack_size发送给对方:ngx_rtmp_send_ack_size
3)将amf发送给对方:ngx_rtmp_send_amf,主要是:

{ NGX_RTMP_AMF_STRING, ngx_null_string, "connect", 0 },

上一篇下一篇

猜你喜欢

热点阅读