在做LOL竞技场项目(项目总结)的时候,发现WEB页面可以直接调用客户端里面的接口和数据,这使我很好奇,决心花点时间再研究下这个实现的大致原理,拓展一下思路和知识面,也为后续这种内嵌客户端的项目开发积累经验,然后在得到多位大牛的帮助下,最后才有了这篇浅显的分析,希望能抛砖引玉,如果你了解得更深入,也可以消息我,一起探讨。

初探:入口

首先我们来看下,在我做的页面里调用客户端接口的代码:

首先是请求接口

其次是等待结果返回

从上面的实现我们大致可以判断,这里是通过window的postMessag消息机制来进行数据通讯的,我们再继续往下分析下 RClientWindowMessenger 的定义,看能否证实一下,该对象是在一个JS文件中定义的对象,而sendMessage的定义如下:

如果我们把上面sendMessage调用和实现的代码组合到一起看,其实就是我们在自己的页面里面调用顶层的window对象来发送一条消息,具体如下:

而数据也是通过消息从客户端传送回来的,而RClientWindowMessenger.addMessageListener的实现就比较简单了,就是实现一个事件分发,把对应事件请求结果分发给事情处理器,如下:

到这里我们只是了解了我们的页面向客户端请求数据使用的是window.postMessage消息机制,但是我们并不了解客户端是怎么接收到这个消息,并处理再返回对应结果的,咱接着往下深入看看。

二探:架构

从上面我们大概能知道我们的页面是嵌入到一个父级页面里面的,因为使用了top,为了证实这个,我在LOL的客户端测试过,在我们的页面里,判断top==window=false,这说明top是存在的另外一个页面,然后我就猜想,top里面应该隐藏了很多的实现逻辑。为了继续深入,我找了负责对接LOL新版LCU客户端的同事,从他们那里了解了到了更多的信息,这更多信息就得了解下riot为啥会有LCU客户端,是为了解决什么问题?并且是怎么解决的呢?这个答案在LCU架构大神自己分享的文章里面我找到了答案,有三个原因:

在博客里大神提到LCU之前的客户端是08年使用AdobeAir实现的,但是随着时间发展,这个框架遇到了下面几个最突出的问题:

第一、H5和JS实现桌面Client端应该有很成熟的方案,并且这能带来额外的好处,比如标准化的流程,开发工具和开发者。

第二、玩家想要在退出游戏的时候保持登录态,接收好友请求或者游戏邀请,而air资源占用较高,有些人会把进程杀掉

第三、随着项目扩大,当很多team都想为客户端增加功能的时候,冲突问题越来越严重

为了解决上面的三个问题,大神设计了超级腻害的架构(当然中间也躺了很多坑,具体可以去文末参考资料看英文原文),就是利用H5+JS来渲染前端UI,然后C++来处理业务逻辑和后端通信,而前端UI接收事件,通过websocket跟后端的C++模块通信。

通过上图我们可以看到,H5部分是运行在CEF(Chromium Embedded Framework)容器里的,这里的CEF你可以简单的理解为就是一个Webview,只不过它比Webview更加灵活,可深度定制,因为它是Google大大开源的,是chrome浏览器实现的内核版本,能实现HTML,JS,CSS的解析,而C++部分还是native实现。

看完上面我们就能知道,这不就是一个CS架构哇,前端UI利用H5技术,后端跑着一堆C++的Microservice,对的没错,大神自己也说这就是一个CS架构,那这个架构是如何解决上面遇到的三个问题的呢?

首先:基于CEF, 使用标准规范的H5+JS实现UI展示和变换逻辑,轻松解决问题1。

其次:游戏时,可以直接关闭CEF进程,只保留后端C++微服务,内存占用20M(最新版本实测30M),登录态保留在微服务中,并能实现tip提示,而CEF UI完全可以通过从微服务拉取数据重建。完美解决问题2。

最后:多人协作的问题,这里大神设计还是相当巧妙的,H5和C++层都设计成了插件机制,能无限扩展,而不会互相冲突,其次还可以按需加载,一劳永逸的解决了问题3。

三探:组件

对于CEF本身和C++的MicroService实现部分我们这里就不去详细深入介绍了(水太深),我感兴趣的还是前端部分,所以这里主要是探究下在CEF里面运行的前端组件部分的实现思路。

