2010-07-28 19 views
9

Sto scrivendo un server di gioco per un gioco a turni in Java. Questi sono i fatti:Quale protocollo scegliere per un server di gioco a turni

  • La velocità del gioco è lento, quindi i clienti devono inviare i dati diciamo ogni 8 secondi, e che i dati sono il più delle volte solo un piccolo aggiornamento incrementale (poche decine di byte), a parte situazioni come unirsi al gioco o elencare giochi disponibili ecc.
  • Il server deve supportare un gran numero di giocatori che, diciamo 1000, che giocano una delle poche centinaia di giochi
  • Quando il giocatore fa un turno , gli altri giocatori nella stessa partita devono essere informati della mossa. Il numero massimo di giocatori nel gioco è di circa 10

Prima di tutto, ho escluso UDP dal mio elenco di opzioni in quanto ho bisogno di un protocollo affidabile perché in rare situazioni ho davvero bisogno di inviare alcuni dati che non possono stare in uno pacchetto e non voglio preoccuparmi di unire pacchetti e cose simili, rintracciando l'ordine dei pacchetti arrivati ​​e altre cose di basso livello.

Quindi il dilemma è se utilizzare TCP o HTTP.

tentativo TCP # 1

La connessione dal client al server (e viceversa) è aperto tutto il tempo. In questo modo, quando un giocatore fa una mossa, il server può facilmente notificare agli altri giocatori nel gioco quale mossa è stata fatta. La cosa principale che mi dà fastidio con questo approccio è se sia consigliabile o addirittura possibile avere fino a 1000 connessioni e socket aperti tutto il tempo?

tentativo TCP # 2

L'alternativa che ho pensato di è, da utilizzare per stabilire una connessione separata/presa su ogni richiesta da un client. Un client aprirà una connessione, invierà alcuni piccoli dati al server e chiuderà quella connessione. Con questo approccio, posso avere un pool di thread di dimensioni fisse di diciamo 10 ed elaborare le richieste del client in ogni thread separatamente in modo che ci siano al massimo 10 connessioni/socket aperti in qualsiasi momento. Ma ci sono due cose che mi dà fastidio con questo approccio:

  1. expensiveness di apertura/chiusura della connessione al client
  2. il modo di notificare altri giocatori nel gioco, dal momento che la connessione a loro è probabilmente chiuso . Ognuno di loro dovrebbe in quel caso il server "poll" per l'aggiornamento diciamo ogni secondo.

Qual è il costo di stabilire un socket/connessione TCP? Si tratta di un'operazione costosa o viene eseguita in pochi ms (o meno)?

HTTP

  1. Ci sarebbe un sacco di overhead se sarei invio di un nuovo GET/POST solo per inviare alcuni byte?
  2. Posso mantenere 1000 connessioni HTTP a client contemporaneamente e quindi utilizzare AJAX o cose simili per ridurre l'overhead ?In tal caso, le connessioni simultanee 1000 rappresentano un problema significativo relativo alla larghezza di banda /prestazioni?

Sono aperto a suggerimenti/consigli di qualsiasi tipo.

+0

about # 2: Dovrai autenticare il lettore ogni volta che viene stabilita la connessione ... Anche questo potrebbe essere lento !? – opatut

+0

Sia il client che il server sono scritti in Java? – Kylotan

+0

Ci sono diversi client, uno dei quali è in Java, ma sto cercando una soluzione generale. – eold

risposta

5

Per vostra informazione: HTTP è TCP. Un protocollo specifico che usa TCP, cioè. L'HTTP è basato su TCP, proprio come TCP è basato su IP, ecc. Quindi la tua scelta è tra HTTP su TCP o un protocollo personalizzato su TCP. Hai ragione che l'UDP è una partita scadente qui.

Se si scrive da soli il server, molti dei vantaggi dell'utilizzo di HTTP vanno via. Il vantaggio principale di HTTP è che sono già disponibili server altamente ottimizzati per poterli utilizzare come un sistema RPC semplice ed efficace. Ma se stai scrivendo il server da solo non è probabile che tu raggiunga l'efficienza di Apache, quindi devi chiedere perché non sceglieresti un protocollo più semplice da usare? Inoltre, l'hacking attorno alla natura pull-only di HTTP sembrerebbe essere la strada sbagliata.

Con questo in mente, vorrei solo utilizzare un protocollo più leggero su TCP. Ottieni un maggiore controllo sulle connessioni e puoi avvisare gli utenti interessati degli aggiornamenti senza richiedere loro di eseguire il polling delle modifiche.Puoi anche perdere il sovraccarico di richieste/risposte HTTP, che è per lo più superfluo nel tuo caso. Puoi invece utilizzare un protocollo su misura piuttosto semplice, magari basato su XML o JSON, o forse uno dei metodi RPC esistenti disponibili.

