超哥哥唉 发表于 2016-11-29 17:01

ProudNet使用方法#5:客户端间的P2P 通信

ProudNet是研究游戏软件开发的游戏服务端 &网络引擎。

本章对客户端之间的直接通信,即P2P通信进行讲述。一般P2P连接1.客户端1与客户端2建立P2P连接。2.连接成功后客户端1与客户端2之间互发信息。但是ProudNet并不是如此操作,而是服务器管理客户端之间的连接。这样做的原因是,假如客户端1被黑客攻击的话,连接任何客户端收发信息发生的隐患。如以下的方式:1.服务器发送客户端1与客户端2连接的命令。2.客户端1与客户端2连接到P2P及时响应。3.客户端1与客户端2之间互发信息。ProudNet 具有P2P组的概念,P2P组是由HostID识别的对象,P2P组可添加0个以上的客户端,也可添加到服务端。P2P组中客户端之间利用P2P进行通信。P2P组可自行定义。如:一个聊天室,游戏玩家的房间或者MMO游戏中假领域中的玩家。当然,一个客户端可进入多个P2P组,重叠也可以。客户端C1,C2 要建立一个组,参照一下代码。 1.   2.HostID list;   3.list = C1;   4.list = C2;   5.G = s->CreateP2PGroup(list, 2); // 第二个要素=数组的大小6.      7.   8.G = s.CreateP2PGroup({C1,C2});
G中包含了P2P组的HostID,服务器即可使用G。那么客户端如何知道G存在?调用关联函数如下。1.2.c->Set_OnP2PMemberJoin([...]   3.      (HostID memberHostID, // 4.      HostID groupHostID, // 5.      int memberCount,   // 6.      const ByteArray &customField)   7.{8.      G = groupHostID;   // 9.      Peers.Add(memberHostID);   10. });11.   12.   13. 14. c.P2PMemberJoinHandler =   15.   (memberHostID, // 16.   groupHostID,// 17.   memberCount,   // 18.   customField) =>{   19.   G = groupHostID; // 20.   Peers.Add(memberHostID);21. };
: memberHostID表示指向的主机及本地与P2P的连接。: memberHostID代表与进入了哪个P2P组。 : P2P组进入多少个主机。: 要添加代码的部分。需要对“自身在哪个P2P组和此通信的主机是谁”进行保存。客户端收到P2P通信的事件后,客户端即可直接发送给对方P2P信息。使用SendUserMessage 或者RMI即可。调用SendUserMessage 或者RMI 做为收信对象添加其它主机的HostID即可发送到P2P。假设添加到G,将队G中的所有主机同时发送数据。1.2.c->SendUsermessage(G, RmiContext::ReliableSend, data, length);3.   4.   5.6.c.SendUserMessage(G, RmiContext.ReliableSend, data);
ProudNet中对P2P组可添加3个以上的客户端。对于已经建立的P2P组,调用 JoinP2PGroup 将更多的主机添加到P2P组。对于新添加的主机和之前建立的主机用OnP2PMemberJoin 事件进行接收。P2P组中要删除主机调用NetServer.LeaveP2PGroup 即可,要消除P2P组调用DestroyP2PGroup 即可。此时,客户端通过OnP2PMemberLeave 了解“谁离开了”。即使建立P2P组通知给客户端也要进行打孔。打孔需要几秒时间,在客户端接收信息的期间NetServer 处理延迟,并在后端运行打孔。打孔成功后通知给客户端, 即OnChangeP2PRelayState事件。1.2.c->Set_OnChangeP2PRelayState([...]   3.      (HostID remoteHostID, ErrorType reason) // 4.{5.      ...6.});7.   8.   9.10. c.ChangeP2PRelayStateHandler =   11.   remoteHostID, reason) =>{// 12.   ...13. };   
:客户端打孔状态发生了何种改变,并且告知改变的状态。假设 reason=Ok 代表打孔成功,其它值代表打孔消失,显示如何消失的状态。要想利用RMI进行P2P通信,将proxy和stub 附加到所有的NetClient 中。如下所示:1.   2.      3.global MyGameP2P//4.{   5.      Player_Move( Vector3 position);   6.}   7.      8.      9.   10. MyGameP2P:: Proxy P2PProxy;//11. MyGameP2P::StubFunctional P2PStub;   12.   13. P2PStub.Player_Move_Function = [...]PARAM_MyGameP2P_Player_Move{//14.   ...   15. };   16.   17. c->AttachProxy(& P2PProxy);//18. c->AttachStub(& P2PStub);   19.   20. P2PProxy.Player_Move(G, RmiContext::UnreliableSend, myPosition); // 21.   22.   23.    24. MyGameP2P.Proxy P2PProxy;//25. MyGameP2P.Stub P2PStub;   26.   27. P2PStub.Player_Move = (sendFrom, rmiContext, position)=>{//28.   ...   29. };   30.   31. c.AttachProxy(P2PProxy);//32. c.AttachStub(P2PStub);   33.   34. P2PProxy.Player_Move(G, RmiContext.UnreliableSend, myPosition); //
: 定义P2P通信用RMI.: P2P RMI的 proxy与 stub的一个实例类.: 定义P2P接收RMI的处理函数.使用者自行定义.: 附加 的实例到NetClient 。: 对P2P 客户端远程调用. 总结:1.创建P2P组直接通信的CreateP2PGroup。2. 通过OnP2PMemberJoin了解客户端之间的P2P通信。3. RMI或者SendUserMessage 发送P2P信息。4.要使用P2P RMI的话Proxy与Stub都要附加到NetClient。

琳琅天上1 发表于 2016-11-30 14:49

好多的代码

琳琅天上1 发表于 2016-12-1 10:59

专业术语啊,听不太懂,嘿嘿嘿

jiaqiongjing 发表于 2016-12-2 09:30

好多的专业术语,看的眼花

大白白-- 发表于 2016-12-5 03:41

感谢分享~

琳琅天上1 发表于 2016-12-5 11:12

新的一天,新的开始。
页: [1]
查看完整版本: ProudNet使用方法#5:客户端间的P2P 通信