拉起DS进程

客户端将比赛地图及相关参数发送给ZoneSvr请求开赛,收到消息后,ZoneSvr会分配一个ip和端口号,并与客户端发过来的地图及其他参数,来构建一个命令行来拉起一个DS进程,

DS启动时在UGameEngine::Init ==> UGameEngine::Browse中调用UGameEngine::LoadMap来序列化地图数据到UWorld* GWorld,

并调用UWorld::SetGameInfo来创建AGameInfo对象,然后调用UWorld::Listen来创建UNetDriver* NetDriver,并调用UTcpNetDriver::InitListen来创建socket,

在LoadMap结尾发送一个信号量通知ZoneSvr,要ZoneSvr将ip和端口号发送给客户端,告诉客户端自己已经准备好了

最后DS在UWorld::Tick中每帧调用NetDriver的UTcpNetDriver::TickDispatch函数中检查是否有客户端连接过来

客户端加入DS

客户端得到DS的ip和端口后,执行命令:open 10.123.102.132:7500?Uin=5897623?Name=Tom?Team=0?ClanName=?SpectatorOnly=0?bVIP=0?bIsRoomOwner=0

open命令会调用UGameEngine::SetClientTravel函数将open命令参数内容设置给UGameEngine的TravelURL变量

客户端在游戏主循环UGameEngine::Tick中会每帧检查UGameEngine的TravelURL变量是否为空

当不为空时,会调用UGameEngine::Browse来创建UNetPendingLevel类型的全局指针变量GPendingLevel

GPendingLevel在其构造函数中创建UTcpNetDriver对象,然后调用该对象的InitConnect函数来创建UDP的Socket、UTcpipConnection对象及Control Channel

然后客户端就正式开启了加入DS的过程,详细如下图所示

Step2补充说明

Ds在UWorld::Tick中每帧调用NetDriver的UTcpNetDriver::TickDispatch函数会先在ClientConnections数组中查找是否已经创建了这个客户端的连接,

发现没有会调用UTcpipConnection::InitConnection来创建一个新的NetConnection,然后加入到ClientConnections数组中,

然后使用这个新的NetConnection调用ReceivedRawPacket来处理网络包数据,由于NMT_Hello包使用的是ControlChanel发送的,

而当前NetConnection的Channels数组中没有该Chanel,于是会调用UNetConnection::CreateChannel创建ControlChanel,

然后使用新的ControlChanel调用UChannel::ReceivedRawBunch ==> UChannel::ReceivedSequencedBunch ==> UControlChannel::ReceivedBunch ==> UWorld::NotifyControlMessage来做出应答

Step5补充说明

bSuccessfullyConnected为true,并有了URL.Map及游戏模式,使得UGameEngine::Tick中检查通过开始LoadMap加载客户端地图:

① 加载失败,则调用传入?failed参数调用UGameEngine::Browse来关闭UNetPendingLevel连接并将GPendingLevel置NULL(在UGameEngine::CancelPending函数中实现),然后加载缺省地图(如大厅地图)

② 加载成功,在LoadMap函数中会将GPendingLevel的NetDriver、NetConnection、ControlChannel转交给新地图的GWorld,地图加载完成后会发送NMT_JOIN消息,并将GPendingLevel置NULL

其他说明

a. UE3通过FSocketSubsystem类型封装了windows(FSocketSubsystemWindows)和unix(FSocketSubsystemBSD)上的Socket,向上对引擎提供了一致的编程接口

引擎通过提供全局变量FSocketSubsystem* GSocketSubsystem单例的方式来使用Socket相关功能

b. 服务器的收包逻辑在UWorld::NotifyControlMessage函数的else分支中,客户端的收包逻辑在UNetPendingLevel::NotifyControlMessage函数中

