在 PHP 中使用 comet?

发布于 2024-07-14 13:38:45 字数 337 浏览 4 评论 0原文

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

我的理解是PHP是一个 彗星的语言很糟糕,因为 Comet 要求您保留 对每个人开放的持久连接 浏览器客户端。 使用 mod_php 这个 意味着捆绑一个阿帕奇孩子 为每个客户全职工作 根本无法扩展。 我的人 知道做Comet的东西主要是 使用 Twisted Python 设计 处理数百或数千 同时连接。

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

I was thinking of implementing real time chat using a PHP backend, but I ran across this comment on a site discussing comet:

My understanding is that PHP is a
terrible language for Comet, because
Comet requires you to keep a
persistent connection open to each
browser client. Using mod_php this
means tying up an Apache child
full-time for each client which
doesn’t scale at all. The people I
know doing Comet stuff are mostly
using Twisted Python which is designed
to handle hundreds or thousands of
simultaneous connections.

Is this true? Or is it something that can be configured around?

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

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

发布评论

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

评论(11

£噩梦荏苒 2024-07-21 13:38:45

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

Apache

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

这篇关于 Ajaxian 的文章 提到在 Apache 上使用 COMET,而且这很困难。 该问题并非 PHP 特有,并且适用于您可能想要在 Apache 上使用的任何后端 CGI 模块。

建议的解决方案是使用 'event' MPM 模块,它会更改请求被分派到工作线程的方式。

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

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

PHP

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

您需要类似 Continuations 的东西,它允许在触发彗星请求的事件发生时恢复彗星请求观察到的。 AFAIK,这在 PHP 中是不可能的。 我只在 Java 中见过它 - 请参阅 Apache Tomcat 服务器

编辑:

有一篇文章这里关于使用负载均衡器(HAProxy)来允许您同时运行 apache 服务器和在同一服务器的端口 80 上启用 comet 的服务器(例如 jetty、用于 Java 的 tomcat)。

Agreeing/expanding what has already been said, I don't think FastCGI will solve the problem.

Apache

Each request into Apache will use one worker thread until the request completes, which may be a long time for COMET requests.

This article on Ajaxian mentions using COMET on Apache, and that it is difficult. The problem isn't specific to PHP, and applies to any back-end CGI module you may want to use on Apache.

The suggested solution was to use the 'event' MPM module which changes the way requests are dispatched to worker threads.

This MPM tries to fix
the 'keep alive problem' in HTTP.
After a client completes the first
request, the client can keep the
connection open, and send further
requests using the same socket. This
can save signifigant overhead in
creating TCP connections. However,
Apache traditionally keeps an entire
child process/thread waiting for data
from the client, which brings its own
disadvantages. To solve this problem,
this MPM uses a dedicated thread to
handle both the Listening sockets, and
all sockets that are in a Keep Alive
state.

Unfortunately, that doesn't work either, because it will only 'snooze' after a request is complete, waiting for a new request from the client.

PHP

Now, considering the other side of the problem, even if you resolve the issue with holding up one thread per comet request, you will still need one PHP thread per request - this is why FastCGI won't help.

You need something like Continuations which allow the comet requests to be resumed when the event they are triggered by is observed. AFAIK, this isn't something that's possible in PHP. I've only seen it in Java - see the Apache Tomcat server.

Edit:

There's an article here about using a load balancer (HAProxy) to allow you to run both an apache server and a comet-enabled server (e.g. jetty, tomcat for Java) on port 80 of the same server.

十年九夏 2024-07-21 13:38:45

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

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

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

You could use Nginx and JavaScript to implement a Comet based chat system that is very scalable with little memory or CPU utilization.

I have a very simple example here that can get you started. It covers compiling Nginx with the NHPM module and includes code for simple publisher/subscriber roles in jQuery, PHP, and Bash.

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

挽容 2024-07-21 13:38:45

PHP

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

  1. 它使用文件 I/O,这比从内存获取数据要慢得多。 例如函数 filemtime()
  2. 其次,但我认为 PHP 至少没有一个像样的线程模型。 无论如何,PHP 并不是为此设计的,因为不共享模型。 就像幻灯片中所说的“共享数据被推送到数据存储层”,例如 MySQL。

替代方案

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

  • Java/JVM:Jetty Continuations
  • Python:达斯汀的slosh
  • Erlang:彗星等的流行语言。
  • Lua、Ruby、C、Perl 仅举几例。

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

PHP

I found this funny little screencasts explaining simple comet. As a side note I really think this is going to kill your server on any real load. When just having a couple of users, I would say to just go for this solution. This solution is really simple to implement(screencasts only takes 5 minutes of your time :)). But as I was telling previously I don't think it is good for a lot of concurrent users(Guess you should benchmark it ;)) because:

  1. It uses file I/O which is much slower then just getting data from memory. Like for example the functions filemtime(),
  2. Second, but I don't think least PHP does not a have a decent thread model. PHP was not designed for this anyway because of the share nothing model. Like the slides says "Shared data is pushed down to the data-store layer" like for example MySQL.

