web-dev-qa-db-ja.com

PHP Socket Server vs node.js:Webチャット

長時間保持されているHTTPリクエスト(Comet)、ajax、およびWebSocket(使用するブラウザーによって異なります)を使用してHTTPWebChatをプログラムしたいと思います。ユーザーデータベースはmysqlにあります。チャットはPHPで記述されていますが、JavaScript(node.js)でも記述できるチャットストリーム自体は除きます。

これらのphpの子の間でチャットメッセージを送信する良い方法がないため、ユーザーごとにphpプロセスを開始したくありません。そこで、PHPまたはnode.jsのいずれかで独自のソケットサーバーを作成することを考えました。これは、1000を超える接続(チャットユーザー)を処理できるはずです。純粋なWeb開発者(php)として私は私は通常Webサーバーに接続を任せているので、ソケットについてはあまり詳しくありません。チャットメッセージはディスクにもmysqlにも保存されませんが、最高速度の配列またはオブジェクトとしてRAMに保存されます。

私の知る限り、単一のphpプロセス(ソケットサーバー)で同時に複数の接続を処理する方法はありませんが、大量のソケット接続を受け入れて、ループで連続して処理することができます(読み取りと書き込み、着信メッセージ->すべてのソケット接続に書き込みます)。問題は、最大1000人のユーザーとのラグが発生する可能性が高く、mysql操作によって全体が遅くなり、すべてのユーザーに影響が及ぶ可能性があることです。

私の質問は:node.jsはより良いパフォーマンスでソケットサーバーを処理できますか? Node.jsはイベントベースですが、複数のイベントを同時に処理できるかどうか(マルチスレッドが必要ではないでしょうか)、またはイベントキューだけがあるかどうかはわかりません。イベントキューを使用すると、phpのようになります。ユーザーを次々と処理します。

チャットルームごとにphpプロセスを生成することもできますが(ユーザー数ははるかに少ない)、シングルスレッドのIRCサーバーで数千人のユーザーを処理することもできます(c ++などで記述)) phpでも可能です。

プロジェクトはphpのみであり、プログラミング言語の混合ではないため、Node.jsよりもPHPの方が好きです。ただし、Nodeが接続を同時に処理できる場合私はおそらくそれを選ぶでしょう。

19
Eliasdx

JavaScript、またはこの場合Nodeが使用しているエンジンであるV8は、designシングルスレッドによるものです。はい、イベントキューだけがあります。

しかし、結局のところ、それはnotの問題であり、複数のプロセッサを使用している場合を除いて、常に最初に何かが発生します。ネットワークカードは1つだけです...ルーターは1つです...また、1000以上のスレッドを使用する...良い考えではなく、スケーリングが悪く、並行性[〜#〜] hell [〜#〜]

1000人のチャットユーザー、それはNode.jsにとってまったく問題ありません

私はあなたにそれをどのように設定するかかなり基本的なアイデアを与えることができます、このプレーンなバニラチャットはtelnet上で機能します、それは..機能がありませんが、それは機能します:

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

ここには魔法は含まれていません( closures の使用を除いて)、rawソケットプログラミングとは関係がなく、並行性の問題もありません。そして、あなたは最新の暑さのいくつかを学びます;)

Node.jsがどのように機能するかをよりよく理解するために、 Node.js タグwikiにリストされているいくつかの講演をご覧になることをお勧めします。

25
Ivo Wetzel

私が答えたもう1つのトピックは、ニーズに合わせて簡単に拡張できます=> nodejsでredis PUBLISH/SUBSCRIBEを使用して、データ値が変更されたときにクライアントに通知する方法は?

0
Alfred