ngx_rtmp_handler 是 Nginx RTMP 模塊中的核心處理部分,主要負責處理 RTMP 流會話中的數據接收、發送、ping 操作以及分塊大小的設置等。
1. 全局變量
-
ngx_rtmp_naccepted
: 記錄接受的 RTMP 連接數。 -
ngx_rtmp_bw_out
和ngx_rtmp_bw_in
: 分別表示輸出帶寬和輸入帶寬,用于監控 RTMP 會話的數據流量。
2. 主要處理函數
2.1 ngx_rtmp_cycle
函數
這個函數是 RTMP 會話的核心調度函數。它設置了 RTMP 會話的數據讀取和發送回調函數,并初始化了 Ping 事件(用于保持與客戶端的連接)。
-
ngx_rtmp_recv
: 用于處理 RTMP 數據接收事件。 -
ngx_rtmp_send
: 用于處理 RTMP 數據發送事件。 -
ngx_rtmp_ping
: 用于處理 RTMP 心跳請求。
該函數還會調用 ngx_rtmp_reset_ping
來重置 Ping 事件,確保 RTMP 會話的活躍性。
2.2 ngx_rtmp_alloc_in_buf
函數
用于為 RTMP 會話分配輸入緩沖區。通過調用 ngx_alloc_chain_link
和 ngx_calloc_buf
函數,分配內存來存儲接收到的數據。數據存儲在 ngx_chain_t
鏈表結構中,方便多次處理。
2.3 ngx_rtmp_reset_ping
函數
這個函數用于重置心跳機制。如果配置了 Ping 超時(cscf->ping
),會啟用心跳定時器,定期向客戶端發送 Ping 請求,以保持連接的活躍狀態。
2.4 ngx_rtmp_ping
函數
處理心跳事件。如果在指定時間內沒有收到 Ping 響應,則會認為客戶端超時,調用 ngx_rtmp_finalize_session
來關閉該會話。
-
如果 Ping 請求超時或連接繁忙,會記錄錯誤日志并終止會話。
-
如果 Ping 請求成功發送,會設置下一次 Ping 事件的定時器。
2.5 ngx_rtmp_recv
函數
這是處理 RTMP 數據接收的主要函數。它執行以下任務:
-
從客戶端接收數據并將數據存儲在輸入緩沖區中。
-
處理分塊數據:如果數據分塊未完成,會繼續接收數據并重組。
-
解析 RTMP 包頭信息(如時間戳、數據長度等)。
-
處理不同類型的 RTMP 消息,并根據數據流的標識符 (
csid
) 將數據分配到正確的流中。 -
如果接收到的消息類型有效,會調用
ngx_rtmp_receive_message
來進一步處理消息。
2.6 ngx_rtmp_send
函數
用于發送 RTMP 數據。該函數會檢查是否有待發送的數據,按照優先級將數據發送到客戶端。如果發送的數據需要等待,則會設置一個定時器,并嘗試在下一個時刻繼續發送。
-
使用
ngx_rtmp_send
進行數據發送,確保 RTMP 數據包能夠及時地推送到客戶端。 -
如果網絡狀況不好,可能會出現超時、寫事件阻塞等情況,此時會處理相應的錯誤或重試。
2.7 ngx_rtmp_prepare_message
函數
此函數負責為 RTMP 消息準備消息頭,計算消息的時間戳、大小、類型等信息。它為每個 RTMP 消息生成一個特定格式的頭部。
-
根據消息的格式(
fmt
)選擇不同的頭部結構。 -
支持 RTMP 消息的擴展時間戳(
ext_timestamp
),這是為了解決大時間戳的問題(RTMP 協議標準只支持 24 位時間戳,而實際中可能會有更大的時間戳)。 -
通過
ngx_rtmp_message_type
函數,生成消息類型的描述(如音頻、視頻、命令消息等)。
3. RTMP 分塊與流控制
RTMP 協議支持將數據分為多個分塊進行傳輸。在 Nginx RTMP 模塊中,分塊的處理和流控制非常重要,特別是在處理大的數據流(如視頻流)時,分塊可以提高數據傳輸的效率。
-
分塊大小設置 (
ngx_rtmp_set_chunk_size
):-
設置每個 RTMP 分塊的大小。如果接收到的塊大小超過了指定的最大值,返回錯誤并終止會話。
-
會為每個連接創建一個新的內存池,并調整 RTMP 會話的輸入緩沖區大小。
-
-
流控制:
-
使用
ngx_rtmp_send_message
來處理消息隊列。如果消息隊列已滿,可能會丟棄某些數據包,確保隊列不會超載。 -
支持根據不同的優先級進行數據包的推送,以確保高優先級數據的及時傳輸。
-
4. 總結
這段代碼主要實現了 RTMP 會話的生命周期管理,特別是數據的接收、發送、流控制和心跳機制。每個 RTMP 會話都通過一系列的回調函數和事件處理機制,確保數據能夠正確流動并處理超時等異常情況。
-
RTMP 分塊與流控制:理解 RTMP 協議如何通過分塊(chunking)來處理大流數據,模塊如何管理每個流的輸入和輸出緩沖區。
-
心跳機制:RTMP 會話如何通過心跳(ping/pong)機制保持與客戶端的連接活躍。
-
消息頭和流類型:如何解析和生成 RTMP 消息頭,并通過流標識符(
csid
)將消息發送到正確的流。 -
錯誤處理和會話終止:如何處理超時、網絡錯誤和流量限制等問題。
這個模塊是 RTMP 協議實現的核心,涉及的數據流控制、錯誤管理和性能優化都非常關鍵,理解這些內容有助于深入掌握 Nginx RTMP 模塊的工作原理。