だから私は通常のPHPソケットを手に入れました(PHPマニュアルの例とほぼ同じコードです)。クライアントがいつ接続を切断したかを検出する方法を見つけました (正常に切断されたかどうかに関係なく)。同じ IP を持つ複数のユーザーが存在する可能性があるため、IP アドレスの使用は停止されています。
前もって感謝します。
TCPまたは UDP パケット ヘッダーで何が配信されるかを考えると、IP アドレスだけが含まれているだけで、多くの ID 情報は含まれていません。クライアントの身元を知りたい場合は、ある種の一意の識別子 (@madara がコメントしたユーザー名とパスワードなど) をクライアントに送信させる必要があります。同じ IP からのものである場合、同じルーターを使用していることを意味します。この場合、その目的は、ルーターの背後にあるデバイスをマスクすることです。
誰が切断したかを検出するには、まず誰が接続したかを特定する必要があります。同じ IP アドレスからの接続であっても、各接続は独自のソケットを取得します。疑似phpで:
// Store all active sockets in an array
$online_users = array();
// Open up a listening socket
$listener = socket_create(...);
socket_listen($listener);
$client_sock = socket_accept($listener);
// Have the client send authentication stuff after connecting and
// we'll receive it on the server side
$username = socket_read($client_sock, $len);
// Map the username to the client socket
$online_users[$username] = $client_sock;
// Continue to read or write data to/from the sockets. When a read or
// write fails, you just iterate through the array to find out who
// it was. If the socket $failed_sock failed, do as follows
foreach ($online_users as $name => $socket)
{
if ($socket == $failed_sock)
{
// $name is the username of the client that disconnected
echo $name . ' disconnected';
// You can then broadcast to your other clients that $name
// disconnected. You can also do your SQL query to update the
// db here.
// Finally remove the entry for the disconnected client
unset($online_users[$name]);
}
}
論理的にあなたの場合、これは難しいものです!ここにただのアイデアがあります:
チャットの場合は、すべてのオンラインユーザーを次の列のデータベースまたはフラットファイルに保存するのはどうですか。
NICKNAME
IP
TIME
そして、これらをチェックし、それに応じて、たとえば10秒ごとに時間を更新する関数を作成します。これに基づいて、いつ誰がオンライン/オフラインであるかを判断できます。
- - - アップデート - - -
ソケットエラーを確認しますか?get_last_error()を使用して、エラーコードを確認します。
$errorcode = socket_last_error();
$errormsg=socket_strerror($errorcode);
die("Error: (".$errorcode.") ".$errormsg."\n");
ユーザーの設定を解除します。
if($data === FALSE) {
socket_close($clients[$i]['socket']);
unset($clients[$i]);
echo 'Client disconnected!',"\r\n";
continue;
}
データベースからクライアントの設定を解除します。$clients配列からIDによって正確なニックネームを識別することもできます。