一般的なPHPソケットの機能は同期しており、着信接続とデータを待っているときにスレッドを停止します。 (例:socket_read
とsocket_listen
)PHPは非同期的にソケットを使用できますか?
私はどのように非同期的に行うのですか?データをポーリングするのではなく、データ受信イベントのデータに応答することができます。
一般的なPHPソケットの機能は同期しており、着信接続とデータを待っているときにスレッドを停止します。 (例:socket_read
とsocket_listen
)PHPは非同期的にソケットを使用できますか?
私はどのように非同期的に行うのですか?データをポーリングするのではなく、データ受信イベントのデータに応答することができます。
うわー、それはsocket_set_nonblock()
のためです。ソケットインタラクションコードは、エラーコード11、EWOULDBLOCK
、および115、EINPROGRESS
が想定する特別な意味を考慮して、別々に書き込まれる必要があります。
要求されるようにここでは、PHPのシンクロソケットポーリングループからのいくつかのやや-架空のサンプルコードです:スクリプトの実行が常にあるので
$buf = '';
$done = false;
do {
$chunk = socket_read($sock, 4096);
if($chunk === false) {
$error = socket_last_error($sock);
if($error != 11 && $error != 115) {
my_error_handler(socket_strerror($error), $error);
$done = true;
}
break;
} elseif($chunk == '') {
$done = true;
break;
} else {
$buf .= $chunk;
}
} while(true);
私の知る限りPHPは、あなたが非同期的にこれを行うことはできませんを意味し、厳密にsinglethreadedですリニア。
私はこれをやってからしばらくしていましたが、私が思い出す限り、あなたはソケットを開いて、データを受信するとスクリプトを実行し続けることができます。
カオスのコードサンプルでさえ、この事実を裏付けるようです。 –
PHPは、posix select()に類似した非同期ソケット操作のためのstream_selectを提供します。 – karunski
select()は同期式です。ソケットが読み込み/書き込みの準備ができているかどうかを知ることができます。それでも、単一のスレッドから呼び出し、read()またはwrite()の代わりにselect()呼び出しをブロックします。 –
これをどのように非同期で行うのですか? は、私はなど、 データの代わりにポーリング、データ 受信したイベントのデータに対応できる
あなたのスクリプトを実行し、受信するすべてのデータがあるweitherチェックしてstream_select発行する必要があります。データを処理して送信します。
「非同期」という用語は、ネットワークプログラミングでよく誤用されます。 I/Oの場合、非同期は非ブロッキングの別の単語として使用されることがよくあります。これは、ネットワークapiの呼び出しが送信を完了する前にプロセスを続行できることを意味します。一般に、プロセス実行のため
、非同期は、複数の命令を一度に計算することができることを意味する(同時に)
言い換えれば、複数のスレッドが複数できるようにするために使用されていない限り、非同期I/Oは真に非同期ではありませんread/write/acceptsが並行して発生する - すべてのソケットは、読み書きするデータを持っているかブロックされていない場合に非同期非同期呼び出しを待たなければならず、大きなファイルを読み書きするのに数秒かかる中断されなければ数分でさえあります。これは、クライアントとサーバーの間の完全なフローを必要とするか、TCP自体が送信を中断することに注意してください。たとえば、クライアントがダウンロードできるよりも高速に送信するサーバーは、書き込み時にブロックを発生させます。
厳密な観点から、PHPは非ブロッキングのみの非同期ネットワーキングを実行できません。要するに、プロセスの進行は、ネットワークコールが有用に読み書きすることができる間に停止する。しかし、プロセスは、コールが有用に読み書きすることができないか、そうでなければブロックするときに継続する。真に非同期のシステムでは、プロセスは関係なく継続され、読み書きは別のスレッドで行われます。 I/Oのブロックは、別のスレッドで実行された場合でも非同期で実行できます。
さらに、PHPは、イベント駆動型入出力をサポートする拡張機能をインストールしないと、イベント駆動型入出力を実行できません。 PHPで非ブロッキングI/Oを実行するには、別の方法でポーリングを行う必要があります。 Chaosのコードは、socket_selectを使用した場合、機能的な非ブロック読み取りの例になります。
これで、select関数はPHPで真の非ブロック動作を可能にします。 Cでは、ポーリングサービスはイベント駆動よりもパフォーマンスが低下するので、PHPでも同じであると確信しています。しかし、この損失は、非ブロッキング呼び出しから保存された時間が通常ミリ秒であるソケットの量に応じてナノ秒 - マイクロ秒であり、呼び出しが待機する場合は秒ですらあります。
どういう意味ですか?非同期データ受信イベントのコードサンプルを表示できますか? –
これは同期ですが、非ブロックですか?それでは、ノンブロッキングとはどういう意味ですか? –
いいえ、非同期で、ポーリングベースです。コードはより大きなポーリングメカニズムからのものです。 PHPは、私が知る限り、あなたが求めているような割り込み/シグナル駆動のソケットI/Oイベントをサポートしていません。完了を待たず直ちに戻り、指示されたエラーコードで操作が準備できていない場合は、非同期通信を実現します。ノンブロッキングソケット上の読み取りと似ています。 Cでの非同期ソケットの使用に関するチュートリアルがたくさんありますが、これについては多くの詳細が説明されています。 PHPのサポートは、標準的なCの上の単なるレイヤーです。 – chaos