2011-01-01 63 views
17

Quiero programar un HTTP WebChat utilizando solicitudes HTTP de larga duración (Comet), ajax y websockets (dependiendo del navegador utilizado). Userdatabase está en mysql. El chat está escrito en PHP, excepto tal vez la secuencia de chat, que también podría escribirse en javascript (node.js):PHP Socket Server vs node.js: Web Chat

No quiero iniciar un proceso de php por usuario ya que no hay una buena manera de enviar el chat mensajes entre estos niños php. Así que pensé en escribir un servidor socket propio en PHP o node.js que debería poder manejar más de 1000 conexiones (usuarios de chat). Como desarrollador puramente web (php) no estoy muy familiarizado con los sockets, ya que generalmente dejo que el servidor web se preocupe por las conexiones. Los mensajes de chat no se guardarán en el disco ni en mysql, sino en la RAM como una matriz u objeto para obtener la mejor velocidad.

Hasta donde yo sé, no hay manera de manejar múltiples conexiones al mismo tiempo en un solo proceso php (servidor de socket), sin embargo, puede aceptar una gran cantidad de conexiones de socket y procesarlas sucesivamente en un bucle (leer y escribir; mensaje entrante -> escribir en todas las conexiones de socket). El problema es que lo más probable es que haya un desfase con ~ 1000 usuarios y las operaciones de mysql podrían ralentizar todo, lo que afectará a todos los usuarios.

Mi pregunta es: ¿Puede node.js manejar un servidor de socket con un mejor rendimiento? Node.js está basado en eventos, pero no estoy seguro de si puede procesar múltiples eventos al mismo tiempo (¿no sería necesario un multihilo?) O si solo hay una cola de eventos. Con una cola de eventos sería como php: procesar usuario tras usuario.

También podría engendrar un proceso de php por sala de chat (mucho menos usuarios) pero afaik hay servidores de IRC únicos que también pueden manejar miles de usuarios. (escrito en C++ o lo que sea) así que tal vez también es posible en php.

Preferiría PHP sobre Node.js porque entonces el proyecto sería php-only y no una mezcla de lenguajes de programación. Sin embargo, si Node puede procesar conexiones simultáneamente, probablemente lo elegiría.

Respuesta

24

JavaScript, o en este caso V8 que es el motor que está utilizando el nodo, es por diseño de un solo hilo. Entonces, sí, solo hay una cola de eventos.

Pero al final, eso es no un problema, algo siempre va a suceder primero, a menos que esté usando procesadores múltiples, y aun así, lo más probable es que solo tenga una tarjeta de red ... un enrutador ... ya tienes la idea Además, usar más de 1000 hilos ... no es una buena idea, escalar mal, y te encontrarás en una concurrencia HELL.

1000 usuarios de chat, que serán sin problema alguno para Node.js.

Te puedo dar una idea bastante básico cómo se configurarlo, este chat con sabor de vainilla cosita funciona a través de telnet, tiene .. no hay características, pero funciona:

var net = require('net'); // require the net module 

var users = []; // keep track of the users 

// setup a new tcp socket server 
net.createServer(function(socket) { // provide a callback in case a new connection gets 
            // established, socket is the socket object 

    // keep track of this users names, via use of closures 
    var name = ''; 

    // ask the new user for a name 
    socket.write('Enter a Name(max 12 chars): '); 

    // register a callback on the socket for the case of incoming data 
    socket.on('data', function(buffer) { // buffer is a Buffer object containing the data 
     if (name !== '') { // in case this user has a name... 

      // send out his message to all the other users... 
      for(var i = 0; i < users.length; i++) { 
       if (users[i] !== socket) { // ...but himself 
        users[i].write(name + ': ' 
            + buffer.toString('ascii').trim() 
            + '\r\n'); 
       } 
      } 

     // otherwise take the data and use that as a name 
     } else { 
      name = buffer.toString('ascii').substring(0, 12).trim().replace(/\s/g, '_'); 
      socket.write('> You have joined as ' + name + '\r\n'); 

      // push this socket to the user list 
      users.push(socket); 
      for(var i = 0; i < users.length; i++) { 
       if (users[i] !== socket) { 
        users[i].write('> ' + name + ' has joined' + '\r\n'); 
       } 
      } 
     } 
    }); 

    // another callback for removing the user aka socket from the list 
    socket.on('end', function() { 
     users.splice(users.indexOf(socket), 1); 
    }); 

// bind the server to port 8000 
}).listen(8000); 

No hay magia involucrada aquí (además del uso de un closures), no tiene que ver con la programación de socket sin procesar y no tendrá ningún problema de simultaneidad. Y aprende algunos de los últimos hotness;)

Le recomiendo que vea algunas de las conversaciones que se enumeran en nuestra wiki de etiquetas Node.js, para obtener una mejor comprensión de cómo funciona Node.js.

+0

Gracias por el código. Escribí más o menos lo mismo la semana pasada en PHP (incluso el nombre! == '' parte es idéntica), así que ahora comprobaré si está en PHP tan rápido como en node.js, así que no necesito molestarme con dos idiomas aunque node.js es agradable y fácil ya que lo utilicé para las secuencias de comandos del lado del cliente desde hace años (jquery, etc.). – Eliasdx

+1

@Eliasdx ¿tiene cada referencia node.js vs php? Tengo curiosidad de cuáles podrían ser los resultados. – William

+0

@Eliasdx ¿Alguna noticia sobre esto? Estoy buscando crear una conversación yo mismo y estoy muy interesado en conocer sus hallazgos. Personalmente estoy más metido en PHP. –