2016-10-15 2 views
0

Je crée un moteur de jeu simple, qui implémente la manipulation de la pièce.NodeJS + Cluster + Socket.IO comment créer une salle de jeu correctement?

Je pensais beaucoup et j'ai encore des doutes que je ne suis pas en train de rendre les chambres non valables.

Voici le scénario.

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.

Donc, si nous courons cela dans plusieurs cas et disons que nous attendons pour 2 utilisateurs.

2 utilisateurs rejoignent la salle statique -> créer une nouvelle salle (en redis) -> entrer ces deux joueurs dans cette salle (s'abonner) -> faire que ces joueurs quittent la salle statique (système en file d'attente).

Maintenant, ce que je pense est un problème. 2 utilisateurs rejoignent la salle statique -> avant de créer une nouvelle salle, un autre joueur rejoint la salle statique (instance de nœud différente) -> créer une nouvelle salle -> déplacer deux joueurs -> autre instance pense toujours qu'il y a assez d'utilisateurs pour créer nouvelle pièce -> quelque chose d'étrange arrive.

Est-ce correct? Comment dois-je implémenter la salle de style de file d'attente?

Répondre

1

Vous avez besoin d'opérations atomiques: mettez toutes ces 4 étapes dans une transaction. Avec Redis, vous pouvez utiliser Transaction ou Lua Scripting pour y parvenir.

Avec les scripts Lua, vous pouvez avoir un script comme celui-ci:

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

Depuis le script lua exécute atomiquement, aucun autre utilisateur ne peut se joindre à la salle statique avant de terminer le déplacement tous les utilisateurs de la salle statique dynamique chambre.

+0

Vous avez absolument raison, mais j'aimerais en savoir un, y a-t-il un moyen natif de javascript pour faire ces atomiquement? – Nika

+0

Désolé, je ne suis pas familier avec javascript ... –

0

Une solution pourrait être de faire entrer tous les joueurs non connectés dans une instance de nœud unique, qui est chargée de créer des salles et d'affecter des joueurs à ces salles. Ensuite, une fois qu'ils sont assignés à une pièce donnée, ils les redirigent vers l'instance de noeud en charge de cette pièce.

+0

Cela n'a aucun sens d'utiliser le cluster de nœuds. – Nika

+0

Cela a du sens parce que la première instance est juste un entrypoint. Une fois qu'un utilisateur est affecté à une pièce, il sera géré par une autre instance du cluster. –

+0

Donc, il devrait être maître, je suppose? Ou comment puis-je faire une telle chose, je ne sais même pas sur quel client d'instance de nœud se connecte à – Nika