关于room_game可热更匹配房间类游戏架构的优化
前言
在用这种架构模式实现中国象棋游戏的过程中,发现之前的设计有些诟病的地方。
- gate和fd没必要暴露给业务层。
- 登录后连接大厅就行,不用强制进房间,这样能适配的业务功能更广泛,进不进房间应该由业务决定,退出房间也一样,退出不代表登出。
- 缺少通用的发消息接口。
- 消息处理函数不够优雅。
- 业务层缺少CMD命令注册入口。
- table缺少主动访问hall大厅和alloc的接口。
优化
新版本的room_game主要针对以上六点做了相关优化。
- 去掉gate,fd 对上层业务的传递,提供发消息的接口。
- 登录仅仅连接大厅,提供桌子的相关操作接口。
- login,hall,table都提供,并且接口保持统一,通用。
- 消息是否转发判断逻辑为,大厅服没有注册处理,转发到桌子服,还没有桌子服,或者桌子服没有处理,视为丢弃消息打印日志即可。
- 提供业务注册CMD消息的入口,并限制命令不可重复注册。
- 提供相关接口。
接口介绍
架构的接口可以分为回调接口和主动调用接口。
回调接口
就是模块挂载的插件需要实现的方法。
登录
init(interface_mgr),初始化。
参数:interface_mgr是主动接口入口。unpack(msg,sz),解包。
参数:msg网络包消息。sz网络包长度。send(gate,fd,packname,pack_body),发包函数。
参数:gate网关服务id。fd连接绑定的id。packname包名。pack_body包内容。check(packname,pack_body),客户端建立连接后,第一条消息应该为登录消息,这里进行登录检查。
参数:packname包名。pack_body包内容。
返回值:
成功返回:player_id玩家id。
失败返回:falseerrorcode失败错误码。errormsg失败消息内容。login_failed(player_id,errcode,errmsg),登录失败。player_id玩家id。errorcode失败错误码。errormsg失败消息内容。
参数传递为check失败或者hall大厅connect连接失败传递的错误码。
login_succ(player_id,login_res),登录成功。player_id玩家id。login_res大厅服返回的登录结果。login_out(player_id)登出,玩家主动登出,或者玩家断线超时了被踢出。player_id玩家id。disconnect(player_id)掉线。player_id玩家id。logining(player_id)正在登录中,正在处理登录消息,通常客户端狂发登录消息导致。player_id玩家id。repeat_login(player_id)重复登录。多连接登录了,此处可以给旧连接发错误码,旧连接将被踢断开。player_id玩家id。`register_cmd
` 注册命令表。
大厅
init(interface_mgr),初始化。
参数:interface_mgr是主动接口入口。unpack(msg,sz),解包。
参数:msg网络包消息。sz网络包长度。send(gate,fd,packname,pack_body),发包函数。
参数:gate网关服务id。fd连接绑定的id。packname包名。pack_body包内容。connect(player_id),连接大厅。
参数:player_id玩家id。
返回值:
不同意连接:falseerrorcode失败错误码。errormsg失败消息内容。
传递到login_faild
同意连接:login_res连接成功内容,将传递到login_succ
disconnect(player_id),掉线。
参数:player_id玩家id。reconnect(player_id),重连。
参数:player_id玩家id。
返回值:与connect相同即可。goout(player_id),登出,也就是agent对象要被删除了。player_id玩家id。register_cmd注册命令表。handle_end消息处理结束。
分配
init(interface_mgr),初始化。
参数:interface_mgr是主动接口入口。match(player_id),匹配。
参数:player_id玩家id。
返回值:
匹配到:尝试进入桌子。table_id
没有匹配到:会尝试创建新桌子。nil
createtable(table_name, table_id, config, create_player_id)创建桌子
参数:table_name桌子名称,也就是mod_config参数里面填的instance_name。table_id桌子唯一id。config桌子在mod_config中的填写的配置。create_player_id创建人,match匹配的创建人没有,表示是系统创建的。entertable(table_id,player_id)玩家进入桌子。
参数:table_id桌子唯一id。player_id玩家id。leavetable(table_id,player_id)离开桌子。
参数:table_id桌子唯一id。player_id玩家id。dismisstable(table_id)解散桌子,所有玩家都离开后,调用。
参数:table_id桌子唯一id。player_id玩家id。tablefull()桌子已满,创建桌子触发
返回值falseerrorcode失败错误码。errormsg失败消息内容。table_not_exists()桌子不存在,进入桌子触发
返回值falseerrorcode失败错误码。errormsg失败消息内容。register_cmd注册命令表。
桌子
init(interface_mgr),初始化。
参数:interface_mgr是主动接口入口。send(gate,fd,packname,pack_body),发包函数。
参数:gate网关服务id。fd连接绑定的id。packname包名。pack_body包内容。table_creator(table_id)桌子创建者。
参数:table_id新建的table_id。
返回值:
table
字段:enter(player_id),进入玩家。
参数:player_id 玩家id。
返回值:
成功:true
失败:falseerrorcode失败错误码。errormsg失败消息内容。
leave(player_id),离开玩家。
参数:player_id 玩家id。
返回值:
成功:true
失败:falseerrorcode失败错误码。errormsg失败消息内容。
disconnect(player_id),玩家掉线。
参数:player_id 玩家id。
reconnect(player_id),重连。
参数:player_id 玩家id。
handle 消息处理表
table
key packname包名
value handle_func(player_id,packname,pack_body)处理函数
参数:player_id玩家id。packname包名。pack_body包内容。
handle_end消息处理结束。register_cmd注册命令表。
主动调用接口
登录
is_online(player_id)是否在线。send_msg(player_id,packname,pack_body)发送消息。send_msg_by_player_list(player_list,packname,pack_body)发送消息给部分玩家。broad_cast_msg(packname,pack_body)广播发送消息。
大厅
is_online(player_id)是否在线。create_join_table(player_id,table_name)创建进入房间。match_join_table(player_id,table_name)匹配进入房间。join_table(player_id,table_name,table_id)进入房间。leave_table(player_id,table_name,table_id)离开桌子。goout(player_id)登出。handle(packname,func)设置消息处理函数。send_msg(player_id,packname,pack_body)发送消息。send_msg_by_player_list(player_list,packname,pack_body)发送消息给部分玩家。broad_cast_msg(packname,pack_body)广播发送消息。get_hall_server_id()获取大厅id。get_alloc_server_id(player_id)获取分配服id。get_table_server_id(player_id)获取桌子服id。get_table_id()获取桌子id。
分配
create_table(table_name) 创建桌子。dismisstable(table_id) 销毁桌子。get_empty_map()获取空桌列表。
桌子
new(table_id)创建绑定table_id的接口对象。kick_out_all()踢出该桌子所有玩家。kick_player(player_id)踢出单个玩家。send_msg(player_id,packname,pack_body)发送消息。send_msg_by_player_list(player_list,packname,pack_body)发送消息给部分玩家。broad_cast_msg(packname,pack_body)广播发送消息。send_hall(player_id,cmd,...)用send的方式给大厅发消息。call_hall(player_id,cmd,...)用call的方式给大厅发消息。send_alloc(cmd,...)用send的方式给分配服发消息。call_alloc(cmd,...)用call的方式给分配服发消息。
总结
通过优化架构,提高了架构易用性,扩展性和使用便捷性。