OpenRTMFP/Cumulus性能优化(7) 基于RTMFP的p2p的实现
2013-08-26 18:29
330 查看
1.RTMFP P2P连接描述:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/e3d1c0f98ab416e9084a5e5820d73bfe)
2.nearId的生成
#define ID_SIZE 0x20
class Entity {
public:
Entity();
virtual ~Entity();
...
const Poco::UInt8 id[ID_SIZE];
...
};
Entity::Entity():id() {
}
再把生成的peer.id进行16进制的编码,如下
Util::FormatHex(id,ID_SIZE);
该peer.id也即NetConnection进行连接时的NetConnection.nearId的值,比如:
如果某个peer.id=37007320,则16进制的编码后,其值为
nearId=4275137c203bbaffc9bf8ee70ee83782d217dc409aa18dbfa7baa0a84c2230b2
3.服务器P2Phandshake的步骤:
根据publisher的nearId查找其session和地址;
向publisher下发player的地址;
向player下发publisher的地址。
然后进行p2phandshake,如下:
_gateway.p2pHandshake(tag,response,peer.address,(const UInt8*)epd.c_str());
查找与该publisher相关的session:
Session* pSession = NULL;
Sessions::Iterator it;
for(it=_sessions.begin();it!=_sessions.end();++it) {
pSession = it->second;
if(Util::SameAddress(pSession->peer.address,address))
break;
}
...
ServerSession*pSessionWanted=(ServerSession*)_sessions.find(peerIdWanted);
然后进行握手,如下:
pSessionWanted->p2pHandshake(address,tag,pSession);
4.向player下发publisher的nearId:
Player和publisher都连接server成功后,并且publisher发布了比如名为“media”的音视频流,则player要想通过p2p播放publisher的音视频流,需要先与publisher进行p2p连接,因此,首先需要得到publisher的nearId,可通过server下发给player,如下:
AMFWriter& amf = client.writer().writeAMFMessage(RPCMessage::GET_PEER_IDS);
...
amf.beginObject();
amf.writeObjectProperty("peerId",Cumulus::Util::FormatHex(pSession->peer.id,ID_SIZE));
amf.endObject();
...
5.player进行p2p连接:
Player接收Publisher的nearId,如下:
public function getPeerIds(...args):void{
if(args.length == 2){
var value:uint = args[0] as uint;
var peerObject:Object = args[1] as Object;
if (peerObject.p2pFlag == 0) {
p2p = true;
_peerId1 = peerObject.peerId;
}
}
if (p2p) {//p2p为true,则进行p2pHandshake连接
call();
}
//login media front
if (!p2p) {//p2p为false,则进行正常的登录流程
startLogin();
}
}
Player接收到publisher的nearId后,进行如下操作:
controlStream = new NetStream(_nc,publisherNearId);
controlStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
controlStream.play(publisherNearId);与之进行p2p连接
6.创建发送NetStream和接收NetStream
连接成功了,就可以和publisher建立一条双工的通道进行数据的收发,如下:
//同时对外发布呼叫者的信息流
outgoingStream = new NetStream(_nc, NetStream.DIRECT_CONNECTIONS);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
outgoingStream.publish("caller");
//尝试播放被呼叫者的信息流
incomingStream = new NetStream(_nc, publisherNearId);
incomingStream.addEventListener(NetStatusEvent.NET_STATUS, incomingStreamHandler);
incomingStream.play("callee");
7.实例:
在自己的机器上跑了一下p2p例子,如下图:
flash客户端:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/c3cd0a68b8a196370579fb1c4acbd53b)
RTMFPServer端:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/6153e1f6f984d1e2c245ad2d5e50a2a6)
由图可看出两个client的peerId和编码后的nearId,如红线方框中所示
转载请注明出处:山水间博客,/article/2317678.html
参考文字:http://www.flextheworld.com/2009/01/flex-stratus-phone-2.html
2.nearId的生成
#define ID_SIZE 0x20
class Entity {
public:
Entity();
virtual ~Entity();
...
const Poco::UInt8 id[ID_SIZE];
...
};
Entity::Entity():id() {
}
再把生成的peer.id进行16进制的编码,如下
Util::FormatHex(id,ID_SIZE);
该peer.id也即NetConnection进行连接时的NetConnection.nearId的值,比如:
如果某个peer.id=37007320,则16进制的编码后,其值为
nearId=4275137c203bbaffc9bf8ee70ee83782d217dc409aa18dbfa7baa0a84c2230b2
3.服务器P2Phandshake的步骤:
根据publisher的nearId查找其session和地址;
向publisher下发player的地址;
向player下发publisher的地址。
然后进行p2phandshake,如下:
_gateway.p2pHandshake(tag,response,peer.address,(const UInt8*)epd.c_str());
查找与该publisher相关的session:
Session* pSession = NULL;
Sessions::Iterator it;
for(it=_sessions.begin();it!=_sessions.end();++it) {
pSession = it->second;
if(Util::SameAddress(pSession->peer.address,address))
break;
}
...
ServerSession*pSessionWanted=(ServerSession*)_sessions.find(peerIdWanted);
然后进行握手,如下:
pSessionWanted->p2pHandshake(address,tag,pSession);
4.向player下发publisher的nearId:
Player和publisher都连接server成功后,并且publisher发布了比如名为“media”的音视频流,则player要想通过p2p播放publisher的音视频流,需要先与publisher进行p2p连接,因此,首先需要得到publisher的nearId,可通过server下发给player,如下:
AMFWriter& amf = client.writer().writeAMFMessage(RPCMessage::GET_PEER_IDS);
...
amf.beginObject();
amf.writeObjectProperty("peerId",Cumulus::Util::FormatHex(pSession->peer.id,ID_SIZE));
amf.endObject();
...
5.player进行p2p连接:
Player接收Publisher的nearId,如下:
public function getPeerIds(...args):void{
if(args.length == 2){
var value:uint = args[0] as uint;
var peerObject:Object = args[1] as Object;
if (peerObject.p2pFlag == 0) {
p2p = true;
_peerId1 = peerObject.peerId;
}
}
if (p2p) {//p2p为true,则进行p2pHandshake连接
call();
}
//login media front
if (!p2p) {//p2p为false,则进行正常的登录流程
startLogin();
}
}
Player接收到publisher的nearId后,进行如下操作:
controlStream = new NetStream(_nc,publisherNearId);
controlStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
controlStream.play(publisherNearId);与之进行p2p连接
6.创建发送NetStream和接收NetStream
连接成功了,就可以和publisher建立一条双工的通道进行数据的收发,如下:
//同时对外发布呼叫者的信息流
outgoingStream = new NetStream(_nc, NetStream.DIRECT_CONNECTIONS);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, outgoingStreamHandler);
outgoingStream.publish("caller");
//尝试播放被呼叫者的信息流
incomingStream = new NetStream(_nc, publisherNearId);
incomingStream.addEventListener(NetStatusEvent.NET_STATUS, incomingStreamHandler);
incomingStream.play("callee");
7.实例:
在自己的机器上跑了一下p2p例子,如下图:
flash客户端:
RTMFPServer端:
由图可看出两个client的peerId和编码后的nearId,如红线方框中所示
转载请注明出处:山水间博客,/article/2317678.html
参考文字:http://www.flextheworld.com/2009/01/flex-stratus-phone-2.html
相关文章推荐
- RTMFP---基于CumulusServer的P2P功能实现
- 一种基于UDP协议实现P2P智能穿越NAT的方案
- 多媒体开发之播放器---一个基于FFmpeg、libtorrent的P2P播放器实现
- Flash Player 10 中的RTMFP协议(实现P2P技术)
- c#基于udp实现的p2p语音聊天工具
- 基于ESFramework的P2P实现 —— ESFramework扩展之EsfP2P
- [置顶] 基于pjsip实现p2p语音对讲
- ESFramework扩展之EsfP2P -- 基于ESFramework的P2P实现
- 一种基于UDP协议实现P2P智能穿越NAT的方案
- C#基于UDP实现的P2P语音聊天工具
- [转载]ESFramework扩展之EsfP2P -- 基于ESFramework的P2P实现
- 一种基于UDP协议实现P2P智能穿越NAT的方案
- 网络编程资料总结(四)----一种基于UDP协议实现P2P智能穿越NAT的方案
- 用C# 实现简单的p2p(基于TCP)
- [转载]Flash Player 10 中的RTMFP(实现P2P)
- 搭建RTMFP服务器以实现P2P直播
- 基于CDN与P2P技术IPTV系统平台的设计与实现
- C#基于UDP实现的P2P语音聊天工具
- ppPhone—基于Kademlia协议的P2P VoIP系统设计与实现
- c#基于udp实现的p2p语音聊天工具