本系列所有文章:手机游戏开发框架设计(前言)


包管理中心

包管理中心是整个配置管理中心的基础,所以与客户端有关的配置都是基于包管理的。

包管理中心可配置每个包的 启动公告 ,实现 停服维护管理 ,这与服务器是否真正关闭无关。

包管理中心还能够提供给客户端需要的服务器列表,实现 服务器故障灵活切换

包管理中心按照每个客户端包提供不同的配置信息,使客户端能够实现以包和渠道为单位的细粒度配置。

[TOC]

配置依赖

在新的客户端开发构架中, 所有 的配置信息,都是从配置中心获取的。这里的 所有 包括:

  • 客户端要连接的服务器和端口号
  • 客户端运行在哪个平台之上
  • 客户端接入的 SDK 需要的信息(例如 talkdata 需要传递 tdid)
  • 客户端用来证明自己属于哪个渠道的信息
  • 客户端在支付的时候需要提供给第三方的信息(例如 IAB 和 IAP 中提供的证明自己账户的 appkey)
  • 其他需要的信息

为了做到这一点,客户端需要两个值来表明自己的身份,还需要一个 API 地址来获取配置信息:


Package ID

证明 你妈是你妈 的唯一身份标识,且不重复


Version

表明包的版本号,用于 在线升级(TODO)


Config API

配置 API 地址,API 依赖上面两个值来查找配置信息。例如:http://yoursite/api/config/

这种架构,能够保证客户端的所有信息(版本信息和包ID除外)都是可以修改的,避免了包发出去之后出现配置错误而无法解决的问题。

为了保证信息的安全(不被第三方随意获取到),需要增加一些附加验证信息,此处暂不讨论。

包管理的两层架构

上面已经提到过,包管理中心是整个配置管理中心的基础。若无法区分包,则 支付中心(TODO)版本管理中心(TODO) 都没有基础, 支付(TODO)在线升级(TODO) 则更加无法完成。

包管理仅有两层结构,这是为了避免层级过多导致的混乱。从现有的发行方式看来,两层结构已经足以解决 运营渠道 的所有问题。

第一层结构是 运营渠道 ,我们使用 Channel ID 来指代它。


Channel ID

用来指定特定的 运营渠道 。每个渠道都有一个唯一的 Channel ID。例如 中国移动 是我们的一个渠道,我们可以使用 CMCC 来代表它。

第二层结构是 。我们使用 Package ID 来指代它。

为了推广,一个运营渠道大多数情况下都不会只有一个包,两个包之间只要有任何信息不同,就应该单独分包。每个包都要分配不同的 Package ID

在客户端仅保存了 Package ID ,不必保存 Channel ID 。这是因为 [Config API][#configapi] 可以根据 Package ID 查询到 Channel ID

在每个 Package ID 之下,可以配置不同的信息。根据 Package ID 的不同,这个包的配置也不同。简单的结构就是如此:

name
1
2
3
4
5
6
7
8
9
10
11
12

digraph packagecentersimple {
graph[rankdir="LR",label="包管理的两层架构(略图)"]
node[shape="box",fillcolor="white",color="black"]

channel[label="Channel ID", shape="doubleoctagon"]

pid[label="Package ID"]
config[label="配置信息"]

channel -> pid -> config
}

Graphviz chart draft_2-packagecentersimple-0.png

那么配置信息有哪些呢?在 配置依赖 中已经进行过简单介绍。在这里详细进行分类:


SDK Config

我们接入的 SDK 需要客户端告诉它们一些值,这些值若嵌入到客户端则不方便修改,放在配置中心则不然。


Platform

客户端运行在何种平台之上。根据目前的运营状态,可能涉及到的所有平台如下:

  • Android
  • Windows
  • iOS
  • iOS Jailbreak
  • Web

每个 Package ID ,仅能对应一个 Platform 。即使是同样的名称,同样的打包配置(这种可能性并不高),在不同平台上的两个包,也应该使用不同的 Package ID


Server Info

这个包要连接的服务器的信息。这些信息可能包括服务器 IP 地址、端口号、服务器名称等等。

我们可以根据包的不同为它分配不同的服务器地址,这种设计为 分服分区 提供了便利。

这里仅包含一些通用配置。支付配置信息和版本配置信息都依赖 包管理的两层架构 ,它们的详细配置信息的说明,见相关章节。

详细的关系示意图:

name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

digraph package2tiers {
graph[rankdir="LR",label="包管理的两层架构(详图)"]
node[shape="box",fillcolor="white",color="black"]

channel[label="Channel ID", shape="doubleoctagon"]

pid[label="Package ID"]
sdk[label="SDK Config"]
plat[label="Platform"]
si[label="Server Info"]

{
node[shape="Mdiamond"]
Android
Windows
iOS
ij[label="iOS Jailbreak"]
Web
}

channel -> pid
pid -> { sdk plat si "更多..." }
plat -> { Android Windows iOS ij Web }
si -> { "服务器IP" "服务器端口" "服务器名称" }
}

Graphviz chart draft_2-package2tiers-1.png

游戏管理

同时可能有多个游戏处于包管理系统之中,我们使用 Game ID 来处理这种情况。


Game ID

用于区分游戏的身份,每个游戏的 Game ID 都是唯一的。

Game IDChannel ID 既可以是上下级关系,也可以是平级关系。

对于上下级关系,以 Game ID 作为根节点,在根节点下选择可用的 Channel ID ,再在 Channel ID 之下建立 Package IDChannel ID 是允许重用的。

name
1
2
3
4
5
6
7
8
9
10

digraph relation1 {
graph[rankdir="LR",label="上下级关系"]

gid[label="Game ID",shape="doubleoctagon"]
cid[label="Channel ID",shape="box"]
pid[label="Package ID",shape="box"]

gid -> cid -> pid
}

Relation1

对于平级关系, Game ID 可以作为 Package ID 的一个属性存在。也就是说在建立 Package ID 的时候,选择其属于哪一个 Game ID

这种关系具体如何选择,取决于数据库如何设计。

name
1
2
3
4
5
6
7
8
9
10
11
12

digraph relation2 {

graph[rankdir="LR",label="平级关系"]

gid[label="Game ID",shape="doubleoctagon"]
cid[label="Channel ID",shape="doubleoctagon"]
pid[label="Package ID",shape="box"]

gid -> pid
cid -> pid
}

Relation2

配置继承

对于 Channel ID 相同的包来说,它们的大多数配置可能都是相同的。为了避免输入时的冗余和错误,配置中心有一套继承机制。简述如下:

  1. Channel ID 级别进行配置,其中的所有配置自动继承给 Package ID
  2. Package ID 级别的配置的优先级更高,允许其在继承来的配置的基础上进行覆盖、删除和增加。

安全性和可靠性

可靠性上要考虑的因素:

  1. 所有的游戏客户端启动的时候都会访问包管理中心;
  2. 若包管理中心不工作,则所有的游戏客户端都无法正常工作;
  3. 游戏的配置要考虑性能和速度。

安全性上要考虑的因素:

  1. 除我们自己的客户端或者处于调试状态外,Config API 不允许直接访问;
  2. 需要一些附加的验证信息对客户端的合法性进行验证。

(本文完)

留言