PHPのsocket_set_blocking関数は、ソケットリソースのブロッキングモードを設定するために使用されます。
ブロッキングモード:ソケット関連の機能を呼び出すときは、操作が完了するのを待つと、この期間中にプログラムが一時停止します。
非ブロッキングモード:ソケット関連の機能を呼び出すときにすぐに戻り、操作が完了するのを待ちません。
デフォルトでは、ソケットはブロックしています。ブロッキングモードは、単純な同期シナリオに適していますが、高性能サーバーには、より詳細な制御フローメカニズムが必要です。
bool socket_set_blocking ( resource $socket , bool $mode )
$ソケット:ソケットリソース。
$モード: trueはブロックを意味し、 falseは非ブロックを意味します。
コントロールフローは、メッセージの送信および受信リズムを管理して、メッセージの送信が速すぎるのを防ぎ、ネットワークの輻輳、過度のリソースの使用、またはメッセージの損失をもたらします。制御フローのある設計を実装できます。
キューメッセージバッファリング、段階的に送信します。
ブロッキングモードと非ブロッキングモードを動的に切り替えます。
タイムアウト処理とエラー再試行メカニズム。
サーバーとクライアントの両方がブロッキングモードを使用して、送信と受信の安定性を確保します。
メッセージを送信し、送信バッファーにデータがある場合にのみ送信して、ブロッキングや待機を防ぎます。
レシーバーは、長期的なハングを避けるために合理的なタイムアウトを設定します。
socket_selectを使用して、多重化を実現し、読み取りと書き込みイベントを監視し、効率を向上させます。
以下は、 Socket_set_blockingを使用してブロッキングモードを制御してメッセージングのフロー制御を実現する方法を示す、単純化されたTCPベースのPHPソケットサーバーの例です。
<?php
$host = "0.0.0.0";
$port = 12345;
// 作成するsocket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, $host, $port);
socket_listen($sock);
echo "Server started at $host:$port\n";
// 監視をセットアップしますsocketブロッキングモードで,接続を受け入れるときにクライアントを待っています
socket_set_blocking($sock, true);
$clients = [];
while (true) {
// 使用 socket_select アクティブな接続を聞いてください
$read = $clients;
$read[] = $sock; // モニターに参加しますsocket
$write = [];
$except = null;
// アクティビティを待っているブロックsocket
if (socket_select($read, $write, $except, 5) < 1) {
continue; // タイムアウトアクティビティなし
}
// 新しい接続を処理します
if (in_array($sock, $read)) {
$newClient = socket_accept($sock);
if ($newClient !== false) {
socket_set_blocking($newClient, true); // クライアントのセットアップsocketブロッキング用,完全なメッセージを保証します
$clients[] = $newClient;
echo "New client connected\n";
}
unset($read[array_search($sock, $read)]);
}
// 既存のクライアントメッセージを処理します
foreach ($read as $client) {
$data = socket_read($client, 2048, PHP_NORMAL_READ);
if ($data === false || $data === '') {
// クライアントの切断
echo "Client disconnected\n";
socket_close($client);
unset($clients[array_search($client, $clients)]);
continue;
}
$data = trim($data);
echo "Received: $data\n";
// 単純なエコー,フロー制御付き:送信する前に確認してくださいsocketブロッキングモード,書き込み障害を防ぎます
socket_set_blocking($client, true);
$sendResult = socket_write($client, "Echo: $data\n");
if ($sendResult === false) {
echo "Failed to send message to client\n";
}
}
}
ブロッキングモードの切り替え<br> リスニングソケットとクライアントソケットの両方がブロックするように設定されているため、データの整合性を保証し、データを読み書きするときに保証でき、非ブロッキングモードでの短い読み取りと短い書き込みのために不完全なメッセージを避けます。
socket_selectは多重化を聞きます
Socket_Selectはブロックし、ソケットが読みやすくなるのを待ち、CPUの使用率を改善し、デッドループでリソースの無駄を避けます。
メッセージキューコントロール(拡張可能)
この例で直接読み取られて書かれていますが、クライアントネットワークの混雑を避けるために送信された各メッセージのサイズと頻度を制御する必要性に応じて、メッセージキューを追加できます。
非ブロッキングモードを使用して、イベント駆動型ライブラリ(Libeventなど)と協力して、高い並行性パフォーマンスを向上させます。
メッセージのシリアル番号と確認メカニズムを紹介して、メッセージ伝送の整合性を確保します。
ハートビートパケット検出接続ステータスを実装します。
socket_set_optionを使用して、TCP_NODELAYを設定するなどのTCPパラメーターを最適化してレイテンシを減らします。
PHPのsocket_set_blocking関数を合理的に使用し、 socket_selectイベントリスニングメカニズムを組み合わせることにより、制御フローを備えた効率的なメッセージングと受信システムを構築できます。制御フローは、メッセージ伝達の安定性を保証するだけでなく、システムの応答速度とリソースの利用を改善します。この記事の例とアイデアが、独自のメッセージシステムを構築する際に役立つことを願っています。