- 握手:
- 由三个固定字节长度的chunk组成
- 客户端和服务端发送三个一样的chunk。
- 客户端发送的命名为C0、C1、C2
- 服务端发送的命名为S0、S1、S2
- 握手时序:
- 首先由客户端发送C0和C1 chunks,客户端只有接收到S1之后才能发送C2,只有接收到S2的时候才能发送其它数据
- 服务端必须接收到C0才可以发送S0和S1,当然,等C0、C1都收到再发也可以、服务端收到C1之后才可以发送S2;必须收到C2后才可以发送数据。
- C0、S0的格式
- 是一个由8个字节组成的版本号,其中0-2已经废弃、3是rtmp规范指定的版本、4-31保留,32之后是不允许的
- C0表示客户端期望的rtmp版本,S0表示服务端接受的rtmp版本
- C1、S1的格式
- 是由1536个字节构成、其中
- 4个字节的时间戳
- 4个字节的0
- 1528个字节的随机值
- C2、S2的格式
- 也是由1536个字节构成,基本是C1、S1的echo,其中
- 4个字节的时间戳 timestamp(对端发送过来的S1或者C1携带的时间戳)
- 4个字节的时间戳 timestamp2(收到对端发出的S1或者C1时的时间)
- 1528个字节的对端发送过来的C1、S1中携带的随机值,echo回去
- timestamp和timestamp2可以用来计算带宽和延迟
- 时序图
- Chunk
- chunk允许更高级别协议的大消息分解成小消息,为了防止低级别的大消息阻塞高级别的小消息
- chunk还可以用较小的开销去发送小消息,因为chunk的header包含一个信息压缩字段//TODO
- chunk的size是可以配置的,可以通过一个控制信令(设置chunk size)来设置。最大的chunk size是65536 bytes,最小是128bytes。大的值会减少cpu消耗,但是也将会产生一个大write,在带宽不足的情况下会增加内容的延迟。小的chunk是不利于大码率流的。chunk size是双向独立的
- chunk的格式
- 每一个chunk都是由header和data构成的
- header被分为三个部分
- basic header
- 大小:1到3 字节
- 这部分encode了chunk stream id 和 chunk 类型。chunk type确定这个message header的格式。这个长度完全依赖于chunk stream id,是一个可变的长度
- chunk msg header
- 大小:0、3、7、11字节
- 这部分描述本发送的message是否是完整的。这个长度是通过chunk header的chunk type指定的
- extended time stamp
- 大小:0或者4 字节
- 当正常时间戳被设置为0xffffff时,这部分必须设置,否则一定不能设置,而应该使用正常时间戳部分。
- basic header
- chunk basic header 格式
- chunk basic header是有chunk type(由图中的fmt表示)和chunk stream id组成,其中chunk type决定了message header的格式
- rtmp协议支持高达65597路流(id:3~65599),id:0、1、2是保留的。0表示stream id 为 header的第二个字节+64;1表示stream id为header的第三个字节*256+第二个字节+64;2表示更低层次的协议消息。值3~63则表示完整的stream id。
- chunk message header
- chunk message header有四种不同的格式,通过basic header的fmt值来控制
- type 0
- 大小:11个字节
- chunk stream的第一个chunk、或者时间戳出现回退必须是这个格式
- 时间戳占3个字节,时间戳大于或者等于0x00ffffff时,这个值必须是0x00ffffff。扩展时间戳’extended timestamp header’必须使用。否则这个时间戳就是完整的时间戳。
- type 1
- 大小:7个字节;
- 不包含message stream id,因为这个chunk和上一个chunk拥有一样的stream id;
- 对于可变消息流(比如:视频格式),在第一个消息之后的每一个新消息的第一个chunk使用这种格式;
- type 2
- 大小:3个字节
- 既不包含流id也不包含message length。和上一个chunk拥有- 同样的stream id和message length
- 在第一个消息之后的每一个消息的第一个chunk使用
- type 3
- 大小:0个字节
- 这个chunk将从上一个chunk获取stream id、message header这些值
- chunk data
- 真正的用户数据,大小在(0,chunkDataSize]之间,chunkDataSize的默认值是128个字节,可以通过set chunk size控制消息来协商修改。
- protocol control message(协议控制消息)
- 协议控制消息的消息流id为0,chunk流id为2。拥有更高的发送优先级
- play 命令 msg 流
- publish 命令 msg 流
- 参考文章
https://www.jianshu.com/p/00aceabce944
https://www.cnblogs.com/lidabo/p/7232594.html