1

TCPリスナーコンポーネントにReactPHPを使用しています。このコンポーネントは、着信接続をリッスンし、それらとデータを交換します。$connections 配列は、クライアントがリスナーに接続/切断すると更新されます。

$loop = React\EventLoop\Factory::create();
$connections = [];
$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn) use($loop, $db){
    global $connections;
    $connections[] = $conn;
    $conn->on('data', function ($data) use ($conn,$loop, $db) {
        global $connections;
        // ...
        // ...
        $conn->on('close', function ($conn) use($loop, $db){
            global $connections;
            if(($key = array_search($conn, $connections, true)) !== FALSE) {
                unset($connections[$key]);
            }   
        });
});
$socket->listen(16555, '127.0.0.1');
$loop->run();

クライアントが telnet 経由で接続されている場合、'close' が出力されるため、閉じた接続を $connection 配列から削除できます。ただし、リスナーに接続する一部のデバイスにも問題があります。デバイスをオフにすると、「閉じる」は出力されません。定期的なタイマーの問題を解決しようとしました:

$loop->addPeriodicTimer(10, function () use($db, $loop){
    global $connections;
    foreach($connections as $c) {
        $remoteAddress = $c->getRemoteAddress();
        $metaData = @stream_get_meta_data($c->stream);
        if(!$metaData) {
            if(($key = array_search($c, $connections, true)) !== FALSE) {
                unset($connections[$key]);
            }   
        }
    }
});

しかし、それは十分に信頼できないようです。関数 stream_get_meta_data は、クライアントが切断されていても有効なメタデータ配列を返します。

4

1 に答える 1