获取英雄或者皮肤详细信息,这个消息的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文件,这个文件里就是对应的英雄或者皮肤的配置数据。而我们获取的到数据格式如下: 我们可以看到,上面英雄的图片,声音资源都是通过 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,所以能直接通过,而外面是无法访问到的。 总结 (责任编辑:本港台直播) |