Nika Nika - 1 month ago 16
Node.js Question

NodeJS + Cluster + Socket.IO how to create game room properly?

I'm making a simple game engine, which implements room manipulation.

I was thinking a lot and still have doubts that I'm making rooms not in the valid way.

Here's the scenario.

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.


So, if we run this in multiple instances and let's say we're waiting for 2 users.

2 users join the static room -> create new room (in redis) -> enter these two players in that room (subscribe) -> make those players to leave static room (queue-like system).

Now what I think is a problem.

2 users join the static room -> before creating new room, one other player joins static room (different node instance) -> create new room -> move two players there -> other instance still thinks there's enough users to create new room -> something weird happens.

Is this correct? How should I implement the queue style room?

Answer

You need atomic operations: put all of these 4 steps into a transaction. With Redis, you can use either Transaction or Lua Scripting to achieve it.

With lua scripting, you can have a script like this:

-- 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

Since the lua script executes atomically, no other user can join the static room before we finish moving all users from the static room to dynamic room.

Comments