腾讯GAD 程序老司机:LOL新版客户端LCU架构探析

在进行LOL arena项目(项目摘要)时,我发现WEB页面可以直接在客户端中调用接口和数据。这让我感到好奇,并决心花一些时间来研究此实施的一般原则,并扩大思路和范围。知识,也为该嵌入式客户端项目的后续开发积累了经验,然后在许多大牛的帮助下,我终于得到了这种简单的分析,希望能丢下一块砖头并吸引玉器,如果您了解得更深,您可以给我发消息并一起讨论。{} {}作者:springwang

初步探索:入口

首先,让我们看一下我制作的页面中调用客户端界面的代码:

首先是请求界面

之后等待结果返回

我们可以从上述实现中大致判断。这是通过窗口的postMessag消息机制进行的数据通信。让我们继续分析RClientWindowMessenger的定义,看看是否可以确认该对象位于JS中文件中定义的对象以及sendMessage的定义如下:

如果将上面的sendMessage调用和实现代码结合在一起,实际上就是我们在页面中调用顶层窗口对象来发送消息,如下所示:

还会通过消息从客户端发送回数据,并且RClientWindowMessenger.addMessageListener的实现相对简单。它是为了实现事件分发并将相应的事件请求结果分发给事件处理器,如下所示:

在这里,我们仅了解页面使用window.postMessage消息机制从客户端请求数据,但我们不了解客户端如何接收此消息以及如何处理并返回相应的结果。然后往下看。

第二次探索:架构

通过以上内容,我们可能知道我们的页面已嵌入父页面中,因为使用了top。为了确认这一点,我已经在LOL客户端上对其进行了测试。在我们的页面中,判断top == window = false,这表明top是另一个存在的页面,然后我猜应该在top中隐藏很多实现逻辑。为了继续深入,我找到了一个负责与LOL的新LOL客户对接的同事。我从他们那里学到了更多信息。有关更多信息,我必须了解为什么在骚乱中有一个LCU客户端。问题是什么?以及如何解决?在LCU架构神本人分享的文章中找到了这个答案。有以下三个原因:

在博客中,这位大神提到在2008年使用AdobeAir实施LCU之前的客户端,但是随着时间的发展,此框架遇到了以下最突出的问题:

首先,H5和JS应该有一个非常成熟的桌面客户端解决方案,这可以带来更多好处,例如标准化的流程,开发工具和开发人员。

其次,玩家希望在退出游戏时保持登录状态,收到好友请求或游戏邀请,而空中资源占用很多,有些人会扼杀该过程

第三,随着项目的扩展,当许多团队希望向客户添加功能时,冲突问题变得越来越严重

为了解决以上三个问题,大神设计了一个超级讨厌的建筑(当然,中间有很多坑,您可以转到文章的末尾作为参考,以查看原始的英文文本) ,即使用H5 + JS渲染前端UI,然后,C ++处理业务逻辑和后端通信,而前端UI接收事件并通过websocket与后端C ++模块进行通信。

如上图所示,H5部分在CEF(铬嵌入式框架)容器中运行。这里的CEF可以简单地理解为Webview,但是它比Webview更灵活,更深入。定制,因为它是Google极大的开源,它是chrome浏览器实现的内核版本,可以实现对HTML,JS,CSS的分析,而C ++部分仍是本机实现。

阅读以上内容后,我们可以知道这不是CS体系结构。哇,前端UI使用H5技术,后端运行大量的C ++微服务。没错,上帝本人说这是CS架构。该体系结构如何解决上面遇到的三个问题?

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

第二:在游戏过程中,您可以直接关闭CEF进程,仅保留后端C ++微服务,内存消耗为20M(最新版本为30M),登录状态保留在微服务中,并且可以实现提示提示,以及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个文件

接下来,我们必须查看wad里面的内容,发现常规解压缩软件无法解压缩,然后在github上搜索node工具包以找到wad文件。减压后,我们将看到我们熟悉的内容。内容包含html,js和json,图片和其他资源。在这里,我首先打开rcp-fe-lol-home组件。这是LCU打开加载的主页,如下所示:

