NodeJS + Cluster + Socket.IO如何正确创建游戏室?

时间:2016-10-15 23:29:03

标签: node.js redis socket.io node-cluster

我正在制作一个简单的游戏引擎,它实现了房间操作。

我在思考很多,但仍然怀疑我是否以有效的方式制作房间。

这是场景。

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 个答案:

答案 0 :(得分:1)

您需要原子操作:将所有这4个步骤放入事务中。使用Redis,您可以使用TransactionLua 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脚本以原子方式执行,因此在我们将所有用户从静态房间移动到动态房间之前,没有其他用户可以加入静态房间。

答案 1 :(得分:0)

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

相关问题