0

Stabilire un socket TCP è un'operazione abbastanza economica. In effetti, il modello HTTP generale deve fare proprio questo. Non dovresti mai tenere i socket HTTP aperti continuamente. Chiamate Ajax, chiamate HTTP, queste sono progettate per essere aperte e chiuse il più rapidamente possibile in modo che la richiesta successiva possa essere gestita.

Non vedo perché il design del sondaggio non sarebbe ideale qui. Sondare quando l'utente lascia un'istanza di un gioco nella lista dei giochi principale per lo stato corrente. Sondare ogni 15 secondi circa quando l'utente si trova nella lista dei giochi principale. Assicurati che il server gestisca questo sondaggio rapidamente, velocemente - meno di un millisecondo se possibile.

Molti server Web hanno un limite rigido di 256 connessioni contemporaneamente, anche se recentemente ho visto questo su 1024 su alcuni server. Indipendentemente da ciò, non dovresti mai avvicinarti a questo limite. Se il tuo software è ottimizzato per la velocità, nessuna connessione dovrebbe essere aperta per più di un millisecondo o due, e non ci dovrebbe essere modo di avvicinarsi al numero di utenti richiesti per utilizzare 256 socket.

L'unico problema di velocità qui è il tempo impiegato dal software server per eseguire effettivamente le interrogazioni. Il sovraccarico di stabilire il socket e chiuderlo non è altro che il sovraccarico del codice lato server che scrivi.

1

Un server dovrebbe essere in grado di avere circa 20.000 socket aperti contemporaneamente. Se decidi di utilizzare http, puoi utilizzare le nuove funzionalità di cometa di tomcat 6+ o jetty 6+, altrimenti verrà assegnato un thread a ciascuna richiesta.

3

Vedo che si guarda il "livello basso". Hai provato a utilizzare qualcosa al livello più alto, qualcosa come http://code.google.com/p/kryonet/ (sviluppato anche per i giochi)? (e trovato forse una cattiva prestazione?)

Penso che i risultati forniti da KryoNet siano abbastanza buoni ed è molto veloce da programmare con le loro API.

1

IMHO HTTP. Sarai in grado di passare attraverso qualsiasi proxy. L'autenticazione potrebbe essere semplice e una volta utilizzando sessioni HTTP o cookie.

Non preoccuparti delle funzionalità del server: la maggior parte dei server moderni può gestire migliaia di client concorrenti.

0

Basta usare socket TCP, una connessione permanente per ogni client, insieme a un thread per eseguire I/O. L'overhead del thread non è troppo alto (Linux assegna di default 48k per i nuovi stack, quindi ciò richiederebbe 48 meg per i client 1k, Windows alloca 2k IIRC), il codice sarà molto più pulito e facile da seguire, e sarà auto- scala con core CPU. Se sei preoccupato per i firewall, investiga su HTTP CONNECT e HTML 5 WebSockets.

0

Suggerirei che se si sta facendo un gioco multiplayer a turni con pacchetti di gioco abbastanza piccoli (< 50K), si dovrebbe considerare l'utilizzo di XMPP/Jabber. Ecco alcuni motivi per cui penso

  • Higher protocollo di livello (XML), come HTTP in cui non si ha a che fare con bit e byte se non si vuole.

  • Costruito la sua presenza, lobby (con MUC), meccanismo di PubSub, l'utente/gestione di autenticazione, chat, ecc La lista potrebbe continuare ...

  • non c'è bisogno di preoccuparsi di scrivere un server scalabile te stesso. La maggior parte dei server Jabber supporta i plugin. Basta scrivere il plugin e lasciare che il server lo ridimensiona per te; un po 'come un server HTTP

  • XMPP è un protocollo estensibile. Puoi trasportare i tuoi dati di gioco come parte di un carico di lavoro della chat. Compatibile con il firewall e con la maggior parte dei server BOSH

  • Vicino al tempo reale e abbastanza affidabile.

  • libero e open client di origine (schiaffo) e il server (Openfire) - in Java

1

Il tuo "Tentativo # 1" va bene - non c'è niente di male ad avere 1000 connessioni aperte (non è raro per un singolo server IRC per avere più di 100.000 connessioni TCP aperte simultanee).

(Potreste notare che alcune impostazioni del sistema operativo devono essere ottimizzate non appena ci si avvicina a quel numero, ad esempio gli UNIX di solito hanno un limite predefinito di file aperti per processo attorno a quello, ma è abbastanza semplice da cambiare).

Problemi correlati