首先我们想象中的前端组件就是html,js和css的文件组合,但是在LCU客户端这里还不太一样,安装完LOL游戏客户端后,在安装目录 LeagueClient\Plugins 下面有一堆文件夹,分别是以rcp-be- 或者 rcp-fe- 开头的,如下图

be 代表的是C++的MicroService组件,而fe就是我们要研究的前端组件实现了,打开fe的一个目录,我们可以看到一般有2个文件

1.  description.json 模块描述信息

2.  assets.wad 包含完整组件文件(不过这里都是压缩过的)

接下来我们要看下wad里面都是什么东东,发现一般的解压缩软件无法解压,然后搜索在github上找到了解压wad文件的node工具包,解压完就看到我们熟悉的内容了html,js和json,图片等资源,我这里先打开rcp-fe-lol-home组件,这个是LCU打开加载的首页,如下图:

在解压完的根目录了,有个928200cf91a315ce.min.js文件,这个就是主窗口的js打包压缩文件,我们可以用编辑器打开格式化一下,还是可以大致分析出很多我们需要的信息,在这个js里,我们发现了主窗口容器常用的消息定义:

容器接收:

rcp-fe-lol-home-loaded:告知框架首页加载完毕

rcp-fe-lol-home-data-request:请求当前账号和环境信息

rcp-fe-lol-home-session-request:请求当前登录token

rcp-fe-lol-home-champ-game-data-request:请求指定英雄和皮肤的详细信息

rcp-fe-lol-home-open-store:请求打开商店

rcp-fe-lol-home-play-sound:请求播放声音

容器发送

rcp-fe-lol-home-hide:主窗口隐藏

rcp-fe-lol-home-show:主窗口显示

rcp-fe-lol-home-settings-changed:游戏配置更新

rcp-fe-lol-home-data-response:返回当前账号和环境信息

rcp-fe-lol-home-session-response:返回当前登录的token

rcp-fe-lol-home-champ-game-data-response:返回指定英雄和皮肤的相信信息

除了上面的消息定义,我还找到基础关键的代码实现

1、首先是iframe创建:

2、给iframe发送消息

3、消息通讯

上图我们可以看到上面常见的几个消息,这里接受到消息后,会有相应的处理,然后处理结束后,会把结果再通过消息返回,下面我们分析下几个消息的处理细节:

消息处理分析

rcp-fe-lol-home-data-request

我们可以看到此消息的hanlder内部是直接调用了f.getClientData方法,然后得到结果t,通过response消息返回,f不用管,下面我们看下getClientData方法的实现:

上面通过字段名称,我们可以了解到是直接返回了账户和系统相关的信息。同样的rcp-fe-lol-home-session-request也是类似的,接下来我们分析下一个比较有用的消息。

rcp-fe-lol-home-champ-game-data-request

获取英雄或者皮肤详细信息,这个消息的handler我们看到,内部貌似是调用了另外一个模块(lol-game-data)里的一个json文件,然后把这个文件的内容返回了,这个lol-game-data,我搜索了下,原来这是另外一个插件,不过按插件文件夹名称:rcp-be-lol-game-data,这里被定义为了后端插件,但是里面没有C++ DLL插件,而是2个wad文件,default-assets.wad和zh_CN-assets.wad,我们前面讲过,wad其实就是一堆静态资源(js css html image text等)的打包文件,应该大部分资源都打包到这里了,因为这2个文件大概有800M,我解压看了下,确实挺多内容的,这里不详述都包含哪些内容了。

