loginApp是整个bigworld进行用户认证的服务,是用户进入游戏的第一步。本篇主要针对loginApp的认证流程,如何和其他服务进行交互,以及loginApp针对多服务负载的不同做法进行分析。

  1. loginApp用户认证流程

  用户通过loginApp认证,主要是以下几个步骤:

  (1) client发送认证请求(前提是他已经知道loginApp的ip和端口)

  (2) loginApp在其监听端口上,收到这个请求

  (3) 收到请求之后,loginApp将认证信息转发给DBMgr,通过DBMgr来验证登陆认证是否合法

  (4) DBMgr通过查询数据库来进行确认

  (5) 如果认证是合法的,那么DBMgr通知BaseAppMgr去创建一个新的entity(玩家实例)

  (6) BaseAppMgr将创建新entity的需求,转发给当前负载最小的BaseApp

  (7) BaseApp创建一个新的Proxy,Proxy就是BaseApp上代表用户的实例

  (8) 同时可能需要在CellApp中创建一个玩家entity,这个要根据实际的项目需要了。也有可能直到用户选取了角色之后,才在cellApp中创建entity。

  (9) 当上门的事情都做完之后,proxy的UDP端口将结果返回给client(通过BaseAppMgr,DBMgr,最后LoginApp)

  上述流程的示意图是这样的:

  

  2. loginApp认证流程在代码中的体现

  代码只截取认为最重要的部分和关键语句,大部分代码省略,使用//......来代替

  (2)(3)loginApp收到认证请求,并且转发:

  

  
  // 先针对参数有效性进行检查
  // ......   // 判断是不是上一个认证请求还没做完
  // First check whether this is a repeat attempt from a recent pending
// login before attempting to decrypt and log in.
if (this->handleResentPendingAttempt( source, header.replyID ))
{
// ignore this one, it's in progress
loginStats_.incPending();
return;
} // 判断是否是否了加密
#ifdef USE_OPENSSL
Mercury::PublicKeyCipher * pPrivateKey = &privateKey_;
#else
Mercury::PublicKeyCipher * pPrivateKey = NULL;
#endif //.......

  // 判断是否之前有认证cache
// First check whether this is a repeat attempt from a recent
// resolved login before attempting to log in.
if (this->handleResentCachedAttempt( source, pParams, header.replyID ))
{
// ignore this one, we've seen it recently
return;
} // ...... INFO_MSG( "Logging in %s{%s} (%s)\n",
pParams->username().c_str(),
pParams->password().c_str(),
source.c_str() ); // Remember that this attempt is now in progress and discard further
// attempts from that address for some time after it completes.
cachedLoginMap_[ source ].reset();
cachedLoginMap_[ source ].pParams( pParams ); DatabaseReplyHandler * pDBHandler =
new DatabaseReplyHandler( source, header.replyID, pParams );
  
  
  // 发送给DBMgr
Mercury::Bundle & dbBundle = this->dbMgr().bundle();
dbBundle.startRequest( DBInterface::logOn, pDBHandler ); dbBundle << source << false /*off channel*/ << *pParams; this->dbMgr().send();

  

  (9) 认证消息返回给client代码

 void DatabaseReplyHandler::handleMessage(    const Mercury::Address & /*source*/,    Mercury::UnpackedMessageHeader & header,    BinaryIStream & data,

void * /*arg*/ )
{
uint8 status;
data >> status;

  //
检查认证返回码
if (status != LogOnStatus::LOGGED_ON)
{
    //
如果认证失败
    // ......

} LoginReplyRecord lrr;
data >> lrr; // If the client has an external address, send them the firewall
// address instead! if (!LoginApp::instance().netMask().containsAddress( clientAddr_.ip ))
{
INFO_MSG( "DatabaseReplyHandler::handleMessage: "
"Redirecting external client %s to firewall.\n",
clientAddr_.c_str() );
lrr.serverAddr.ip = LoginApp::instance().externalIP();
}
  
  // 返回client认证结果,并且缓存认证结果
  LoginApp::instance().sendAndCacheSuccess( clientAddr_, replyID_, lrr, pParams_ ); gNumLogins++; delete this;
}

  3. loginApp是如何做负载的

  loginApp是bigworld中用来处理用户登录认证的,为了防止单一loginApp存在性能瓶颈,同时防止单点故障,bigworld也是可以运行同时运行多个loginApp。不过我们知道多个baseApp和cellApp是分别有,baseAppMgr和cellAppMgr来做管理和负载的,loginApp我们却没有找到类似的loginAppMgr。

  在bigworld的文档中,是这样写的:

