在PHP中使用comet?

在PHP中使用comet?,php,comet,Php,Comet,我曾考虑使用PHP后端实现实时聊天,但我在一个讨论comet的网站上看到了这条评论: 我的理解是PHP是一个 Comet的语言很糟糕,因为 Comet要求你保持 对每个用户开放的持久连接 浏览器客户端。使用mod_php 意味着把一个孩子绑起来 每个客户的全职 根本不可伸缩。我爱的人 知道做彗星的东西大多是 使用设计的TwistedPython 处理成百上千的 同时连接 这是真的吗?或者它是可以配置的吗?mod_php不是使用php的唯一方法。您可以使用fastcgi。PHP必须使用--启用fa

我曾考虑使用PHP后端实现实时聊天,但我在一个讨论comet的网站上看到了这条评论:

我的理解是PHP是一个 Comet的语言很糟糕,因为 Comet要求你保持 对每个用户开放的持久连接 浏览器客户端。使用mod_php 意味着把一个孩子绑起来 每个客户的全职 根本不可伸缩。我爱的人 知道做彗星的东西大多是 使用设计的TwistedPython 处理成百上千的 同时连接


这是真的吗?或者它是可以配置的吗?

mod_php不是使用php的唯一方法。您可以使用fastcgi。PHP必须使用
--启用fastcgi
编译


PHP作为FastCGI:

我认为这更像是一个问题,因为有很多apache线程一直在运行是一个问题。如果它通过apache以与PHP(通常)相同的方式工作,那么任何语言都会存在这种问题。

我也有类似的问题。我发现一个有趣的选择是使用现有的Comet服务器,如CometdJava或CometdPython,作为核心消息中心。然后,您的PHP代码只是Comet服务器的一个客户端——它可以像其他客户端一样发布或读取来自通道的消息


这里链接了一个有趣的代码片段:它实现了该方法的一部分(尽管也有一些调试代码)

您将很难在PHP中实现comet,因为它固有的单线程特性

签出-该服务允许您通过服务器端发布集成PHP,卸载繁重的并发连接,并允许您立即创建实时聊天应用程序。

PHP 我发现这个有趣的小彗星。顺便说一句,我真的认为这会在任何实际负载下杀死你的服务器。当只有几个用户的时候,我会说只需要使用这个解决方案。这个解决方案实现起来非常简单(屏幕播放只需花费您5分钟的时间:)。但正如我之前所说,我认为这对很多并发用户来说并不好(我想你应该对它进行基准测试),因为:

  • 它使用文件I/O,这比仅仅从内存中获取数据要慢得多。例如,函数
    filemtime()
  • 第二,但我不认为PHP至少没有一个像样的线程模型。无论如何,PHP并不是为此而设计的,因为。如幻灯片所示,“共享数据被下推到数据存储层”,例如MySQL
  • 选择 我真的认为如果你想做任何comet/long轮询,你应该尝试其他方法。您可以使用多种语言,例如:

    • Java/JVM:Jetty
    • 蟒蛇:达斯汀的
    • Erlang:comet/etc的流行语言
    • Lua、Ruby、C、Perl等等

    只需执行一个简单的google搜索,就可以向您展示许多PHP的替代方案(我认为在任何大负载下都会杀死您的服务器)。

    我目前正在使用套接字函数实现一个可伸缩的PHP Comet服务器。它被称为“phet”([ph]pcom[et])

    项目页面:

    自由参与发展。我目前已经完成了大部分服务器逻辑,只需要完成客户端的工作


    编辑:最近使用
    pcntl\u fork
    方法添加了“多线程”功能:)

    一个新模块刚刚为nginx web服务器推出,它允许Comet使用任何语言,包括PHP


    同意/扩大已经说过的内容,我认为FastCGI无法解决问题

    阿帕奇 进入Apache的每个请求都将使用一个工作线程,直到请求完成,这对于COMET请求来说可能需要很长时间

    提到在Apache上使用COMET,这很困难。这个问题不是PHP特有的,它适用于您可能希望在Apache上使用的任何后端CGI模块

    建议的解决方案是使用更改将请求分派到工作线程的方式的

    此MPM尝试修复 HTTP中的“保持活动”问题。 在客户端完成第一个 请求时,客户端可以保留 连接已打开,请发送更多信息 使用相同套接字的请求。这 可以节省大量的开销 创建TCP连接。然而, Apache传统上保留一个完整的 等待数据的子进程/线程 来自客户,它带来了自己的 缺点。要解决这个问题,, 此MPM使用专用线程来 处理两个侦听套接字,以及 处于同一状态的所有插座均保持活动状态 国家

    不幸的是,这也不起作用,因为它只会在请求完成后“打盹”,等待来自客户端的新请求

    PHP 现在,考虑到问题的另一面,即使您通过为每个comet请求保留一个线程来解决问题,您仍然需要为每个请求保留一个PHP线程——这就是为什么FastCGI没有帮助的原因

    您需要这样的东西,当观察到comet请求被触发的事件时,允许恢复comet请求。抱歉,这在PHP中是不可能的。我只在Java中见过它——请参阅Apache

    编辑:


    使用负载平衡器()允许您在同一服务器的端口80上运行apache服务器和启用comet的服务器(例如jetty、tomcat for Java)。

    您必须使用PHP创建自己的服务器。使用Apache/mod_-php甚至fastcgi根本无法扩展。几岁,但可以让你开始:

    PHP Comet服务器:

    您可以使用Nginx和JavaScript实现一个基于Comet的聊天系统,该系统具有很强的可扩展性,内存或CPU利用率很低

    我这里有一个非常简单的例子,可以让你开始。它涵盖了使用NHPM模块编译Nginx,并包括jQuery、PHP和Bash中简单发布者/订阅者角色的代码

    您可以
    <?php
    
    $i = 0;
    
    $app = function ($request, $response) use (&$i) {
        $i++;
    
        $text = "This is request number $i.\n";
        $headers = array('Content-Type' => 'text/plain');
    
        $response->writeHead(200, $headers);
        $response->end($text);
    };
    
    $loop = React\EventLoop\Factory::create();
    $socket = new React\Socket\Server($loop);
    $http = new React\Http\Server($socket);
    
    $http->on('request', $app);
    
    $socket->listen(1337);
    $loop->run();