我们继续看 p("/lol-game-data”) 应该是加载插件,然后通过get方法获取数据,get这里接受了一个 /assets/v1/champions/" + championId + ".json”,很明显是个json文件,这个文件里就是对应的英雄或者皮肤的配置数据。而我们获取的到数据格式如下:

我们可以看到,上面英雄的图片,买QQ号码声音资源都是通过 127.0.0.1:40854 来访问的,那这就说明LCU客户端自己开了一个本地的WebServer,为了防止冲突,这里每次都是随机设置了端口号,很明显这里的webserver不是我们通常意义上的apache或者nginx,因为这里是从wad压缩包里读取数据,而不是常规的目录里,所以实现肯定不一样。具体实现没有深究,

上面的分析总结一下:H5页面和客户端通信的核心原理就是message,而html资源都是通过本地开启webserver来访问。具体实现就是:LCU会创建CEF的进程,然后创建一个webview的主容器,最后会在主容器里创建一个IFrame,用来加载我们的页面,正如上面讲的,我们的页面定义了消息发送(top)和接收的方法,而主容器里也定义了同样的消息发送(IFrame)和接收的方法,实现了H5和Client本地数据的双向通讯。

四探:进程通讯

接下来我们进一步分析客户端的实现,打开LCU客户端,我们可以看到,如下几个进程:

LeagueClient:主进程,承载后端插件,前端插件,并且负责和服务器通信。

LeagueClientUx:CEF承载进程,负责前端主容器逻辑处理和与LeagueClient主进程通讯。

LeagueClientUxRender:CEF承载进程,应该只负责HTML UI界面渲染,强制kill掉它,会自动重新拉起来。

我们最前面讲大神架构的时候说到,在启动游戏客户端后,就可以关闭掉UI部分,在设置里我选择了启动游戏关闭客户端,在进程里,发现Ux和UxRender进程就被杀掉了:

然后我们观察网络通讯可以看到,进程之间通过websocket通讯,这个在大神的文字里也有说到,下面可以看到,这个通讯是双向的,根据端口我们可以看到,LeagueClient 和LeagueClientUx之间,互相有通讯,然后UX还和GameLoader之间也有通讯,还可以看到LeagueClient和Ux都开了多个websocket通道,而且多个通道之间会通讯,具体每个通道负责什么信息,这里不是太清楚。

实际上,通过 lol-home-data 消息,我们可以得到客户端启动的http webserver的地址和端口,后面所有的资源访问都是通过这个地址,通过端口50992,我们可以确定,LeagueClient进程负责启动这个webserver,实际上通过下图中assetUrls里面的url信息,我们可以推断出,这个webserver就是把整个plugins目录当做了跟目录,然后CEF承载前端fe插件的加载访问也是通过这个webserver使用https的协议,而不是特殊的本地文件处理,完全符合web的规范。这样前端插件就真的跟web开发一摸一样了。只是多了riot提供的更丰富的API接口而已。

然后我试着直接在chrome里访问对应的资源,发现需要权限验证,在客户端里访问应该是种了带权限的cookie或者token,所以能直接通过,而外面是无法访问到的。

总结

通过这个分析,对于LCU的客户端架构有了大致的了解(前端部分),也算是拓展了自己的思路,近3年,随着node的发展,其实对于前端开发来说,对于客户端的实现方案还是挺多选择的,这里使用了CEF实现的方式,这里瞎扯淡一下:是否可以改为node+webkit的nwjs架构,或者基于Atom编辑器实现的electron框架,这个可以纯前端开发实现,也可以支持插件化或者模块化开发,是不是别这里的CEF更简单呢?当然任何一个架构都是在历史架构基础之上演化而来,而离开历史框架谈架构意义不大。

游戏技术探讨:LOL新版客户端LCU架构探析相关推荐

  1. 计算机辅助翻译论文的应用环境,计算机辅助翻译(CAT)技术在现代翻译中的应用探析.pdf...

    计算机辅助翻译(CAT)技术在现代翻译中的应用探析.pdf 计算机辅助翻译 (CAT)技术 在现代翻译中的应用探析 王华树 杨润丽2 (1.北京师范大学,北京:2.北京大学,北京) 摘 要 :在经济全 ...

  2. 游戏SDK(一) 客户端整体架构

    游戏SDK 客户端整体架构 前言 从事游戏SDK的开发好几年,包括 Android 端及 iOS 端,做过休闲游戏SDK 也做过重度手游SDK,从对SDK和游戏行业一无所知到现在还算有些了解,踩过很多 ...

  3. 论计算机技术与电子商务探讨,计算机技术电子商务应用论文,关于探析计算机技术在电子商务中的应用相关参考文献资料-免费论文范文...

    导读:本论文可用于计算机技术电子商务应用论文范文参考下载,计算机技术电子商务应用相关论文写作参考研究. [关 键 词] 计算机技术:电子商务:应用分析 [中图分类号] G718 [文献标志码] A [ ...

  4. 物联网技术的最新发展状况及应用探析

    在现实生活中已可见物联网的具体应用,如远程防盗.高速公路不停车收费.智能图书馆.远程电力抄表等,只不过这些仅是物联网技术的邹形,还尚未形成一个庞大的网络.物联网固然给我们构建了一个十分美好的蓝图,在未 ...

  5. 英雄连门最新服务器开启时间,新版客户端现已开启公测!

    从今天开始,所有玩家都可以参加公测并体验新版客户端了. 快去下载(大约6GB)新客户端吧.无需任何申请程序--只需打开 如上周所述,新版公测客户端将对所有人开放.在公测期间,你随时可以通过下载器下载更 ...

  6. 端到端加密优缺点_网络通信中常见的数据加密技术探析

    前言 目前在各行各业中都广泛使用计算机网络通信技术,计算机网络已成为人们生活中不可或缺的重要内容,人们对计算机网络的依赖性不断提高,计算机网络通信的安全性受到越来越多的关注.数据加密技术是保障计算机网 ...

  7. 金融行业网络架构与技术探讨

    1.整体架构 整体是数据中心--一级分行--二级分行--支行的架构 拓扑: 需要考虑的核心需求和解决方案: 高可用性: 双中心.双设备.链路捆绑.动态协议.VRRP.生成树.BFD.防火墙的HA 设备 ...

  8. 笔记|滴滴iOS客户端的架构,组件化,技术选型

    笔记来源infoq:滴滴iOS客户端的架构演变之路 1,状态机,把订单中的阶段,例如:出租车的等待抢单.出租车的等待接驾.专车的等待抢单.专车的等待接驾,都当成一种独立的状态,每 个状态机只需要知道可 ...

  9. ETSI MEC — 面向边缘计算的 5G 增强技术探讨

    目录 文章目录 目录 面向边缘计算的 5G 增强技术探讨 边缘应用服务器(EAS) 边缘应用服务器(EAS)的发现机制 应用迁移,EAS 重定向,业务连续性保障 网络向本地边缘应用平台快速提供网络信息 ...

最新文章

  1. 码流 / 码率 / 比特率 / 帧速率 / 分辨率 / 高清
  2. 辨析Java与Javascript
  3. 【控制】《鲁棒控制》-周克敏老师
  4. 详解两阶段3D目标检测网络 Voxel R-CNN:Towards High Performance Voxel-based 3D Object Detection
  5. python实现线性回归预测不用sklearn库_python – 为什么我的自定义线性回归模型不匹配sklearn?...
  6. php和xml区别,php和XML
  7. 广西大学计算机英语复试的内容,广西大学计算机专业的研究生复试时
  8. 稳定币协议Fei Protocol通过FIP-2提案
  9. linux下进程的创建代码,伪代码说明Linux进程创建过程
  10. Midori 0.5 发布,轻量级跨平台网页浏览器
  11. 资源管理器 右键 反应慢 现象解决方案
  12. eclipse中tomcat能正常启动,但是访问不了tomcat首页(问题解决)
  13. 公司邮箱地址格式是什么?邮箱地址怎么写?邮箱地址大全
  14. 集合竞价如何买入_教你几招!什么是集合竞价?散户如何参与集合竞价?
  15. 2022化工自动化控制仪表考试试题及模拟考试
  16. 计算机科班Java开发好书推荐
  17. js过滤英文双引号变成中文双引号
  18. 开启邮箱的SMTP服务获取授权码(QQ邮箱、163邮箱)
  19. 远程桌面退出后CPU过高的问题
  20. 主流平面设计软件推荐,实用工具推荐必坑指南!

热门文章

  1. WIN10共享剪切板
  2. [FML]学习笔记三 Rademacher Complexity
  3. 运用大数据提升政府治理能力
  4. Chrome Stylist 插件 (CSS备份)
  5. php配置文件详解(phg.ini php-fpm.conf)
  6. 多元线性回归-岭回归
  7. Mysql高级部分系列(二)
  8. 理论---url pattern 匹配规则
  9. 魔兽争霸 怎么窗口化
  10. 全新平台VS2010