关于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
    11
    assert(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
2
3
4
5
6
7
assert(hall_plug.init,"not init")             --初始化
assert(hall_plug.unpack,"not unpack") --解包函数
assert(hall_plug.dispatch,"not dispatch") --消息分发
assert(hall_plug.connect,"not connect") --连接大厅
assert(hall_plug.disconnect,"not disconnect") --掉线
assert(hall_plug.reconnect,"not reconnect") --重连
assert(hall_plug.goout,"not goout") --退出
  • 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
2
3
4
5
6
7
assert(alloc_plug.init,"not alloc init")           --初始化
assert(alloc_plug.match,"not match") --匹配
assert(alloc_plug.tablefull,"not tablefull") --桌子已满
assert(alloc_plug.createtable,"not createtable") --创建桌子
assert(alloc_plug.entertable,"not entertable") --进入桌子
assert(alloc_plug.leavetable,"not leavetable") --离开桌子
assert(alloc_plug.dismisstable,"not dismisstable") --解散桌子
  • 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
2
3
4
5
6
7
8
9
10
assert(room_plug.init,"not room_plug init")                 --初始化
assert(room_plug.table_creator,"not table_creator") --桌子建造者

local tmp_table = room_plug.table_creator(1,g_room_conf,ROOM_CMD)

assert(tmp_table.enter,"table_creator not enter") --坐下
assert(tmp_table.leave,"table_creator not leave") --离开
assert(tmp_table.disconnect,"table_creator not disconnect") --掉线
assert(tmp_table.reconnect,"table_creator not reconnect") --重连
assert(tmp_table.handler,"table_creator not handler") --消息处理
  • 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) 消息处理。

关于room_game可热更分配房间类游戏架构
https://huahua132.github.io/2023/07/22/skynet_fly_ss/room_game/
作者
huahua132
发布于
2023年7月22日
许可协议