Alternatives

I really think you should try the alternatives if you want to do any comet/long polling. You could use many languages like for example:

  • Java/JVM: Jetty continuations.
  • Python: Dustin's slosh.
  • Erlang: Popular language for comet/etc.
  • Lua, Ruby, C, Perl just to name a few.

Just performing a simple google search, will show you a lot alternatives also PHP(which I think on any big load will kill your server).

洛阳烟雨空心柳 2024-07-21 13:38:45

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

PHP 作为 FastCGI: http://www.fastcgi.com/drupal/node /5?q=节点/10

mod_php is not the only way to use PHP. You can use fastcgi. PHP must be compiled with --enable-fastcgi.

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

栀梦 2024-07-21 13:38:45

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

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

事件循环基于反应器模式(因此得名),并受到 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();

You may also try https://github.com/reactphp/react

React is a low-level library for event-driven programming in PHP. At its core is an event loop, on top of which it provides low-level utilities, such as: Streams abstraction, async dns resolver, network client/server, http client/server, interaction with processes. Third-party libraries can use these components to create async network clients/servers and more.

The event loop is based on the reactor pattern (hence the name) and strongly inspired by libraries such as EventMachine (Ruby), Twisted (Python) and Node.js (V8).

The introductory example shows a simple HTTP server listening on port 1337:

<?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();
ペ泪落弦音 2024-07-21 13:38:45

我有类似的问题。 我发现有趣的一个选择是使用现有的 Comet 服务器(例如 cometd-java 或 cometd-python)作为核心消息中心。 然后,您的 PHP 代码只是 Comet 服务器的客户端 - 它可以像其他客户端一样从通道发布或读取消息。

这里链接了一个有趣的代码片段: http://morglog.org/?p=22=1< /a> 实现了该方法的一部分(尽管也有一些调试代码)。

I'm having a similar issue. One option I'm finding interesting is to use an existing Comet server, like cometd-java or cometd-python, as the core message hub. Your PHP code is then just a client to the Comet server -- it can post or read messages from channels, just like other clients.

There's an interesting code snippet linked here: http://morglog.org/?p=22=1 that implements part of this method (although there are bits of debug code spread around, too).

走过海棠暮 2024-07-21 13:38:45

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

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

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

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

I'm current implementing a scalable PHP Comet server using socket functions. It is called 'phet' ( [ph]p com[et] )

Project page: http://github.com/Tim-Smart/phet

Free free to join in on development. I have currently managed to get most of the server logic done, just need to finish off the client side stuff.

EDIT: Recently added 'Multi-threading' capabilities using the pcntl_fork method :)

弱骨蛰伏 2024-07-21 13:38:45

在 PHP 中实现 Comet 会很困难,因为它固有的单线程特性。

查看 Websync On-Demand - 该服务可让您通过服务器端发布集成 PHP,从而减轻繁重的负担并发连接的东西,让你立即创建一个实时聊天应用程序。

You'll have a hard time implementing comet in PHP, just because of it's inherent single-threaded-ness.

Check out Websync On-Demand - the service lets you integrate PHP via server-side publishing, offloading the heavy concurrent connection stuff, and will let you create a real-time chat app in no time.

一杆小烟枪 2024-07-21 13:38:45

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

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

A new module just came out for the nginx web server that'll allow Comet with any language, including PHP.

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

电影里的梦 2024-07-21 13:38:45

您必须使用 PHP 创建自己的服务器。 使用 Apache/mod_php 甚至 fastcgi 根本无法扩展。 已有几年历史,但可以帮助您入门:

PHP-Comet-Server:
http://sourceforge.net/projects/comet/

You will have to create your own server in PHP. Using Apache/mod_php or even fastcgi will not scale at all. A few years old, but can get you started:

PHP-Comet-Server:
http://sourceforge.net/projects/comet/

尐偏执 2024-07-21 13:38:45

我认为这更像是一个问题,因为一直运行大量 apache 线程是一个问题。 如果任何语言都像 PHP(通常)一样通过 apache 工作,那么它就存在于任何语言中。

I think this is more an issue that having a lot of apache threads running all the time is a problem. That will existing with any language if it works via apache in the same way as PHP (usually) does.

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