UE3客户端加入DS过程的更多相关文章

  1. SpringMVC处理客户端请求的过程

    SpringMVC处理客户端请求的过程 以程序部署在Tomcat上为例,网站程序使用SpringMVC框架开发. 1.客户端发起一个访问网站的请求(如: localhost:8080/index). ...

  2. NIO客户端主要创建过程

    NIO客户端主要创建过程:   步骤一:打开SocketChannel,绑定客户端本地地址(可选,默认系统会随机分配一个可用的本地地址),示例代码如下:    SocketChannel client ...

  3. UE3客户端服务器GamePlay框架

    客户端(当前玩家)与服务器对应关系图: 整体上看,UE3的GamePlay框架使用的是MVC架构 ① 橙色的Actor对象及橙色箭头相连的成员变量只会被同步给Owner客户端 Controller:控 ...

  4. 记一次kafka客户端NOT_COORDINATOR_FOR_GROUP处理过程

    转发请注明原创地址:https://www.cnblogs.com/dongxiao-yang/p/10602799.html 某日晚高峰忽然集群某个大流量业务收到lag报警,查看客户端日志发现reb ...

  5. Fabric1.4源码解析:客户端创建通道过程

    在使用Fabric创建通道的时候,通常我们执行一条命令完成,这篇文章就解析一下执行这条命令后Fabric源码中执行的流程. peer channel create -o orderer.example ...

  6. 利用IDEA创建Web Service服务端和客户端的详细过程

    创建服务端 一.file–>new–>project 二.点击next后输入服务端名,点击finish,生成目录如下 三.在 HelloWorld.Java 文件中右击,选 WebServ ...

  7. 安装oracle 11g 客户端,检查过程中报物理内存不足的解决

    今早接到同事电话,说安装oracle 11g客户端的时候,在检查先决条件的时候,报错,说内存不足,但是本机的内存是2G,肯定够用:如图: 找了一圈,原来Oracle执行先决条件检查是依赖c$共享,很多 ...

  8. rtmp直播拉流客户端EasyRTMPClient设计过程中时间戳问题汇总

    EasyRTMPClient 简介 EasyRTMPClient是EasyDarwin流媒体团队开发.提供的一套非常稳定.易用.支持重连接的RTMPClient工具,以SDK形式提供,接口调用非常简单 ...

  9. Netty源码分析之客户端启动过程

    一.先来看一下客户端示例代码. public class NettyClientTest { public void connect(int port, String host) throws Exc ...

随机推荐

  1. [Swift]LeetCode238. 除自身以外数组的乘积 | Product of Array Except Self

    Given an array nums of n integers where n > 1,  return an array outputsuch that output[i] is equa ...

  2. B+树的Copy-on-Write设计

    本文主要介绍B+树的Copy-On-Write,包括由来.设计思路和核心源码实现(以Xapian源码为例).中文的互联网世界里,对B树.B+树的科普介绍很丰富,但对它们在工业界的实际使用却几乎没有相关 ...

  3. Python内置函数(62)——sum

    英文文档: sum(iterable[, start]) Sums start and the items of an iterable from left to right and returns ...

  4. BBS论坛(三十二)

    32.帖子排序功能完成 (1)front_index.html <ul class="post-group-head"> {% if current_sort==1 % ...

  5. [我的理解]Javascript的原型与原型链

    一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...

  6. Hystrix是如何工作的

    接上一篇:<Hystrix介绍> 流程图 下面这幅图相当重要 稍微解释一下上面的流程: Construct a HystrixCommand or HystrixObservableCom ...

  7. Python2中文处理纪要

    python2不是以unicode作为基本代码字符类型,碰到乱码的几率是远远高于python3,但即便如此,相信很多人,也不想随意的迁移到python3,这里就总结几个我平常碰到的问题及解法. 文件中 ...

  8. C语言实现二叉树的创建&遍历

    算法思想(重点是递归的使用)  利用扩展先序遍历序列创建二叉链表 采用类似先序遍历的递归算法,首先读入当前根结点的数据,如果是'.'则将当前 树根置为空,否则申请一个新结点,存入当前根结点的数据,分别 ...

  9. 用户代码与Spring的交互形式,你有总结过吗?

    PS:教科书般的文章太多了,我要追求与众不同,注意是追求.授人以鱼不如授人以渔. 相关文章 如何慢慢地快速成长起来? 你是如何看待Spring容器的,是这样子吗?

  10. Jenkins结合.net平台综合之监听git仓库并自动摘取最新代码编译

    前面章节我们讲解了Jenkins结合.net平台工具以及一些第三方工具实现项目自动还原,自动编译,自动测试和自动发布.然而实现自动化还有一个关键的步骤就是监听源码仓库变化然后从仓库拉取最新代码,然后再 ...