2016-10-15 1 views
0

Ich mache eine einfache Spiel-Engine, die Raummanipulation implementiert.NodeJS + Cluster + Socket.IO, wie Spielräume richtig erstellen?

Ich habe viel nachgedacht und habe immer noch Zweifel, dass ich Räume nicht in der gültigen Weise mache.

Hier ist das Szenario.

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.

Also, wenn wir laufen diese in mehreren Instanzen und lassen Sie uns sagen, dass wir für zwei Benutzer auf jemanden warten.

2 Benutzer betreten den statischen Raum -> neuen Raum erstellen (in Redis) -> geben Sie diese zwei Spieler in diesen Raum ein (abonnieren) -> diese Spieler veranlassen, den statischen Raum zu verlassen (Warteschlangen-ähnliches System).

Nun, was ich denke, ist ein Problem.

2 Benutzer betreten den statischen Raum -> vor dem Erstellen eines neuen Raumes, ein anderer Spieler verbindet den statischen Raum (unterschiedliche Knoteninstanz) -> neuen Raum erstellen -> zwei Spieler dorthin bewegen -> andere Instanz denkt immer noch, dass genug Benutzer vorhanden sind neues Zimmer -> etwas Seltsames passiert.

Ist das korrekt? Wie soll ich den Queue Style Room implementieren?

Antwort

1

Sie benötigen atomare Operationen: setzen Sie alle diese 4 Schritte in eine Transaktion. Mit Redis können Sie entweder Transaction oder Lua Scripting verwenden, um dies zu erreichen.

Mit lua scripting, können Sie ein Skript wie diese:

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

Da das Lua Script atomar ausführt, kann kein anderer Benutzer den statischen Raum beitreten, bevor wir alle Benutzer aus dem statischen Raum dynamisch beenden bewegen Zimmer.

+0

Sie haben absolut Recht, aber ich möchte eines wissen, gibt es eine native Javascript-Möglichkeit, diese atomar zu tun? – Nika

+0

Tut mir leid, ich bin nicht vertraut mit Javascript ... –

0

Eine Lösung könnte sein, alle nicht verbundenen Spieler in eine einzige Knoteninstanz einzutragen, die für das Erstellen von Räumen und die Zuweisung von Spielern zu diesen Räumen verantwortlich ist. Sobald sie einem bestimmten Raum zugeordnet sind, leitet er sie an die Knoteninstanz weiter, die für diesen Raum zuständig ist.

+0

Das macht keinen Sinn Knoten Cluster dann zu verwenden. – Nika

+0

Es macht Sinn, weil die erste Instanz nur ein Einstiegspunkt ist. Sobald ein Benutzer in einem Raum betroffen ist, wird er von einer anderen Instanz im Cluster behandelt. –

+0

Also sollte es Master sein, denke ich? Oder wie kann ich so etwas tun? Ich weiß nicht einmal, auf welcher Knoteninstanz der Client eine Verbindung zu – Nika