2011-01-01 31 views
17

Desidero programmare una WebChat HTTP utilizzando richieste HTTP a lungo termine (Comet), ajax e websocket (a seconda del browser utilizzato). Userdatabase è in mysql. La chat è scritta in PHP tranne forse lo stesso flusso di chat che potrebbe anche essere scritto in javascript (node.js):PHP Socket Server vs node.js: Web Chat

Non voglio avviare un processo php per utente in quanto non c'è un buon modo per inviare la chat messaggi tra questi php childs. Quindi ho pensato di scrivere un proprio server socket in PHP o node.js che dovrebbe essere in grado di gestire più di 1000 connessioni (utenti di chat). Come sviluppatore puramente web (php) non ho molta dimestichezza con i socket perché di solito il web server si preoccupa delle connessioni. I messaggi di chat non verranno salvati su disco né in mysql ma nella RAM come array o oggetto per la migliore velocità.

Per quanto ne so non c'è modo di gestire più connessioni contemporaneamente in un singolo processo php (socket server), tuttavia è possibile accettare una grande quantità di connessioni socket ed elaborarle in un ciclo continuo (leggi e scrivi; messaggio in entrata -> scrivi su tutte le connessioni socket). Il problema è che probabilmente ci sarà un ritardo di circa 1000 utenti e le operazioni di mysql potrebbero rallentare il tutto, il che influenzerà quindi tutti gli utenti.

La mia domanda è: Can node.js può gestire un server socket con prestazioni migliori? Node.js è basato su eventi ma non sono sicuro che possa elaborare più eventi contemporaneamente (non sarebbe necessario il multi-threading?) O se c'è solo una coda di eventi. Con una coda di eventi sarebbe proprio come php: processare l'utente dopo l'utente.

Potrei anche generare un processo php per chat room (molto meno utenti) ma, a parte questo, ci sono i server IRC a singolo canale che sono anche in grado di gestire migliaia di utenti. (scritto in C++ o qualsiasi altra cosa) quindi forse è anche possibile in PHP.

Preferirei PHP su Node.js perché il progetto sarebbe php-only e non una combinazione di linguaggi di programmazione. Tuttavia, se il nodo può elaborare simultaneamente le connessioni, probabilmente lo sceglierei.

risposta

24

JavaScript, o in questo caso V8, che è il motore utilizzato dal nodo, è di design single threaded. Quindi sì, c'è solo una coda di eventi.

Ma alla fine, questo è non un problema, qualcosa è sempre succederà prima, a meno che non si sta utilizzando più processori, e anche allora, è molto probabile avere una sola scheda di rete ... un router .. Hai un'idea. Inoltre, utilizzando 1000+ thread ... non è una buona idea, scala male, e ti troverai in una concorrenza HELL.

1000 utenti di chat, che saranno nessun problema per Node.js.

posso darvi una piuttosto semplice idea di come si dovrebbe configurarlo, questa chat plain vanilla thingy funziona su telnet, non ha .. senza funzioni, ma funziona:

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); 

Non c'è la magia coinvolta qui (a parte l'uso di un closures), non devi avere a che fare con la programmazione raw del socket e non avrai problemi di concorrenza. E impari alcune delle ultime novità;)

Ti consiglio di guardare alcuni dei dialoghi elencati nel nostro tag wiki Node.js, per capire meglio come funziona Node.js.

+0

Grazie per il codice. Ho scritto più o meno lo stesso la scorsa settimana in PHP (anche il nome! == '' part è identico), quindi ora controllerò se è in PHP veloce come in node.js quindi non ho bisogno di bug con due lingue sebbene node.js sia bello e facile dato che lo ho usato per lo scripting lato client da anni (jquery, ecc.). – Eliasdx

+1

@Eliasdx fai ogni benchmark node.js vs php? Sono curioso di sapere quali potrebbero essere i risultati. – William

+0

@Eliasdx Qualche notizia su questo? Sto cercando di creare una chat me stesso e molto interessato a conoscere le tue scoperte. Sono personalmente più interessato a PHP. –