2010-11-23 34 views
10

Estoy haciendo un navegador web basado en el juego multijugador. He determinado que los websockets son la mejor forma de manejar las comunicaciones dada su naturaleza en tiempo real. El cliente usa un lienzo HTML5 para renderizar el juego y los websockets para comunicarse con el host.Servidor de juegos PHP, ¿múltiples clientes TCP?

He elegido usar PHP para alojar el juego, ya que parece ser el preferido por los proveedores de hosting. No he usado PHP antes, pero he hecho cosas similares con websockets en Java, pero confiando mucho en multihilo.

He estado viendo algunos tutoriales sobre sockets php con múltiples clientes; pero la mayoría de ellos hace cosas como desviar nuevos procesos para cada cliente. Como tendré un bucle constante en el juego, no creo que sea adecuado.

Lo que estoy tratando de lograr es un medio de asignar puertos a cada cliente mientras se conectan, escuchando nuevos clientes, intercambiando datos con la lista actual de clientes y ejecutando el bucle de juego todos juntos.

Los lugares en los que necesito ayuda son:

  • Cómo encontrar y asignar los puertos a los nuevos clientes, notificar al cliente de ese puerto, y limpiarlo cuando se desconectan.
  • Cómo hacer lo anterior, y todas las demás transacciones de socket, sin bloquear el bucle del juego. Sería aceptable aceptar mensajes de clientes en fragmentos parciales y solo actuar sobre un mensaje completo.

¿Alguien me puede dar algún consejo técnico sobre cómo lograr estos objetivos? No creo que todo esto parezca demasiado pedir de PHP, pero corrígeme si me equivoco.

Algún pseudocódigo de lo que idealmente me gustaría conseguir en el lado del servidor. Ninguna de las funciones debe bloquear: Clientes de matriz;

while(gamerunning) 
{ 
    CheckForNewClients(); 
    GetStatusFromClients(); 
    DoGameUpdate(); 
    SendGameStateToClients(); 
} 

[Actualización] Para todos los interesados, he creado una aplicación dedicada de soporte Web Sockets (específicamente el uso de Java, y la biblioteca de sockets 'TooTallNates' web) en lugar de un servicio web real, ya que parecía tener más sentido, aunque, por cierto, parece que la mayoría de los navegadores web han lanzado sockets web en el contenedor debido a problemas de seguridad.

+1

En caso de que pueda obtener un VPS o algo que le permita ejecutar Node.js en él, le sugiero encarecidamente que tome la ruta del Nodo. Los servidores multijugador en Node.js son pan comido. –

+0

¿No es node.js una solución del lado del cliente para websockets? –

+0

no, nodejs en resumen es muy rápido, eventdriven, javascript en el servidor para escribir servidores. –

Respuesta

5

No recomendaría usar PHP para este tipo de aplicación. PHP no admite oficialmente multihilo y ejecutar un script PHP durante un período de tiempo indefinido (como un servidor) no es realmente una función anunciada.

supuesto, usted podría tratar de hacer historia :)

(por favor, corríjanme si me equivoco)

+2

Tal vez he hecho historia ... He hecho daemons de servidores socket con PHP en el pasado (porque mi empleador hizo cumplir esa tecnología) y no veo cuál es el problema. Funciona muy bien, con un solo proceso o múltiples. – netcoder

+1

Lo mismo aquí, actualmente estoy escribiendo un back-end de juego en PHP (como daemon). Escucha/escribe mensajes a través de una puerta de enlace XMPP. Hasta ahora, funciona muy bien (no muy rápido, pero no puede vencer la usabilidad de PHP). –

+1

@Kendall: No creo que la velocidad sea realmente un problema. También he escrito socket daemons en Java, y PHP supera a la mayoría de ellos en cuanto a la velocidad. Primero, no hay JVM para comenzar. En segundo lugar, PHP está muy cerca de C raw sockets, a diferencia de la capa de socket abstracta de Java. – netcoder

7

Usted realmente necesita para ejecutar un demonio de PHP con el fin de hacerlo de manera eficaz (y NECESITA ser PHP 5.3). Escribí una visión general bastante completa del uso de PHP for daemon processes. Lo que sea que elija, le sugiero que use un sistema de bucle run basado en eventos.

He diseñado una biblioteca básica de RunLoop llamada LooPHP que podría ser útil, especialmente si va a tratar con *_select. Estaría más que feliz de responder cualquier pregunta que tengas al respecto.

EDIT:

En un sistema basado en caso de que no simplemente while una lista de comandos, que reaccionan a un oyente. Por ejemplo ...

En vez de hacer: bucles

while(1) { 
    ... /* listen, react */ 
} /* repeat */ 

Ejecutar el trabajo mediante el registro de escucha (sockets, y otros eventos generadores asincrónicos)

class ReactClass { ... } 

$loop = new LooPHP_EventLoop(new ReactClass); 

//add one time event 
$loop->addEvent(function() { 
    print "This event was called 0.5 second after being added\n"; 
}, 0.5 /* in seconds */); 

//this creates a repeating event, this is called right away and repeats 
$add_event = function() use ($loop, &$add_event) { 
    print "This event is REPEATEDLY called 0.1 every second\n"; 
    $loop->addEvent($add_event, 0.1); 
}; 
$add_event(); 

//start the loop processing, no events are processed until this is done 
$loop->run(); //php doesn't leave this call until the daemon is done 
exit(0); //cleanly exit 

El caso anterior es un muy simple 1 fuente EventLoop y una adición manual de funciones temporizadas (estas pueden agregarse incluso desde una llamada al ReactClass).

En la aplicación en la que estoy trabajando, necesitaba tener entrada de eventos asíncrona en el backend (a través de un socket) y luego tener la capacidad de llamar funciones al desplazamiento arbitrario del evento original (para clientes caducados, etc.)

Si desea obtener más ejemplos, puede encontrarlos en github.

Espero que esto le resulte útil.

+0

any1 aquí, ¿sabes que garena está trabajando? Necesito ayuda para eso también ... – booota

+0

Me gusta el aspecto de esto. ¿Podría mostrarme cómo configurar esto para que las funciones de evento tengan acceso a una matriz de objetos que se actualiza constantemente en un bucle de juego separado? –

+0

@Toby Wilson He actualizado mi publicación. Avísame si eso ayuda. –

Cuestiones relacionadas