简体   繁体   English

PHP Socket Server vs node.js:Web Chat

[英]PHP Socket Server vs node.js: Web Chat

I want to program a HTTP WebChat using long-held HTTP requests (Comet), ajax and websockets (depending on the browser used). 我想使用长期持有的HTTP请求(Comet),ajax和websockets(取决于所使用的浏览器)来编写HTTP WebChat。 Userdatabase is in mysql. 用户数据库在mysql中。 Chat is written in PHP except maybe the chat stream itself which could also be written in javascript (node.js): 聊天是用PHP编写的,除了聊天流本身,也可以用javascript(node.js)编写:

I don't want to start a php process per user as there is no good way to send the chat messages between these php childs. 我不想为每个用户启动一个php进程,因为没有好方法在这些php子进程之间发送聊天消息。 So I thought about writing an own socket server in either PHP or node.js which should be able to handle more then 1000 connections (chat users). 所以我想在PHP或node.js中编写自己的套接字服务器应该能够处理超过1000个连接(聊天用户)。 As a purely web developer (php) I'm not much familiar with sockets as I usually let web server care about connections. 作为一个纯粹的Web开发人员(php)我不太熟悉套接字,因为我通常让Web服务器关心连接。 The chat messages won't be saved on disk nor in mysql but in RAM as an array or object for best speed. 聊天消息不会保存在磁盘上或mysql中,而是保存在RAM中作为数组或对象以获得最佳速度。

As far as I know there is no way to handle multiple connections at the same time in a single php process (socket server), however you can accept a great amount of socket connections and process them successive in a loop (read and write; incoming message -> write to all socket connections). 据我所知,在单个php进程(套接字服务器)中无法同时处理多个连接,但是你可以接受大量的套接字连接并在循环中连续处理它们(读写;传入message - >写入所有套接字连接)。 The problem is that there will most-likely be a lag with ~1000 users and mysql operations could slow the whole thing down which will then affect all users. 问题是最大可能会有〜1000个用户的滞后,而mysql操作可能会减慢整个事情的速度,从而影响所有用户。

My question is: Can node.js handle a socket server with better performance? 我的问题是:node.js可以处理性能更好的套接字服务器吗? Node.js is event-based but I'm not sure if it can process multiple events at the same time (wouldn't that need multi-threading?) or if there is just an event queue. Node.js是基于事件的,但我不确定它是否可以同时处理多个事件(不需要多线程吗?)或者是否只有一个事件队列。 With an event queue it would be just like php: process user after user. 使用事件队列就像php:用户之后处理用户。

I could also spawn a php process per chat room (much less users) but afaik there are singlethreaded IRC servers which are also capable to handle thousands of users. 我还可以为每个聊天室(更少的用户)生成一个php进程,但是afaik还有单线程的IRC服务器,它们也能够处理数千个用户。 (written in c++ or whatever) so maybe it's also possible in php. (用c ++或其他语言编写)所以也许在php中也可以。

I would prefer PHP over Node.js because then the project would be php-only and not a mixture of programming languages. 我更喜欢PHP而不是Node.js因为那时项目将只是php而不是编程语言的混合。 However if Node can process connections simultaneously I'd probably choose it. 但是,如果Node可以同时处理连接,我可能会选择它。

JavaScript, or in this case V8 which is the engine that Node is using, is by design single threaded. JavaScript,或者在这种情况下,V8是Node正在使用的引擎,是设计单线程的。 So yes there's just an event queue. 所以是的,只有一个事件队列。

But in the end, that's not a problem, something's always gonna happen first, unless you're using multiple processors, and even then, you will most likely only have one network card... one router... you get the idea. 但最终,这不是问题,除非你使用多个处理器,否则总会先发生一些事情,即使这样,你很可能只有一个网卡......一个路由器......你明白了。 Also, using 1000+ threads... not a good idea, scales badly, and you will find yourself in a concurrency HELL . 此外,使用1000+线程...不是一个好主意,鳞片不好,你会发现自己在一个并发地狱

1000 chat users, that will be no problem at all for Node.js. 1000个聊天用户,这对Node.js来说完全没问题

I can give you a pretty basic idea how you would set it up, this plain vanilla chat thingy works over telnet, it has.. no features, but it works: 我可以给你一个非常基本的想法,你将如何设置它,这个普通的香草聊天东西在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);

There's no magic involved in here (besides the use of a closures ), you don't have to do with raw socket programming and you won't have any concurrency problems. 这里没有任何魔法(除了使用闭包 ),你不需要处理原始套接字编程,你不会有任何并发​​问题。 And you learn some of the latest hotness ;) 你会学到一些最新的热情;)

I recommend that you watch some of the talks that are listed on our Node.js tag wiki, to get a better grasp of how Node.js works. 我建议你观看我们的Node.js标签wiki上列出的一些会谈,以便更好地掌握Node.js的工作原理。

我回答的另一个主题可以帮助您,并且可以轻松扩展到您的需求=> 如何使用redis PUBLISH / SUBSCRIBE与nodejs在数据值发生变化时通知客户端?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM