83

PHP バックエンドを使用してリアルタイム チャットを実装することを考えていましたが、comet について議論しているサイトで次のコメントを見つけました。

私の理解では、PHP は Comet にとってひどい言語です。Comet では、各ブラウザー クライアントに対して永続的な接続を開いたままにしておく必要があるからです。mod_php を使用すると、これはクライアントごとに Apache の子をフルタイムで結び付けることを意味し、まったくスケーリングしません。私が知っている Comet の作業を行っている人々は、ほとんどが Twisted Python を使用しています。これは、数百または数千の同時接続を処理するように設計されています。

これは本当ですか?それとも、設定できるものですか?

4

11 に答える 11

62

すでに述べたことに同意/拡張すると、FastCGI が問題を解決するとは思えません。

アパッチ

Apache への各要求は、要求が完了するまで 1 つのワーカー スレッドを使用します。これは、COMET 要求の場合は長時間になる可能性があります。

Ajaxian に関するこの記事では、Apache で COMET を使用することについて言及していますが、それは難しいことです。この問題は PHP に固有のものではなく、Apache で使用するすべてのバックエンド CGI モジュールに適用されます。

提案された解決策は、リクエストがワーカー スレッドにディスパッチされる方法を変更する「イベント」MPM モジュールを使用することでした。

この MPM は、HTTP の「キープ アライブの問題」を修正しようとします。クライアントが最初のリクエストを完了した後、クライアントは接続を開いたままにし、同じソケットを使用してさらにリクエストを送信できます。これにより、TCP 接続を作成する際のオーバーヘッドを大幅に節約できます。ただし、Apache は伝統的に子プロセス/スレッド全体をクライアントからのデータを待機させたままにしており、これが独自の欠点をもたらします。この問題を解決するために、この MPM は専用スレッドを使用して、リッスン ソケットとキープ アライブ状態のすべてのソケットの両方を処理します。

残念ながら、これも機能しません。リクエストが完了したにのみ「スヌーズ」し、クライアントからの新しいリクエストを待つためです。

PHP

さて、問題の反対側を考えると、comet リクエストごとに 1 つのスレッドを保持することで問題を解決したとしても、リクエストごとに 1 つの PHP スレッドが必要になります。これが FastCGI が役に立たない理由です。

コメットリクエストがトリガーされたイベントが観測されたときにコメットリクエストを再開できる継続のようなものが必要です。私の知る限り、これは PHP で可能なことではありません。Java でしか見たことがありません。Apache Tomcat サーバーを参照してください。

編集:

ロード バランサー ( HAProxy ) を使用して、Apache サーバーとコメット対応サーバー (Jetty、Java の Tomcat など) の両方を同じサーバーのポート 80 で実行できるようにする方法に関する記事がここにあります。

于 2009-11-23T15:09:31.643 に答える
14

Nginx と JavaScript を使用して、メモリや CPU の使用率がほとんどなく、非常にスケーラブルな Comet ベースのチャット システムを実装できます。

ここに非常に簡単な例があり、すぐに始めることができます。NHPM モジュールを使用した Nginx のコンパイルについて説明し、jQuery、PHP、および Bash での単純なパブリッシャー/サブスクライバー ロールのコードが含まれています。

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

于 2010-08-27T21:29:32.503 に答える
10

PHP

シンプルな彗星を説明するこの面白い小さなスクリーンキャストを見つけました。補足として、これは実際の負荷でサーバーを停止させると本当に思います。ユーザーが数人しかいない場合は、このソリューションを選択することをお勧めします. このソリューションの実装は非常に簡単です (スクリーンキャストにかかる時間はわずか 5 分です :))。しかし、前に言ったように、多くの同時ユーザーには適していないと思います (ベンチマークする必要があると思います ;))。

  1. メモリからデータを取得するよりもはるかに遅いファイル I/O を使用します。たとえば、関数のようfilemtime()に、
  2. 2 つ目ですが、少なくとも PHP に適切なスレッド モデルがないとは思いません。いずれにせよ、共有なしモデルのため、PHP はこのように設計されていません。スライドのように、MySQL のように「共有データはデータストア層にプッシュされます」と書かれています。

代替案

コメット/ロングポーリングを行いたい場合は、代替手段を試す必要があると本当に思います。たとえば、次のような多くの言語を使用できます。

  • Java/JVM: Jettyの継続
  • Python: ダスティンのスロッシュ.
  • Erlang: comet などで人気のある言語。
  • ほんの数例を挙げると、Lua、Ruby、C、Perl。

簡単なGoogle検索を実行するだけで、PHPの多くの代替手段が表示されます(負荷が大きいとサーバーが停止すると思います)。

于 2009-08-24T23:26:57.897 に答える
7

PHP を使用する方法は mod_php だけではありません。fastcgi を使用できます。PHP は でコンパイルする必要があります--enable-fastcgi

FastCGI としての PHP: http://www.fastcgi.com/drupal/node/5?q=node/10

于 2009-03-02T17:46:20.003 に答える
6

https://github.com/reactphp/reactを試すこともできます

React は、PHP でのイベント駆動型プログラミング用の低レベル ライブラリです。そのコアにはイベント ループがあり、その上でストリームの抽象化、非同期 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();
于 2013-01-21T09:54:41.887 に答える
4

私は同様の問題を抱えています。私が興味深いと思っているオプションの 1 つは、cometd-java や cometd-python などの既存の Comet サーバーをコア メッセージ ハブとして使用することです。PHP コードは、Comet サーバーの単なるクライアントになります。他のクライアントと同様に、チャネルからメッセージを投稿または読み取ることができます。

ここにリンクされている興味深いコード スニペットがあります: http://morglog.org/?p=22=1このメソッドの一部を実装しています (ただし、デバッグ コードも散らばっています)。

于 2009-04-24T21:05:13.297 に答える
3

本質的にシングルスレッドであるという理由だけで、PHPでcometを実装するのは難しいでしょう。

Websync On-Demandをチェックしてください-このサービスでは、サーバー側の公開を介してPHPを統合し、大量の同時接続をオフロードし、リアルタイムのチャットアプリをすぐに作成できます。

于 2009-07-27T21:27:22.667 に答える
3

現在、ソケット関数を使用してスケーラブルな PHP Comet サーバーを実装しています。これは「phet」と呼ばれます ( [ph]p com[et] )

プロジェクトページ: http://github.com/Tim-Smart/phet

無料で開発に参加できます。私は現在、ほとんどのサーバーロジックを完成させることができました.クライアント側のものを完成させる必要があるだけです.

EDIT:メソッドを使用して最近追加された「マルチスレッド」機能pcntl_fork:)

于 2009-11-18T06:55:27.180 に答える
1

PHP を含む任意の言語で Comet を使用できるようにする、nginx Web サーバー用の新しいモジュールが登場しました。

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

于 2009-11-23T14:30:16.467 に答える
1

PHP で独自のサーバーを作成する必要があります。Apache/mod_php や fastcgi を使用しても、まったく拡張できません。数年前ですが、始めることができます:

PHP コメット サーバー: http://sourceforge.net/projects/comet/

于 2010-06-23T19:51:41.153 に答える
0

これは、多くのApacheスレッドを常に実行していることが問題であるというよりも問題だと思います。PHP(通常)と同じようにApacheを介して動作する場合、それはどの言語にも存在します。

于 2009-03-02T17:48:11.420 に答える