OpenRTMFP/Cumulus性能优化(7) 基于RTMFP的p2p的实现

1.RTMFP P2P连接描述:

OpenRTMFP/Cumulus性能优化(7) 基于RTMFP的p2p的实现_第1张图片

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的步骤:

根据publishernearId查找其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接收到publishernearId后,进行如下操作:

        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客户端:

OpenRTMFP/Cumulus性能优化(7) 基于RTMFP的p2p的实现_第2张图片

RTMFPServer端:

 

由图可看出两个client的peerId和编码后的nearId,如红线方框中所示 

 

 

转载请注明出处:山水间博客,http://blog.csdn.net/linyanwen99/article/details/10360111

参考文字:http://www.flextheworld.com/2009/01/flex-stratus-phone-2.html

 

你可能感兴趣的:(山水间文集)