Подтвердить что ты не робот

PHP Socket Server vs node.js: веб-чат

Я хочу запрограммировать HTTP WebChat, используя длинные HTTP-запросы (Comet), ajax и websockets (в зависимости от используемого браузера). База данных пользователя находится в mysql. Чат написан на PHP, за исключением, может быть, самого потока чата, который также может быть записан в javascript (node.js):

Я не хочу запускать php-процесс для каждого пользователя, так как нет хорошего способа отправить чат-сообщения между этими php-детьми. Поэтому я подумал о написании собственного сервера сокетов в PHP или node.js, который должен иметь возможность обрабатывать более 1000 подключений (пользователей чата). Как чисто веб-разработчик (php), я не очень хорошо разбираюсь в сокетах, поскольку я обычно позволяю веб-серверу заботиться о соединениях. Сообщения чата не будут сохранены на диске или в mysql, а в ОЗУ как массив или объект для лучшей скорости.

Насколько я знаю, нет способа одновременно обрабатывать несколько подключений в одном php-процессе (сервер сокетов), однако вы можете принимать большое количество соединений сокетов и обрабатывать их последовательно в цикле (чтение и запись, входящее сообщение → запись во все соединения сокетов). Проблема в том, что наиболее вероятно будет отставание от ~ 1000 пользователей, а операции с mysql могут замедлить работу всего, что повлияет на всех пользователей.

Мой вопрос: может ли node.js обрабатывать сервер сокетов с лучшей производительностью? node.js основан на событиях, но я не уверен, может ли он обрабатывать несколько событий одновременно (не нужно многопоточность?) или если есть очередь событий. С очередью событий это будет точно так же, как php: обрабатывать пользователя после пользователя.

Я мог бы также генерировать php-процесс в чате (гораздо меньше пользователей), но afaik есть однопоточные IRC-серверы, которые также способны обрабатывать тысячи пользователей. (написано на С++ или что-то еще), поэтому, возможно, это также возможно в php.

Я бы предпочел PHP над node.js, потому что тогда проект был бы php-only, а не смесью языков программирования. Однако, если Node может обрабатывать соединения одновременно, я бы выбрал его.

4b9b3361

Ответ 1

JavaScript, или в этом случае V8, который является движком, который использует Node, по умолчанию дизайн. Итак, да, есть очередь событий.

Но в конце концов, эта не проблема, что-то всегда произойдет первым, если вы не используете несколько процессоров, и даже тогда у вас, скорее всего, будет только одна сетевая карта... один маршрутизатор... у вас есть идея. Кроме того, использование 1000+ потоков... не очень хорошая идея, плохо масштабируется, и вы окажетесь в concurrency 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);

Здесь нет никакой магии (помимо использования закрытий), вам не нужно заниматься программированием сокетов, и у вас не будет никаких concurrency проблемы. И вы узнаете некоторые из последних жарких;)

Я рекомендую вам посмотреть некоторые из разговоров, которые перечислены в нашей Node.js теге wiki, чтобы лучше понять, как работает Node.js.