容器收到:

rcp-fe-lol-home-loaded:通知框架主页已加载

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

rcp-fe-lol-home-session-request:请求当前的登录令牌

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:游戏配置更新

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

rcp-fe-lol-home-session-response:返回当前记录的令牌

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

...

除了以上消息定义外,我还发现了基本的关键代码实现

1.第一步是创建一个iframe:

2.将消息发送到iframe

3.电子报

在上图中,我们可以在上方看到一些常见消息。收到消息后,将进行相应的处理,然后在处理完成后,将通过消息返回结果。让我们分析接下来的几条消息。处理细节:

邮件处理分析

rcp-fe-lol-home-data-request

我们可以看到,此消息的处理方法直接调用f.getClientData方法,然后获取结果t,该结果由响应消息返回,f无关紧要。下面我们看一下getClientData方法的实现:

从上面的字段名称中,我们可以知道直接返回了与帐户和系统相关的信息。相同的rcp-fe-lol-home-session-request是相似的。接下来,我们分析下一个有用的新闻。

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

获取英雄或皮肤的详细信息。从该消息的处理程序中可以看出,似乎它在内部调用了另一个模块中的json文件(lol-game-data),然后返回了该文件的内容。我搜索了lol-game-data,结果发现这是另一个插件,但是根据插件文件夹的名称:rcp-be-lol-game-data,这被定义为后端插件,但没有C ++ DLL插件,而是有2个wad文件:default-assets.wad和zh_CN-assets.wad。如前所述,wad实际上是一堆静态资源的打包文件(js css html图像文本等)。在这里,由于这两个文件大约为800M,因此我将其解压缩并进行了查看,它的内容很多,因此我将不赘述。

让我们继续看到p(“ / lol-game-data”)应该是加载插件,然后通过get方法获取数据,在此处接受一个/ assets / v1 /冠军/“ + ChampionId +“ .json”,显然是一个json文件,该文件是对应的英雄或皮肤的配置数据。我们获得的数据格式如下:

以上分析总结:H5页面和客户端通信的核心原理是消息,而html资源则通过本地开放式Web服务器进行访问。具体实现是:LCU将创建CEF流程,然后创建webview的主容器,最后在该主容器中创建IFrame以加载页面。如上所述,我们的页面定义了消息发送(顶部在主容器中定义了接收方法以及相同的消息发送(IFrame)和接收方法,从而实现了H5和客户端本地数据的双向通信。

四大探索:过程沟通

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

LeagueClient:主进程,该进程带有后端插件和前端插件,并负责与服务器进行通信。

LeagueClientUx:CEF承载过程,负责前端主容器逻辑处理以及与LeagueClient主过程的通信。

LeagueClientUxRender:CEF托管过程,该过程仅应负责呈现HTML UI界面,强制杀死它,它将自动再次拉起。

最初谈到“大神”架构时,我们说过启动游戏客户端后,我可以关闭UI部分。在设置中,我选择启动游戏以关闭客户端。在此过程中,我发现了Ux和UxRender进程被杀害:

然后观察网络通信,可以看到该过程通过websocket进行通信。大神的经文也提到了这一点。如下所示,这种通信是双向的。根据端口,我们可以看到LeagueClient和LeagueClientUx之间存在通信,UX与GameLoader之间存在通信。您还可以看到LeagueClient和Ux打开了多个websocket通道,并且多个通道之间将进行通信。每个渠道负责什么信息,这里不太清楚。

然后,我尝试直接在chrome中访问相应的资源,并发现需要权限验证。客户端中的访问应该是一种具有许可权的cookie或令牌,因此可以直接传递,但不能在外部访问。

总结一下

我希望这种分析可以给您一些启发或帮助。如果您有更多内部信息,请告知我有关本文的误解,并寻求建议。

1.《英雄联盟lcu 英雄联盟lcu资格领取》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《英雄联盟lcu 英雄联盟lcu资格领取》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/tiyu/292652.html