In terms of load, a single LoginApp should be sufficient for most purposes. However, as this is still a potential bottleneck, and single point of failure, BigWorld supports running multiple LoginApps.
The remaining issue then is how to distribute the client login requests across multiple login servers. The standard way to do this is use a DNS solution similar to how popular web sites balance traffic load across multiple machines.

  从上面的介绍来看,bigworld本身确实是没有提供类似的loginAppMgr,而是需要我们使用DNS来做负载,DNS返回不同的loginApp ip,来分担压力。

bigworld源码分析(2)—— loginApp分析的更多相关文章

  1. bigworld源码分析(3)——dbMgr分析

    dbMgr主要是玩家数据的读取和保存的,例如在bigworld源码分析(3)中,玩家在认证的时候,loginApp需要通过dbMgr来验证玩家数据是否合法,这就是针对玩家的账号数据进行查询.本篇中,我 ...

  2. bigworld源码分析(1)—— 研究bigworld的意义和目标

    对于网络游戏服务器开发熟悉的人,基本都知道bigworld引擎,此引擎包括客户端部分和服务器部分,已经有很多知名的网络游戏通过bigworld来构建游戏.我主要关注bigworld的服务器部分,它是一 ...

  3. ArrayList源码和多线程安全问题分析

    1.ArrayList源码和多线程安全问题分析 在分析ArrayList线程安全问题之前,我们线对此类的源码进行分析,找出可能出现线程安全问题的地方,然后代码进行验证和分析. 1.1 数据结构 Arr ...

  4. Okhttp3源码解析(3)-Call分析(整体流程)

    ### 前言 前面我们讲了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析]( ...

  5. Okhttp3源码解析(2)-Request分析

    ### 前言 前面我们讲了 [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析]( ...

  6. Spring mvc之源码 handlerMapping和handlerAdapter分析

    Spring mvc之源码 handlerMapping和handlerAdapter分析 本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mv ...

  7. HashMap的源码学习以及性能分析

    HashMap的源码学习以及性能分析 一).Map接口的实现类 HashTable.HashMap.LinkedHashMap.TreeMap 二).HashMap和HashTable的区别 1).H ...

  8. ThreadLocal源码及相关问题分析

    前言 在高并发的环境下,当我们使用一个公共的变量时如果不加锁会出现并发问题,例如SimpleDateFormat,但是加锁的话会影响性能,对于这种情况我们可以使用ThreadLocal.ThreadL ...

  9. 物联网防火墙himqtt源码之MQTT协议分析

    物联网防火墙himqtt源码之MQTT协议分析 himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,采用epoll模式支持数十万 ...

  10. Netty 源码学习——客户端流程分析

    Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...

随机推荐

  1. SELinux深入理解

    ps:今天在远程给服务器配置https的时候,一直乱码,以前做系统的系统第一件事情,就是关闭selinx,今天忘记了,然后就悲剧了... 弄了半天才弄好,镇定思痛,好好的来看下selinux 1. 简 ...

  2. Hibernate的关联映射——单向1-N关联

    Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...

  3. jQuery 添加元素

    jQuery 添加元素 1.append 在被选元素的结尾插入内容 $(document).ready(function(){ $("button").click(function ...

  4. 《BI项目笔记》历年理化指标分析Cube的建立

    该系统属于数据仓库系统,与传统的管理信息系统有本质差别,是“面向主题”设计的.“面向主题”的方式,既有利于数据组织和利用,又有利于用户的理解和使用. 分析主题主要维度:烟叶级别.烟叶级别按等级信息.烟 ...

  5. PHP基础知识之————php5-cli 的安装以及phpredis的安装

    在系统安装完后最好执行下列命令更新下软件 sudo apt-get update 安装php5-cli apt-get install php5-cli 下载phpredis wget https:/ ...

  6. oracle 之 函数

    本次主题 青涩/色 函数的结束一定要使用return语句返回一个与声明匹配的值 --语法: create[or replace] function<函数名> [(参数列表)] return ...

  7. tomcat配置项目的图片路径不在项目下的处理

    <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWA ...

  8. python核心编程第六章练习6-9

    6-9.转换.为练习5-13写一个姊妹函数,接受分钟数,返回小时数和分钟数.总时间不变,并且要求小时尽可能大.[答案]代码如下: #!/usr/bin/env python # translate m ...

  9. linux 删除用户

    userdel可删除用户帐号与相关的文件.若不加参数,则仅删除用户帐号,而不删除相关文件命 令: userdel 功能说明:删除用户帐号. 语 法:userdel [-r][用户帐号] 补充说明:us ...

  10. NGUI Camera's raycast hit through the UI Layer issue

    Raycast into GUI?http://forum.unity3d.com/threads/raycast-into-gui.263397/ << ; Ray myray = UI ...