Nginx RTMP 发送模块分析 (ngx_rtmp_send.c)

ngx_rtmp_send.c 是 Nginx RTMP 模块中的发送部分,主要用于构建和发送 RTMP 消息。它处理各种 RTMP 控制消息和用户消息的创建与发送,涵盖了 RTMP 协议中的多种消息类型,如 chunk sizeabortackpingplay status 等。

1. 宏定义与数据结构

1.1 NGX_RTMP_USER_START

这个宏用于初始化一个 RTMP 消息的头部,设置消息类型和流标识符:

  • s:RTMP 会话(ngx_rtmp_session_t)。

  • tp:消息类型(例如 NGX_RTMP_MSG_CHUNK_SIZE)。

  • __cscf:RTMP 服务端配置,获取用于消息发送的配置。

宏首先创建一个 ngx_rtmp_header_t 类型的变量,初始化消息头部,然后分配一个共享的缓冲区用于存储消息。

1.2 NGX_RTMP_USER_OUT1NGX_RTMP_USER_OUT4

这两个宏用于将数据(如整数或字节)输出到消息缓冲区:

  • NGX_RTMP_USER_OUT1(v):将 1 字节的数据 v 写入缓冲区。

  • NGX_RTMP_USER_OUT4(v):将 4 字节的数据 v 写入缓冲区,以字节序反转的方式存储(大端存储)。

1.3 NGX_RTMP_USER_END

该宏用于完成消息的准备工作,并将消息传递给 ngx_rtmp_prepare_message 进行最终处理。然后返回共享缓冲区。

2. 协议控制消息

RTMP 协议定义了多种控制消息,以下是几种常见的控制消息及其处理:

2.1 ngx_rtmp_create_chunk_sizengx_rtmp_send_chunk_size

这两个函数用于创建和发送 chunk size 控制消息。RTMP 协议使用分块传输数据,chunk size 消息用于设置每个 RTMP 消息的最大大小。

  • ngx_rtmp_create_chunk_size:构建一个 chunk size 消息,将 chunk_size 写入缓冲区。

  • ngx_rtmp_send_chunk_size:调用 ngx_rtmp_send_shared_packet 发送构建好的消息。

2.2 ngx_rtmp_create_abortngx_rtmp_send_abort

这两个函数用于创建和发送 abort 消息。abort 消息用于告知接收方某个数据流的传输已中止。

  • ngx_rtmp_create_abort:构建 abort 消息并写入流标识符(csid)。

  • ngx_rtmp_send_abort:发送 abort 消息。

2.3 ngx_rtmp_create_ackngx_rtmp_send_ack

这两个函数用于创建和发送 ack 消息。ack 消息用于确认接收到的消息序列号。

  • ngx_rtmp_create_ack:构建一个 ack 消息,将确认的序列号写入缓冲区。

  • ngx_rtmp_send_ack:发送 ack 消息。

2.4 ngx_rtmp_create_bandwidthngx_rtmp_send_bandwidth

这两个函数用于创建和发送带宽控制消息。带宽消息用于控制 RTMP 流的带宽限制,常见的类型包括 limit_type

  • ngx_rtmp_create_bandwidth:构建带宽控制消息,包含带宽大小和限制类型。

  • ngx_rtmp_send_bandwidth:发送带宽控制消息。

3. 用户控制消息

RTMP 也定义了多个用户控制消息,用于管理流的状态(如流开始、流结束等)。以下是几个常见的用户控制消息的处理:

3.1 ngx_rtmp_create_stream_beginngx_rtmp_send_stream_begin

这两个函数用于创建和发送 stream begin 消息,表示某个流的开始。

  • ngx_rtmp_create_stream_begin:构建一个 stream begin 消息,将流标识符(msid)写入缓冲区。

  • ngx_rtmp_send_stream_begin:发送 stream begin 消息。

3.2 ngx_rtmp_create_stream_eofngx_rtmp_send_stream_eof

这两个函数用于创建和发送 stream eof 消息,表示流的结束。

  • ngx_rtmp_create_stream_eof:构建一个 stream eof 消息。

  • ngx_rtmp_send_stream_eof:发送 stream eof 消息。

3.3 ngx_rtmp_create_stream_dryngx_rtmp_send_stream_dry

这两个函数用于创建和发送 stream dry 消息,表示流暂时没有数据可供播放。

  • ngx_rtmp_create_stream_dry:构建一个 stream dry 消息。

  • ngx_rtmp_send_stream_dry:发送 stream dry 消息。

3.4 ngx_rtmp_create_set_buflenngx_rtmp_send_set_buflen

这两个函数用于创建和发送 set buffer length 消息,用于设置缓冲区的大小。

  • ngx_rtmp_create_set_buflen:构建一个 set buffer length 消息,将流标识符和缓冲区长度(毫秒)写入消息。

  • ngx_rtmp_send_set_buflen:发送 set buffer length 消息。

3.5 ngx_rtmp_create_recordedngx_rtmp_send_recorded

这两个函数用于创建和发送 recorded 消息,表示流的录制已完成。

  • ngx_rtmp_create_recorded:构建一个 recorded 消息。

  • ngx_rtmp_send_recorded:发送 recorded 消息。

3.6 ngx_rtmp_create_ping_requestngx_rtmp_send_ping_request

这两个函数用于创建和发送 ping request 消息,RTMP 协议使用 Ping 消息来保持连接活跃。

  • ngx_rtmp_create_ping_request:构建一个 ping request 消息。

  • ngx_rtmp_send_ping_request:发送 ping request 消息。

3.7 ngx_rtmp_create_ping_responsengx_rtmp_send_ping_response

这两个函数用于创建和发送 ping response 消息,表示对 ping request 消息的响应。

  • ngx_rtmp_create_ping_response:构建一个 ping response 消息。

  • ngx_rtmp_send_ping_response:发送 ping response 消息。

4. AMF 消息

4.1 ngx_rtmp_append_amfngx_rtmp_create_amf

这两个函数用于创建 AMF 消息并将其附加到发送数据中。AMF 消息用于 RTMP 命令和数据传输。通过 ngx_rtmp_amf_write 将 AMF 数据写入到缓冲区。

4.2 ngx_rtmp_send_amf

用于发送 AMF 消息,调用 ngx_rtmp_create_amf 创建消息并通过 ngx_rtmp_send_shared_packet 发送。

5. 总结

这段代码实现了 Nginx RTMP 模块中的发送功能,负责创建并发送多种 RTMP 协议的控制消息和用户消息。它通过宏和函数将消息数据格式化并写入缓冲区,然后发送给客户端。模块支持多种 RTMP 消息类型,包括协议控制消息、用户控制消息、AMF 消息等。可以从以下几个方面来理解这段代码:

  1. RTMP 消息类型:代码处理了多种 RTMP 消息类型,如 chunk sizeabortack 等,了解这些消息类型及其在 RTMP 协议中的作用。

  2. 消息构建与发送:通过宏和函数构建 RTMP 消息头,填充消息体,并最终发送出去。

  3. AMF 消息处理:AMF 消息是 RTMP 中常用的消息格式,主要用于传输命令和数据,理解 AMF 消息的创建和发送是掌握 RTMP 协议的关键。

这段代码是 Nginx RTMP 模块的核心之一,负责处理客户端请求、控制流量并进行 RTMP 消息的传输。