首先我們先分析下基本流程。
1、初始化流程
initnetworking---初始化網路
initialize
logger::init()---初始化日誌
lowercase(extension) == "lua"---載入.lua字尾配置檔案
loadluafile
normalize
初始化日誌配置
初始化監聽配置
iohandlermanager::initialize()
初始化io,讀寫佇列清零
grs.pconfigfile->configmodules()
protocolfactorymanager::registerprotocolfactory(grs.pprotocolfactory) 載入預設支援的協議集合
grs.pconfigfile->configacceptors()
根據ip和埠開啟***
grs.pconfigfile->configinstances()
配置多例項,win下不支援
將***與例項繫結
installquitsignal
設定程式退出機制
runiohandlermanager::pulse()
對socket資源進行輪詢,查詢是否有需要進行讀寫的socket操作
2、接收客戶端的連線請求之connect
pulse()
fd_isset(map_val(i)->getinboundfd(), &_readfdscopy)
map_val(i)->onevent(_currentevent)
tcpacceptor::accept()
進入accept進行連線的建立
baseprotocol *pprotocol = protocolfactorymanager::createprotocolchain
為連線建立對應配置的協議,比如tcp && rtmp,或者udp && rtcp==
tcpcarrier *ptcpcarrier = new tcpcarrier(fd)
為連線建立乙個tcp互動物件,並將其和剛建立的協議物件繫結,建立時建構函式中就註冊了讀請求
fd_isset(map_val(i)->getinboundfd(), &_readfdscopy)
map_val(i)->onevent(_currentevent)
tcpcarrier::onevent(select_event &event)
進入讀分支讀取資料,根據對應的協議分析讀取的資料依據結果填充_outputbuffer傳送緩衝區,並設定傳送訊號tcpcarrier::signaloutputdata()--->enable_write_data,通知pulse輪詢socket狀態需要傳送資料,然後再次進入tcpcarrier::onevent(select_event &event)寫分支進行真正的資料傳送操作
rtmp訊息型別為:rm_invoke_function_connect
3、接收客戶端的發布流之publish
這一段屬於rtmp協議互動的部分
rm_invoke_function_releasestream
這裡沒有獲得stream名稱,傳送名稱請求
rm_invoke_function_fcpublish
這裡獲得stream名稱
rm_invoke_function_createstream
processinvokecreatestream
pfrom->createneutralstream(id) == null
rtmpstream *pstream = new rtmpstream
這裡建立乙個rtmpstream流控制物件 rtmpstream ---> basestream
rm_invoke_function_publish
processinvokepublish
innetrtmpstream *pinnetrtmpstream = pfrom->createins(vh_ci(request) 建立network inbound stream
pinnetrtmpstream->sendonstatusstreampublished()
傳送準備接收流請求
4、接收客戶端請求實時流
這一段屬於rtmp協議互動的部分
rm_invoke_function_play
processinvokeplay
pfrom->closestream(vh_si(request), true)
關閉該連線之前請求的流
trylinktolivestream(pfrom, vh_si(request), streamname, linked)
將該連線繫結
for_map(inboundstreams, uint32_t, basestream *, i)
通過streamname查詢找到流輸入
baseoutnetrtmpstream * pbaseoutnetrtmpstream = pfrom->createons(streamid, 先建立流輸出
pbaseinnetstream->link(pbaseoutnetrtmpstream)
然後將流輸出繫結至流輸入
上面我們做了流程的分析,這一篇我們對其中涉及到的類做乙個梳理,兩篇可以結合著一起看,對整個程式的執行是有幫助的。
streamsmanager _streamsmanager;
baseprotocol
協議基類,一切協議都基於這個類,例如basehttpprotocol和basertmpprotocol
baseprotocol *_pfarprotocol;
遠端協議
baseprotocol *_pnearprotocol;
//表示到伺服器的遠近[outside world --->ssl--->http--->rtmp--->server]
//離伺服器最近的是rtmp協議,最遠的為ssl
basertmpprotocol rtmp協議運算基類
iobuffer _outputbuffer;
協議的互動buffer
所屬的協議事務類
basestream *_streams[max_streams_count]; 這邊是乙個連線物件允許請求256次流?
linkedlistnode*_psignaledrtmpoutnetstream;
輸出流集合
map_connections;
協議基礎類的支援?
streamsmanager
流鏈結管理
basestream
流處理基類
baseprotocol *_pprotocol;
所屬協議
streamsmanager *_pstreamsmanager;
反向查詢流管理
baseinstream --->basestream
流輸入類
map_linkedstreams;
對應的流輸出集合
baseoutstream --->basestream
流輸出類
baseinstream *_pinstream;
流的輸入物件
innetrtmpstream --->baseinnetstream --->baseinstream
rtmp 流發布時建立的,用於管理流輸入,在這個類中做流分發處理
iobuffer _videocodecinit;
iobuffer _audiocodecinit;
對應的音訊流緩衝
iohandler
處理io互動,網路相關,tcpacceptor,tcpcarrier,tcpconnector...
baseprotocol *_pprotocol;
所屬的互動協議,rtmp/http/rtsp...
iohandlertype _type;
標識本io的處理型別,參見iohandlertype,accept/connect/tcp/udp
tcpacceptor
tcp***
iohandlermanager
io互動管理,程式入口為這個類
static map_activeiohandlers;
有效io
static map_deadiohandlers;
無效io
protocolmanager
protocol協議互動管理
protocolfactorymanager
協議工廠,包含本程式所支援的協議,貌似跟配置檔案無關,有25種協議
CRtmpServer分析與應用
crtmpserver是一款不錯的開源流 伺服器,用c 語言編寫,跨平台。官方介紹crtmpserver不僅支援adobe rtmp協議,還支援其它常用的協議 crtmpserver從生產環境使用的情況來看,每天都在用,從幾十m到上百m的流量不等,執行幾個月無宕機,cpu,記憶體各方面效能指標穩定,...
crtmpserver筆記之文件結構
1.頂層 crtmpserver 下的資料夾結構 3rdparty 對lua,xml進行解析的源 資料夾 sources 專案的核心實現源 資料夾 builders 各種環境 vs2010,android,linux 下的專案生成 configs 一些預定義的配置檔案和示例啟動指令碼 docs 專案...
利用crtmpserver搭建rtmp伺服器
google 實踐 最終直播成功。記錄一下。架構為 ffmpeg crtmpserver flash 進一步拆分 flv muxer librtmp crtmpserver flash 進入正題 編譯crtmpserver 過程曲折。請參考 1.源 根資料夾的readme。2.google。3.我遇...