PHP Socket 服务器与 Node.js:网络聊天

发布于 2024-10-10 02:04:44 字数 829 浏览 0 评论 0原文

我想使用长期保存的 HTTP 请求(Comet)、ajax 和 websockets(取决于所使用的浏览器)来编写 HTTP WebChat 程序。用户数据库位于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 可以同时处理连接,我可能会选择它。

I want to program a HTTP WebChat using long-held HTTP requests (Comet), ajax and websockets (depending on the browser used). Userdatabase is in mysql. Chat is written in PHP except maybe the chat stream itself which could also be written in 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.
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). As a purely web developer (php) I'm not much familiar with sockets as I usually let web server care about connections. The chat messages won't be saved on disk nor in mysql but in RAM as an array or object for best speed.

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

My question is: Can node.js handle a socket server with better performance? 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. With an event queue it would be just like php: process user after user.

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. (written in c++ or whatever) so maybe it's also possible in php.

I would prefer PHP over Node.js because then the project would be php-only and not a mixture of programming languages. However if Node can process connections simultaneously I'd probably choose it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

桃气十足 2024-10-17 02:04:44

JavaScript,或者在本例中是 Node 使用的引擎 V8,是设计单线程的。所以是的,只有一个事件队列。

但最终,这不是问题,总是会先发生一些事情,除非您使用多个处理器,即使如此,您很可能只有一个网卡...一个路由器。 ..你明白了。另外,使用 1000 多个线程...不是一个好主意,扩展性很差,并且您会发现自己处于并发地狱之中。

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

这里没有涉及任何魔法(除了使用闭包),你不必与原始套接字编程,你不会有任何并发​​问题。并且您可以了解一些最新热点;)

我建议您观看我们的 Node.js< 上列出的一些演讲/a> 标签 wiki,以更好地掌握 Node.js 的工作原理。

JavaScript, or in this case V8 which is the engine that Node is using, is by design single threaded. 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 chat users, that will be no problem at all for 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:

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.

記憶穿過時間隧道 2024-10-17 02:04:44

我回答的另一个主题可以帮助您并且可以轻松地满足您的需求=> 如何使用redis发布/使用 Nodejs 订阅以在数据值发生变化时通知客户端?

Another topic which I answered which could help you and will easily scale to your needs => How to use redis PUBLISH/SUBSCRIBE with nodejs to notify clients when data values change?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文