2010-07-28 14 views
9

Estoy escribiendo un servidor de juegos para un juego por turnos en Java. Estos son los hechos:Qué protocolo elegir para un servidor de juegos por turnos

  • La velocidad del juego es lento, por lo que los clientes necesitan para enviar datos digamos que cada 8 segundos, y que los datos es que la mayoría de las veces sólo una pequeña actualización incremental (algunas decenas de bytes), aparte de situaciones como unirse al juego o enumerar juegos disponibles, etc.
  • El servidor debe admitir una gran cantidad de jugadores que, digamos 1000, que jueguen uno de los cientos de juegos
  • Cuando el jugador da vuelta , otros jugadores en el mismo juego deben ser notificados del movimiento. La cantidad máxima de jugadores en el juego es de alrededor de 10

En primer lugar, excluí UDP de mi lista de opciones porque necesito un protocolo confiable porque en raras ocasiones necesito enviar algunos datos que no caben en uno paquete y no quiero molestarme con la fusión de paquetes y cosas similares, el seguimiento del orden de los paquetes recibidos y otras cosas de bajo nivel.

Entonces el dilema es si usar TCP o HTTP.

intento TCP # 1

La conexión desde el cliente al servidor (y viceversa) se abre todo el tiempo. De esta manera, cuando un jugador hace un movimiento, el servidor puede notificar fácilmente a otros jugadores en el juego que se realizó el movimiento. Lo principal que me molesta con este enfoque es si es aconsejable o incluso posible tener hasta 1000 conexiones y tomas de corriente abiertas todo el tiempo.

intento TCP # 2

la alternativa que pensé es decir, a utilizar para establecer una conexión separada/hembra en cada petición de un cliente. Un cliente abriría una conexión, enviaría algunos datos pequeños al servidor y cerraría esa conexión. Con este enfoque, puedo tener un grupo de subprocesos de tamaño fijo de digamos 10 y procesar las solicitudes del cliente en cada subproceso por separado para que haya, como máximo, 10 connectinos/sockets abiertos en cualquier momento. Pero hay dos cosas que me molestan con este enfoque:

  1. elevado coste de abrir/cerrar la conexión con el cliente
  2. la forma de notificar a otros jugadores en el juego, ya que la conexión con ellos es más probable cerrada . Cada uno de ellos debería en ese caso "sondear" el servidor para la actualización, digamos cada segundo.

¿Cuál es el costo de establecer un socket/conexión TCP? ¿Es esta una operación costosa o esto se hace solo en unos pocos ms (o menos)?

HTTP

  1. Habría un montón de gastos generales si que sería el envío de un nuevo GET/POST sólo para enviar unos pocos bytes?
  2. ¿Puedo mantener 1000 conexiones HTTP a clientes simultáneamente y luego usar AJAX o cosas similares para reducir sobrecarga?En ese caso, ¿tendría 1000 conexiones simultáneas un problema significativo con respecto al ancho de banda ?

Estoy abierto a sugerencias/consejos de cualquier tipo.

+0

sobre # 2: Usted tiene que autenticar al jugador cada vez que se establece la conexión ... Este proceso puede ser lento, así !? – opatut

+0

¿Están el cliente y el servidor escritos en Java? – Kylotan

+0

Hay varios clientes, uno de los cuales está en Java, pero estoy buscando una solución general. – eold

Respuesta

5

Solo para su información: HTTP es TCP. Un protocolo específico que usa TCP, es decir. HTTP se basa en TCP, al igual que TCP está basado en IP, etc. Así que realmente su elección es entre HTTP sobre TCP o un protocolo personalizado sobre TCP. Tienes razón en que el UDP es un mal partido aquí.

Si está escribiendo el servidor usted mismo, muchos de los beneficios del uso de HTTP desaparecen. El principal beneficio de HTTP es que ya hay servidores altamente optimizados disponibles para que pueda usarlo como un sistema RPC simple y efectivo. Pero si está escribiendo el servidor usted mismo no es probable que alcance la eficiencia de los gustos de Apache, por lo que debe preguntarse por qué no elegiría simplemente un protocolo más simple de usar. Además, piratear la naturaleza de solo extracción de HTTP parece ser el camino equivocado.

Con esto en mente, usaría un protocolo más liviano sobre TCP. Obtiene más control sobre las conexiones y puede notificar a los clientes interesados ​​sobre las actualizaciones sin que tengan que solicitar cambios.También puede perder la sobrecarga de solicitud/respuesta HTTP, que en su mayoría es superflua. En su lugar, puede utilizar un protocolo a medida bastante simple, tal vez basado en XML o JSON, o tal vez uno de los métodos RPC existentes disponibles.

