OpenRTMFP/Cumulus Primer(21)經由伺服器的釋出/訂閱流程的關鍵點
OpenRTMFP/Cumulus Primer(21)經由伺服器的釋出/訂閱流程的關鍵點
- 作者:柳大·Poechant(鍾超 Michael)
- 部落格:Blog.csdn.net/poechant
- 郵箱:zhongchao.ustc@gmail.com
- 日期:July 23th, 2012
整個流程概括如下:
Flash 客戶端通過 NetConnection 與 Cumulus 建立連線,然後通過 NetStream 使用 RTMFP 釋出 Audio/Video/Data(下面簡稱為 A/V/D) 給伺服器,這個 Flash Player 就作為一個釋出者(Publisher)。RTMFP 伺服器接收到後給所有的訂閱者(Subscribers)傳送 Audio/Video/Data。
1 客戶端釋出(Publishing on client side)
通過 NetConnection 連線 RTMFP 伺服器 Cumulus,可以參考《OpenRTMFP/Cumulus Primer(2)用Lua編寫HelloWorld應用擴充套件CumulusServer》一文。關鍵的一個語句如下,其中 nc 是一個 NetConnection 物件(不是“腦殘”的意思 - -|||):
nc.connect("rtmfp://localhost:1935");
在連線成功後通過 NetStream 釋出 Audio/Video,如下所示,其中 ns1 是一個 NetStream 物件。
ns1.publish("poechant_media_flow", "live");
根據音視訊不同的需求,播放相應內容。如果是釋出 Data,則使用NetStream.send()
來實現。這樣就完成了客戶端的 A/V/D 釋出
2 伺服器端(Server-side)
Cumulus 通過 RTMFPReceiving 這個 RTMFP 協議資料接收引擎完成一些連線建立的相關動作,以及接收資料包:
void RTMFPServer::receive(RTMFPReceiving& rtmfpReceiving);
該函式會在收到客戶端發來請求時響應,如果是仍未建立連線的請求,則由此建立 Session(RTMFP 的核心概念之一),並取出其中的資料包。這其中有多個過程,我這裡就不詳述,以後會發布文章來解釋。
繼續我們的話題,在RTMFPServer::receive 函式中如果是建立連線階段,則會呼叫 Handshake 類的 receive 來做接下來的處理,這個我就不去詳細分析了,因為與本文主題無關。與本文有關的是,如果是已經建立了 Session 的,則會呼叫:
void ServerSession::packetHandler(PacketReader& packet);
這是一個相對複雜的函式,會從 packet 中取出很多有用的資訊。此外,比較重要的是,在我們上述情況下,會呼叫 Flow 類的:
void Flow::fragmentSortedHandler(UInt64 stage,PacketReader& fragment,UInt8 flags);
該函式中會對 Audio/Video/Data 分別響應不同的處理機制:
switch(type) {
case Message::AMF_WITH_HANDLER:
case Message::AMF:
messageHandler(name,amf);
break;
case Message::AUDIO:
audioHandler(*pMessage);
break;
case Message::VIDEO:
videoHandler(*pMessage);
break;
default:
rawHandler(type,*pMessage);
}
接下來在 Publication 中完成對所有訂閱了該釋出者的 Flash Players 傳送資訊,核心的程式碼為:
for(it=_listeners.begin();it!=_listeners.end();++it) {
it->second->pushAudioPacket(time,packet);
packet.reset(pos);
}
for(it=_listeners.begin();it!=_listeners.end();++it) {
it->second->pushVideoPacket(time,packet);
packet.reset(pos);
}
for(it=_listeners.begin();it!=_listeners.end();++it) {
it->second->pushDataPacket(name,packet);
packet.reset(pos);
}
其中的 _listeners 就是該 Publication 中的所有訂閱者。訂閱者的新增/刪除是通過:
Listener& addListener(
Peer& peer,
Poco::UInt32 id,
FlowWriter& writer,
bool unbuffered);
void removeListener(
Peer& peer,
Poco::UInt32 id);
這兩個函式來實現的。
要注意的是,在 Publication 中已經完成了向訂閱者釋出資訊,之後雖然會響應到 Peer 及 RTMFPServer 的onAudioPacket
、onVideoPacket
、onDataPacket
,但此時都與訂閱者接收資訊無關了。Cumulus 正是在RTMFPServer::onAudioPacket
、RTMFPServer::onVideoPacket
、RTMFPServer::onDataPacket
中呼叫使用者定製的服務(Lua 指令碼實現),完成一些自定義的需求。我是在此通過直接的 C++ 功能擴充套件,來新增業務需求的,沒有使用 Lua 指令碼及 Cumulus 中的 Lua 指令碼引擎,主要原因是為了提高效率。
3 客戶端訂閱(Subscribing on client side)
訂閱很簡單,在play
的時候傳入正確的釋出者名稱即可。
ns2.play("poechant_media_flow");
測試程式碼可以參考 Reference-1,其中的例子是關於NetStream::send(…)
的,用於傳送 Data,Audio 和 Video 的程式可以參考該例修改。
客戶端訂閱後,這些資訊並不會直接從釋出者那裡通過 P2P 的方式接收。如果想使用釋出者與接受者直接連線的方式,則需要在 NetStream 初始化的時候,傳入NetStream.DIRECT_CONNECTIONS
引數,預設的NetStream.CONNECT_TO_FMS
是將資料上行到伺服器再下行給所有訂閱者(Subscribers)的。根據不同的應用場景,可以使用不同的方式。
4 Reference
- http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#send()
-
轉載請註明來自柳大的CSDN部落格:Blog.csdn.net/poechant
-
相關文章
- OpenRTMFP/Cumulus Primer(4)CumulusServer啟動流程分析Server
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續)Server
- OpenRTMFP/Cumulus Primer(6)CumulusServer啟動流程分析(續2)Server
- OpenRTMFP/Cumulus Primer(7)CumulusServer啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(5)CumulusServer啟動流程分析(續1)Server
- OpenRTMFP/Cumulus Primer(7)CumulusServer 啟動流程分析(續3)Server
- OpenRTMFP/Cumulus Primer(16)AMF解析之AMFReader
- OpenRTMFP/Cumulus Primer(14)AMF解析之PacketReader/Writer
- OpenRTMFP/Cumulus Primer(8)CumulusServer主程式主迴圈分析Server
- OpenRTMFP/Cumulus Primer(18)AMF解析之AMFReader(續2)
- OpenRTMFP/Cumulus Primer(17)AMF解析之AMFReader(續1)
- OpenRTMFP/Cumulus Primer(9)AMF解析之BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(1)入門介紹與部署CumulusServerServer
- Redis的釋出訂閱Redis
- OpenRTMFP/Cumulus Primer(15)AMF解析之資料型別定義資料型別
- OpenRTMFP/Cumulus Primer(9)AMF 處理方式解析——BinaryReader/Writer
- OpenRTMFP/Cumulus Primer(19)獨立使用CumulusLib時的執行緒安全Bug執行緒
- Redis 的訂閱與釋出Redis
- OpenRTMFP/Cumulus Primer(13)IO管理之區域性記憶體片記憶體
- OpenRTMFP/Cumulus Primer(2)用Lua編寫HelloWorld應用擴充套件CumulusServer套件Server
- 釋出訂閱EventEmitterMIT
- Redis釋出訂閱Redis
- 釋出-訂閱模式模式
- 釋出訂閱模式模式
- sqlserver關於釋出訂閱replication_subscription的總結SQLServer
- OpenRTMFP/Cumulus Primer(23)執行緒邏輯分析之二:RTMFPManager對RTMFPServer的影響執行緒Server
- 設計模式之釋出訂閱模式(2) Redis 釋出/訂閱模式設計模式Redis
- 基於 Redis 的訂閱與釋出Redis
- JavaScript中釋出/訂閱模式的理解JavaScript模式
- 對釋出-訂閱者模式的解析模式
- Redis的訊息釋出和訂閱Redis
- Spring 中的釋出-訂閱模式Spring模式
- JS訂閱釋出模式JS模式
- 釋出訂閱管道化
- ActiveMQ釋出訂閱模式MQ模式
- openGauss 釋出訂閱
- mqtt訂閱和釋出MQQT
- MQTT-釋出與訂閱的報文MQQT