关于room_game可热更分配房间类游戏架构
简介
room_game是skynet_fly基于热更系统实现的分配房间类游戏架构。
room_game注重什么:
* 框架与业务解耦。
* 可热更。
* 协议使用自由,目前提供protobuf和json协议。
* socket和websocket通用。
架构介绍
room_game架构由多个skynet服务组成,由gate网关,login登录服,hall大厅服,alloc分配服,room房间服组成。
room_game针对玩家登录、登出事情处理好了服务之间消息处理。预留了相关事件的接口,开发新游戏只需要针对相关接口做对应的处理就行。
gate网关
room_game可以选择使用gate或者ws_gate,gate用的是skynet原生的gate,ws_gate是skynet_fly基于skynet的websocket实现的。
ws_gate是基于master/slave模式,slave可以开多个,可以充分利用多核优势。login登录服
登录服依赖 share_config_m配置。
下面是写在load_mods.lua的配置。
登录服是不支持热更的,因为agent是跟player_id绑定的,登录需要一直记录player_id和对应管理agent的hall大厅对重连做保障。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18--共享配置
share_config_m = {
launch_seq = 1,
launch_num = 1,
default_arg = {
--room_game_login用的配置
room_game_login = {
gateservice = "gate", --gate 或者 wsgate
--gate连接配置
gateconf = {
address = '127.0.0.1',
port = 8001,
maxclient = 2048,
},
login_plug = "login_plug",
}
}
},其中
login_plug
表示登录服需要引入的登录插件。
其中插件需要实现全部接口,不然会被assert断言导致启动失败。1
2
3
4
5
6
7
8
9
10
11assert(login_plug.init,"login_plug not init") --初始化
assert(login_plug.unpack,"login_plug not unpack") --解包函数
assert(login_plug.check,"login_plug not check") --登录检查
assert(login_plug.login_succ,"login_plug not login_succ") --登录成功
assert(login_plug.login_failed,"login_plug not login_failed") --登录失败
assert(login_plug.disconnect,"login_plug not disconnect") --掉线
assert(login_plug.login_out,"login_plug not login_out") --登出
assert(login_plug.time_out,"login_plug not time_out") --登录超时时间
assert(login_plug.logining,"login_plug not logining") --正在登录中
assert(login_plug.repeat_login,"login_plug not repeat_login") --重复登录init()
插件可能需要做一些初始化的工作,比如加载pb协议。unpack(msg,sz)
客户端消息解包函数。check(gate,fd,packname,req)
登录检查函数,成功应该返回玩家id,登录失败通常返回nil,errcode,errmsg,errcode,errmsg将传入login_failed中。login_failed(gate,fd,player_id,errcode,errmsg)
登录失败,这里可以给客户端发送登录失败的错误信息。login_succ(gate,fd,player_id,login_res)
登录成功,这里可以给客户端发送登录成功。login_out(player_id)
登出回调。disconnect(gate,fd,player_id)
掉线回调。logining(gate,fd,player_id)
正在登入中。上一个登录请求还没有处理完。repeat_login(gate,fd,player_id)
被挤号。 一般这里通知在其他设备登录。hall大厅服
大厅服可以启动多个,用于管理agent,记录玩家绑定的alloc服务和room服务,保证断线重连可以重回房间。
大厅服支持热更,热更之后的玩家都会登录到新的服务,旧的服务一直维持到该服务中的所有玩家登出。
大厅服配置1
2
3
4
5
6
7
8--大厅服
room_game_hall_m = {
launch_seq = 2,
launch_num = 6,
default_arg = {
hall_plug = "hall_plug",
}
},其中
hall_plug
表示大厅服需要实现的插件接口。
1 |
|
init()
初始化。unpack(msg,sz)
客户端消息解包。dispatch(gate,fd,packname,req,CMD)
处理消息,返回值为true表示大厅已经处理消息,为false,表示需要转发到room房间服去处理。connect(gate,fd,player_id)
连接到大厅。disconnect(gate,fd,player_id)
掉线。reconnect(gate,fd,player_id)
重连。goout(player_id)
登出。alloc分配服
分配服只有一个,我觉得单服设计应该简单一点。
可以热更。热更后,旧的分配服不会再进入玩家了。
分配服配置1
2
3
4
5
6
7
8
9--分配服
room_game_alloc_m = {
launch_seq = 3,
launch_num = 1,
default_arg = {
alloc_plug = "alloc_plug",
MAX_TABLES = 10000,
}
},其中MAX_TABLES是最大桌子数量,alloc用了简单轮询机制去给room服分配房间。
alloc_plug表示分配服需要实现的插件接口。
1 |
|
init()
初始化.match(player_id)
匹配桌子。返回桌子id匹配成功,返回nil匹配失败,失败之后会去创建桌子,如果桌子爆满会调用tablefull接口。createtable(table_id)
创建了一个桌子。entertable(table_id,player_id)
玩家进入桌子。leavetable(table_id,player_id)
玩家离开桌子。dismisstable(table_id)
桌子被销毁了。tablefull()
桌子已经满了。 这里可以nil,errcode,errmsg,会被登录服接住,之后出现在登录服的login_failed接口中。room房间服
可以开多个。
可以热更。
房间服配置。1
2
3
4
5
6
7
8
9
10
11--房间服
room_game_room_m = {
launch_seq = 4,
launch_num = 6,
default_arg = {
room_plug = "room_plug",
room_conf = {
player_num = 2,
}
}
},room_plug表示房间服需要实现的插件接口。
1 |
|
init()
初始化table_creator(table_id,room_conf,ROOM_CMD)
创建游戏桌子,返回一个游戏桌子闭包,提供基础接口处理。table.enter(player)
玩家桌下。table.leave(player)
玩家离开。table.disconnect(player)
玩家掉线。table.reconnect(player)
玩家重连。table.handler(player,packname,req)
消息处理。