使用PHP的彗星?

时间:2009-03-02 17:30:19

标签: php comet

我正在考虑使用PHP后端实现实时聊天,但我在讨论彗星的网站上发表了这条评论:

  

我的理解是PHP是一个   彗星的可怕语言,因为   彗星要求你保持一个   持久连接对每个人开放   浏览器客户端使用mod_php这个   意味着捆绑一个Apache孩子   每个客户的全职   完全没有规模。人民我   知道彗星的东西大多是   使用设计的Twisted Python   处理数百或数千   同时连接。

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

11 个答案:

答案 0 :(得分:61)

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

的Apache

每个进入Apache的请求都将使用一个工作线程,直到请求完成,这可能需要很长时间才能完成COMET请求。

This article on Ajaxian提到在Apache上使用COMET,这很困难。该问题并非特定于PHP,并且适用于您可能希望在Apache上使用的任何后端CGI模块。

建议的解决方案是使用'event' MPM module来改变将请求分派给工作线程的方式。

  

此MPM尝试修复   HTTP中的“保持活动问题”。   客户端完成第一个后   请求,客户端可以保留   连接打开,并进一步发送   请求使用相同的套接字。这个   可以节省大量的开销   创建TCP连接。然而,   Apache传统上保留了整个   子进程/线程等待数据   来自客户,它带来了自己的   缺点。要解决这个问题,   这个MPM使用专用线程   处理Listening套接字和   Keep Alive中的所有套接字   状态。

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

PHP

现在,考虑到问题的另一面,即使您解决了每个彗星请求占用一个线程的问题,每个请求仍然需要一个PHP线程 - 这就是FastCGI无法帮助的原因。

你需要像Continuations这样的东西,它允许在被触发的事件被观察时恢复彗星请求。 AFAIK,这在PHP中是不可能的。我只在Java中看到它 - 请参阅Apache Tomcat server

修改

有一个article here关于使用负载均衡器(HAProxy)允许您在端口80上运行apache服务器和启用Comet的服务器(例如jetty,tomcat for Java)同一台服务器。

答案 1 :(得分:14)

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

我在这里有一个非常简单的例子,可以帮助你入门。它包括使用NHPM模块编译Nginx,并包含jQuery,PHP和Bash中简单发布者/订阅者角色的代码。

http://blog.jamieisaacs.com/2010/08/27/comet-with-nginx-and-jquery/

答案 2 :(得分:10)

PHP

我发现这个有趣的小screencasts解释了简单的彗星。作为旁注,我真的认为这会在任何实际负载下扼杀您的服务器。如果只有几个用户,我会说只是去寻找这个解决方案。这个解决方案实现起来非常简单(截屏视频只需要5分钟的时间:))。但正如我之前所说,我不认为它对很多并发用户有好处(猜猜你应该对它进行基准测试;))因为:

  1. 它使用的文件I / O比从内存中获取数据慢得多。例如函数filemtime()
  2. 其次,但我不认为PHP没有一个像样的线程模型。由于share nothing model,PHP不是为此而设计的。就像幻灯片一样,“共享数据被推送到数据存储层”,例如MySQL。
  3. 替代

    我真的认为如果你想做任何彗星/长轮询,你应该尝试其他选择。您可以使用多种语言,例如:

    • Java / JVM:Jetty continuations
    • Python:Dustin的slosh
    • Erlang:彗星/等的流行语言
    • Lua,Ruby,C,Perl仅举几例。

    只是执行一个简单的谷歌搜索,将向您展示很多替代品PHP(我认为在任何大的负载将杀死您的服务器)。

答案 3 :(得分:7)

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

PHP as FastCGI:http://www.fastcgi.com/drupal/node/5?q=node/10

答案 4 :(得分:6)

您也可以尝试https://github.com/reactphp/react

  

React是PHP中用于事件驱动编程的低级库。它的核心是一个事件循环,在它上面提供了低级实用程序,例如:Streams抽象,async dns解析器,网络客户机/服务器,http客户机/服务器,与进程的交互。第三方库可以使用这些组件来创建异步网络客户端/服务器等。

     

事件循环基于reactor模式(因此得名),并受到诸如EventMachine(Ruby),Twisted(Python)和Node.js(V8)等库的强烈启发。

介绍性示例显示了一个侦听端口1337的简单HTTP服务器:

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

答案 5 :(得分:4)

我遇到了类似的问题。我觉得有趣的一个选择是使用现有的Comet服务器,如cometd-java或cometd-python,作为核心消息中心。您的PHP代码只是Comet服务器的客户端 - 它可以像其他客户端一样发布或读取来自频道的消息。

这里有一个有趣的代码片段:http://morglog.org/?p=22=1实现了这个方法的一部分(虽然也有一些调试代码也在传播)。

答案 6 :(得分:3)

你很难用PHP实现彗星,因为它具有固有的单线程性。

查看Websync On-Demand - 该服务允许您通过服务器端发布集成PHP,卸载繁重的并发连接内容,并且可以让您立即创建实时聊天应用程序。

答案 7 :(得分:3)

我目前正在使用套接字函数实现可扩展的PHP Comet服务器。它被称为'phet'([ph] p com [et])

项目页面:http://github.com/Tim-Smart/phet

免费加入开发。我目前设法完成大部分服务器逻辑,只需要完成客户端的工作。

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

答案 8 :(得分:1)

nginx网络服务器刚刚推出了一个新模块,它将允许Comet使用任何语言,包括PHP。

http://www.igvita.com/2009/10/21/nginx-comet-low-latency-server-push/

答案 9 :(得分:1)

您必须在PHP中创建自己的服务器。使用Apache / mod_php甚至fastcgi根本不会扩展。几岁,但可以让你开始:

PHP-彗星服务器: http://sourceforge.net/projects/comet/

答案 10 :(得分:0)

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