0

El establecimiento de un socket TCP es una operación bastante barata. De hecho, el modelo HTTP general es hacer justamente esto. Nunca deberías mantener las tomas HTTP abiertas continuamente. Llamadas Ajax, llamadas HTTP, están diseñadas para abrirse y cerrarse lo más rápido posible para que se pueda gestionar la siguiente solicitud.

No veo por qué el diseño de sondeo no sería ideal aquí. Encuesta cuando el usuario deja una instancia de un juego a la lista de juegos principal para el estado actual. Encuesta cada 15 segundos más o menos cuando el usuario está en la lista principal de juegos. Asegúrese de que el servidor maneje esta encuesta rápidamente, rápido, menos de un milisegundo si es posible.

Muchos servidores web tienen un límite estricto de 256 conexiones a la vez, aunque recientemente he visto esto en 1024 en algunos servidores. De todos modos, nunca deberías acercarte a este límite. Si su software está optimizado para la velocidad, ninguna conexión debería abrirse durante más de un milisegundo o dos, y no debería haber forma de acercarse siquiera a la cantidad de usuarios necesarios para usar 256 enchufes.

El único problema de velocidad aquí es cuánto tiempo lleva el software de su servidor realizar realmente las consultas encuestadas. La sobrecarga de establecer el socket y cerrarlo no es nada junto a la sobrecarga del código del lado del servidor que usted escribe.

1

Se supone que un servidor puede tener alrededor de 20,000 zócalos abiertos al mismo tiempo. Si decide usar http, puede usar las nuevas funciones de cometa de tomcat 6+ o embarcadero 6+, de lo contrario, se asignará un hilo a cada solicitud.

3

Veo que mira el "nivel bajo". ¿Has intentado usar algo en el nivel superior, algo así como http://code.google.com/p/kryonet/ (también desarrollado para juegos)? (y encontró tal vez un mal rendimiento?)

Creo que los resultados entregados por KryoNet son bastante buenos y es muy rápido para programar con su API.

1

HTTP EN MIO. Podrás pasar por cualquier proxy. La autenticación se puede hacer de manera simple y una vez con sesiones HTTP o cookies.

No se preocupe por las capacidades del servidor: la mayoría de los servidores modernos pueden manejar miles de clientes concurrentes.

0

sólo tiene que utilizar sockets TCP, una conexión persistente para cada cliente, junto con un hilo que hacer E/S. La sobrecarga de subprocesos no es demasiado alta (Linux asigna 48k de forma predeterminada para nuevas pilas, por lo que esto requeriría 48 megas para clientes de 1k, Windows asigna 2k de IIRC), su código será mucho más limpio y fácil de seguir, y usted automáticamente escalar con núcleos de CPU. Si le preocupan los firewalls, investigue HTTP CONNECT y HTML 5 WebSockets.

0

Sugeriría que si está haciendo un juego de turnos basado en turnos con paquetes de juego bastante pequeños (< 50K), debería considerar usar XMPP/Jabber. Aquí están algunas de las razones por qué creo que

  • protocolo de nivel superior (XML) como HTTP en el que no tiene que tratar con los bits y bytes si no quiere.

  • incorporado que la presencia, vestíbulo (con MUC), mecanismo de pubsub, gestión de usuario/autenticación, chat, etc. La lista es interminable ...

  • no tiene que preocuparse de escribir un servidor escalable el tuyo La mayoría de los servidores de Jabber admiten complementos. Simplemente escriba el complemento y deje que el servidor lo escale; un poco como un servidor HTTP

  • XMPP es un protocolo extensible. Puede llevar los datos de su juego como parte de una carga de chat. Firewall amable y la mayoría de los servidores de soporte BOSH

  • Cerca en tiempo real y bastante fiable.

  • cliente de código libre y abierto (golpear) y el servidor (Openfire) - en Java

1

Su "Intento # 1" está bien - no hay nada de malo en tener 1.000 conexiones abiertas (no es raro para que un único servidor IRC tenga más de 100.000 conexiones TCP abiertas simultáneas).

(Es posible que deba ajustar algunos ajustes del sistema operativo a medida que se acerca a ese número; por ejemplo, UNIX suele tener un límite predeterminado de archivo abierto por proceso, pero es lo suficientemente simple como para cambiar).

Cuestiones relacionadas