代码之家  ›  专栏  ›  技术社区  ›  Nika

NodeJS+集群+套接字。IO如何正确创建游戏室?

  •  0
  • Nika  · 技术社区  · 8 年前

    这是一个场景。

    1) There's one static room, where users are able to 'register'. 2) after certain number of users are registered, it should create dynamic room and put these certain number of users in that room and make them quit the static room.

    因此,如果我们在多个实例中运行它,假设我们正在等待2个用户。

    2个用户加入静态房间->创建新房间(在redis中)->在该房间中输入这两个玩家(订阅)->让这些玩家离开静态空间(队列式系统)。

    现在我认为这是一个问题。

    2个用户加入静态房间->在创建新房间之前,另一个玩家加入静态房间(不同节点实例)->创建新房间->将两个玩家移动到那里->另一个实例仍然认为有足够的用户创建新房间->奇怪的事情发生了。

    这是正确的吗?如何实现队列样式的房间?

    2 回复  |  直到 8 年前
        1
  •  1
  •   for_stack    8 年前

    您需要原子操作:将所有这4个步骤放入事务中。使用Redis,您可以使用 Transaction Lua Scripting 为了实现它。

    使用lua脚本,您可以使用如下脚本:

    -- add new user to static room
    redis.call('lpush', 'static_room', ARGV[1])
    
    -- if the number of static room reaches the limit
    local num = redis.call('llen', 'static_room')
    if num == 2  then
        -- get the room number for a new dynamic room
        local new_dynamic_room_num = redis.call('incr', 'dynamic_room');
        local dynamic_room = 'dynamic_room' .. new_dynamic_room_num
    
        -- move all users from static room to dynamic room
        while true do
            local num = redis.call('llen', 'static_room')
    
            if num == 0 then break end
    
            redis.call('rpoplpush', 'static_room', dynamic_room)
        end
    end
    

    由于lua脚本以原子方式执行,所以在我们完成将所有用户从静态房间移动到动态房间之前,没有其他用户可以加入静态房间。

        2
  •  0
  •   Pascal Le Merrer    8 年前

    一种解决方案是让所有未连接的玩家进入一个唯一的节点实例,该节点实例负责创建房间并将玩家分配到这些房间。然后,一旦将它们分配给给定的房间,它就会将它们重定向到负责该房间的节点实例。