PHPでcometを使用していますか?


82

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

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

これは本当ですか?それとも、周りに構成できるものですか?


4
あなたは... FastCGIのようにPHPを実行することができます
イタイMoav -Malimovka

4
nodeJSをサーバーとして使用してクライアント接続を維持し、javascriptのWebSocketを使用してブラウザーからサーバーに接続します。この意味でのPHPは、nodejsに接続し、クライアント側で何らかの方法で処理されるサービスデータをプッシュする特権クライアントになることができます。
Artjom Kurapov 2012年

1
@ArtjomKurapov PHPをWebサーバーにして、Apacheのリクエスト処理方法をバイパスすることができます。これは、コメットリクエストのみを処理する実際のPHPサーバーのように考えてください。
クリスチャン

@Christian 5.4以降の組み込みのphpWebサーバーを意味する場合、開発専用であり、
本番環境で

2
@ArtjomKurapovいいえ、PHPソケットを使用してポート80をリッスンし、入力を無期限にブロックすることで、実際のP​​HPサーバーを作成することを意味しました。事実上サーバーの動作です。これは、phpwebsocketのようなプロジェクトですでに実際に見られます。
クリスチャン

回答:


61

すでに言われていることに同意/拡大すると、FastCGIが問題を解決するとは思わない。

Apache

Apacheへの各リクエストは、リクエストが完了するまで1つのワーカースレッドを使用します。これは、COMETリクエストの場合は時間がかかる場合があります。

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

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

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

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

PHP

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

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

編集:

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


20
私はこれが正確に解決策を提供しないことを理解しています:/
マイクヒューストン

Apache / PHPは、彗星ソリューションをスケールアウトするための適切なオプションではないため、+ 1。PHPユーザー向けのオプションは、1)前述のように、追加のサーバーとプロキシのクレイジーな構成、または2)SaaSソリューションを使用し、WebSyncOn-Demandなどを介してコメットのものをオフロードすることです。
jvenema 2010

1
これはいくつかの面で間違っています。ユーザーごとに1スレッドのメソッドを残したい場合は、Apacheを仲介者として削除し、PHPにこれらのリクエストを処理させることで簡単に実現できます。もちろん、Apacheはコンテンツの提供に優れているため、コンテンツを提供しないサブドメインでこのApacheのないPHPサーバーを実行します。
クリスチャン

@MikeHouston IISでphpを使用してcometを試すのはどうですか?
ravi404 2012

@ ravz、IISとcometについてここにいくつかのものがあります:stackoverflow.com/questions/1898848/comet-programming-in-iis、しかし私はfast-cgiPHPモジュールがapacheと同じ制限を持っていると思います。ここでは、シングルスレッド環境について説明しています。microsoft.com / web / platform / phponwindows.aspx-私はWindowsサーバーを自分で使用していないため、スレッドモデルについてはよくわかりません。
マイクヒューストン

14

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

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

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


10

PHP

単純な彗星を説明するこの面白い小さなスクリーンキャストを見つけました。ちなみに、これは実際の負荷でサーバーを強制終了すると思います。ユーザーが数人いる場合は、このソリューションを選択するだけです。このソリューションは実装が非常に簡単です(スクリーンキャストは5分しかかかりません:))。しかし、前に言ったように、それは多くの同時ユーザーにとっては良いことではないと思います(あなたはそれをベンチマークするべきだと思います;))理由は:

  1. ファイルI / Oを使用しますが、これはメモリからデータを取得するよりもはるかに低速です。たとえば関数のようにfilemtime()
  2. 第二に、しかし私は少なくともPHPがまともなスレッドモデルを持っていないと思います。PHPは、シェアードナッシングモデルのため、このために設計されていません。スライドのように、たとえばMySQLのように、「共有データはデータストアレイヤーにプッシュダウンされます」と書かれています。

代替案

彗星/ロングポーリングを行いたい場合は、別の方法を試してみるべきだと思います。たとえば、次のような多くの言語を使用できます。

  • Java / JVM:桟橋の続き
  • Python:ダスティンのスロッシュ
  • Erlang:彗星などに人気のある言語。
  • ほんの数例を挙げると、Lua、Ruby、C、Perl。

単純なグーグル検索を実行するだけで、PHPも多くの選択肢が表示されます(大きな負荷がかかるとサーバーが停止すると思います)。


7

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

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


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

4

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

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


3

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

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

開発に無料で参加できます。私は現在、サーバーロジックのほとんどを実行することができましたが、クライアント側のものを終了する必要があります。

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


このライブラリの使用方法についてすぐに利用できる例はありません。
ftrotter 2012年

3

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

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



1

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

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


0

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


1
重要なのは、通常、リクエストごとのスレッドではなく、リクエストごとのプロセスでphpを実行するということです。
troelskn 2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.