Webプログラミングでは、通常、PHPはHTTP要求を処理するために使用されますが、実際にはPHPは、TCP通信関数を実装するために使用できるSocket_*シリーズ関数を含むリッチな基礎となるネットワーク操作機能も提供します。この記事では、PHP socket_accept()関数に基づいてシンプルなチャットルームアプリケーションプロトタイプを構築する方法を示して、PHPのソケットプログラミングメカニズムを理解するのに役立ちます。
チャットルームの基本的なメカニズムは次のとおりです。サーバーはポートに耳を傾け、複数のクライアントがソケットを介してサーバーに接続し、サーバーはクライアントの接続( socket_accept()を介して)を受け入れ、受信したメッセージを他のすべてのクライアントにブロードキャストします。
サーバーは、ソケットの作成、バインディングポート、接続のリスニング、ループでのクライアント接続の受け入れ、およびメッセージの処理と転送を担当します。
<?php
$host = '0.0.0.0';
$port = 12345;
$clients = [];
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, $host, $port);
socket_listen($server);
echo "Server started on $host:$port\n";
while (true) {
$read = $clients;
$read[] = $server;
$write = $except = null;
if (socket_select($read, $write, $except, null) < 1) {
continue;
}
if (in_array($server, $read)) {
$client = socket_accept($server);
if ($client) {
socket_getpeername($client, $addr, $port);
echo "Client connected: {$addr}:{$port}\n";
$clients[] = $client;
socket_write($client, "チャットルームへようこそ!\n");
}
unset($read[array_search($server, $read)]);
}
foreach ($read as $sock) {
$data = @socket_read($sock, 2048, PHP_NORMAL_READ);
if ($data === false) {
$index = array_search($sock, $clients);
socket_getpeername($sock, $addr, $port);
echo "Client disconnected: {$addr}:{$port}\n";
unset($clients[$index]);
socket_close($sock);
continue;
}
$data = trim($data);
if (!empty($data)) {
socket_getpeername($sock, $addr, $port);
$message = "[{$addr}:{$port}] 説明する: {$data}\n";
foreach ($clients as $client) {
if ($client !== $sock) {
socket_write($client, $message);
}
}
echo $message;
}
}
}
クライアントは、Telnetを使用するか、ブラウザを使用してWebsocket Proxyに接続できます。ただし、PHPを使用してクライアントをシミュレートしてメッセージを送信する場合は、次のコードを使用することもできます。
<?php
$host = '127.0.0.1';
$port = 12345;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $host, $port);
echo socket_read($socket, 2048);
while (true) {
echo "メッセージを入力してください: ";
$msg = trim(fgets(STDIN));
if ($msg === 'exit') {
break;
}
socket_write($socket, $msg . "\n");
$response = socket_read($socket, 2048);
echo "メッセージを受け取りました: " . $response;
}
socket_close($socket);
マルチプロセスサポート: PCNTL_FORK()を使用して、メインプロセスのブロックを避けるためにマルチプロセスサポートを実現できます。
ログ管理:各メッセージにタイムスタンプを追加して、後でトラブルシューティングを容易にします。
ID :各クライアントにニックネームまたはIDを設定すると、ユーザーエクスペリエンスが向上します。
フロントエンド接続:WebSocketの転送を介してPHPチャットルームをWebページのフロントエンドと統合し、通信ブリッジのhttp://m66.net/socket-proxyと同様のミドルウェアを使用できます。
socket_accept()などのPHPソケット機能を介して、コマンドライン環境で基本的なチャットサービスを実装できます。 PHPはリアルタイム通信の主流言語ではありませんが、その基礎となる機能を使用して、ネットワークプログラミングメカニズムを学習するための導入例として適しています。生産環境に展開する場合は、よりプロフェッショナルなメッセージキューと非同期サーバーフレームワークを組み合わせて、パフォーマンスと安定性を向上させることをお勧めします。