在 PHP 中使用 Comet?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/603201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:13:48  来源:igfitidea点击:

Using comet with PHP?

phpcomet

提问by ryeguy

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

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

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.

我的理解是 PHP 对 Comet 来说是一种糟糕的语言,因为 Comet 要求你保持对每个浏览器客户端的持久连接。使用 mod_php 这意味着为每个根本无法扩展的客户端全职捆绑一个 Apache 子级。我认识的做 Comet 的人大多使用 Twisted Python,它旨在处理成百上千个同时连接。

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

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

采纳答案by Mike Houston

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

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

Apache

阿帕奇

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

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

This article on Ajaxianmentions 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.

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

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

建议的解决方案是使用“事件”MPM 模块,该模块改变了将请求分派到工作线程的方式。

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.

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

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

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

PHP

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.

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

You need something like Continuationswhich 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.

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

Edit:

编辑:

There's an article hereabout 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.

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

回答by Jamie

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

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

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.

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

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

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

回答by Alfred

PHP

PHP

I found this funny little screencastsexplaining 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:

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

  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.
  1. 它使用文件 I/O,这比从内存中获取数据要慢得多。例如功能filemtime()
  2. 其次,但我认为至少 PHP 没有一个像样的线程模型。由于没有共享模型,PHP 无论如何都不是为此而设计的。就像幻灯片所说的“共享数据被下推到数据存储层”,例如 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.
  • Java/JVM:码头延续
  • 蟒蛇:达斯汀的slosh
  • Erlang:彗星/等的流行语言。
  • Lua、Ruby、C、Perl 仅举几例。

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

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

回答by vartec

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

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

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

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

回答by Gordon

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

你也可以试试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).

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

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

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

介绍性示例显示了一个简单的 HTTP 服务器侦听端口 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();

回答by Evan P.

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.

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

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

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

回答by jvenema

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

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

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.

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

回答by Tim

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

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

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

项目页面: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_forkmethod :)

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

回答by ceejayoz

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

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

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

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

回答by sroussey

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 创建自己的服务器。使用 Apache/mod_php 甚至 fastcgi 根本无法扩展。几年前,但可以让你开始:

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

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