Giocatori automatici / in coda


8

Sto usando Node.js e Redis. Sto cercando di trovare un modo affidabile per automatizzare i giocatori. C'è un server corrispondente e quindi più server di gioco impostati.

Di seguito è ciò che devo avere successo:

  1. Il giocatore invia la richiesta di partecipazione con il tipo di gioco (piccolo / medio ecc.)
  2. Il server corrispondente aggiunge il giocatore al tipo di gioco corrente in attesa di giocatori
  3. Il server di gioco invia al giocatore l'ID del gioco

Attualmente ho implementato questo come segue:

  1. Il server corrispondente ascolta il gioco: coda: piccola usando BRPOP
  2. Verifica se esiste il gioco: coda: piccolo: id = id
  3. Verifica se il gioco: id: la lunghezza degli utenti è <= 6 (numero massimo di giocatori)
  4. Aggiunge il giocatore al gioco: id: elenco utenti se lo è
  5. Se la lunghezza del gioco ora è 6, rimuove il gioco: coda: piccola: id

Se il server corrispondente trova game: queue: small: id mancante, fa come segue:

  1. Gioco INCR: nextGameId
  2. Imposta il gioco: coda: piccola: id per l'ID precedentemente generato
  3. Aggiunge l'ID del gioco al gioco: coda: in attesa

I server di gioco attendono l'utilizzo di BRPOP per i nuovi giochi. Quando ne ottengono uno, attendono che il gioco abbia un minimo di 2 utenti, quindi avviano un timer. Se non si riempiono in quel momento, iniziano con gli utenti che hanno e successivamente rimuovono il gioco: coda: piccolo: id (costringendo così il matchmaker a richiedere un nuovo gioco).

Mentre il mio metodo funziona, non sono convinto che funzionerà bene in produzione e sembra molto contorto. Vedo il potenziale per i seguenti problemi:

  • Il server di gioco si arresta in modo anomalo dopo aver accettato l'ID del gioco dalla lista di attesa e gli utenti vengono aggiunti al gioco: id: utenti ma non accade nulla con loro (l'incidente stesso non è un problema, ma gli utenti che continuano ad essere aggiunti a quella coda di giochi sono )
  • Se un utente si disconnette e il gioco non è stato avviato, il server di gioco rimuoverà l'utente dal gioco: id: elenco utenti. Mentre è in procinto di farlo, il server di matchmaking potrebbe aggiungere un utente all'elenco e pensare che il gioco sia pieno, rimuovendolo così dalla coda.

Il mio pensiero iniziale era di passare a una singola coda di utenti in attesa di un tipo di gioco. Tuttavia, ciò presenta ulteriori problemi:

  • Se il server a cui gli utenti si connettono si arresta in modo anomalo, non rimuoverà l'utente dalla coda, lasciando così l'utente a entrare in un gioco quando non esiste. Potrei usare set ordinati per memorizzare il tempo della richiesta e fare in modo che il sondaggio del client venga restituito fino a quando non viene restituito un ID gioco, ma ciò significherebbe che non ho idea di quanto tempo quel client ha atteso e quindi non so se avviare il gioco con meno utenti.
  • Senza mettere gli utenti in un gioco, non hanno la possibilità di vedere a cosa si sono uniti gli utenti, né la possibilità di chattare con gli utenti in attesa (poiché ciò richiede un ID di gioco).

Nessuno dei modi in cui l'ho impostato sembra giusto, quindi speravo che qualcuno potesse essere in grado di offrire alcuni suggerimenti migliori. Ho davvero bisogno di mantenere separati i server di gioco e i server di matchmaking al fine di farli crescere come richiesto.


Il problema del database che ho risolto qui: stackoverflow.com/questions/15172556/…
Chris Evans

In Controlla se game: queue: small: id = id esiste , come si ottiene l'ID?
Rayon,

Risposte:


1

Il tuo primo e principale errore è quello di utilizzare un database per una coda live, che i dati sono molto meglio archiviati nella memoria di processo nel processo di matchmaking. Lascia che i processi comunichino direttamente tra loro. Quindi è anche quasi costretto a te che è l'unica responsabilità del server di matchmaking rimuovere i giocatori dalla coda quando vengono messi in gioco, come dovrebbe essere.

Più in generale sul matchmaking, ritarda le decisioni su quali partite esatte fare fino al punto in cui inizia la partita, se hai 3 giocatori che si adattano a una partita a 4 giocatori, non decidere che devono giocare quel tipo di gioco prima che ci sia anche un quarto giocatore, potrebbe volerci molto tempo prima che arrivi quel giocatore, e alcuni di loro potrebbero smettere di aspettare nel frattempo. Un'implementazione decente per questo è quella di avere una coda per ogni tipo di gioco e mettere ogni giocatore in tutte le code corrispondenti alla sua richiesta, quindi quando una coda è piena, avvia il gioco e rimuovi i giocatori coinvolti da tutte le loro code.


Stavo usando Redis per gestire bene le code. Inizialmente gestivo il matchmaking all'interno del server stesso e ha funzionato molto bene, ma ho riscontrato due problemi con questo approccio: non sono riuscito a trovare un modo per ridimensionarlo e in secondo luogo come il server richiede un nuovo gioco per avviarsi su un altro server. Potrebbe inviare un messaggio a tutti loro ma il carico non sarebbe bilanciato?
Chris Evans,

1
@ChrisEvans Non dovresti preoccuparti troppo del ridimensionamento, un semplice processo di matchmaking può gestire migliaia di iniziazioni di gioco al secondo. Se solo lo codifichi bene non avrai bisogno del matchmaking per scalare a più processi, anche se ottieni milioni di clienti. Per quanto riguarda il bilanciamento del carico sui server di gioco, un semplice approccio round robin in cui ciascun server di gioco ottiene a sua volta un nuovo gioco è abbastanza efficace se i server sono generalmente in grado di gestire un gran numero di giochi ciascuno. Altrimenti puoi periodicamente chiedere ai server di gioco quanto sono impegnati, non deve succedere una volta per nuova partita.
aaaaaaaaaaaa
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.