👌

【PHP】HTTP/1 サーバーに stream_select を使う

2024/07/22に公開
<?php

# https://www.php.net/manual/ja/function.stream-select.php#122839

$host = "tcp://0.0.0.0:8000";
$socket = stream_socket_server(
    $host, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN
);
stream_set_blocking($socket, 0);

$msg = "HTTP/1.1 200 OK\r\n".
       "Content-Type: text/html; charset=UTF-8\r\n".
       "Content-Length: 12\r\n".
       "Connection: Close\r\n".
       "\r\n".
       "Hello World\n";

$connections = [];
$read = [];
$write = null;
$except = null;

printf("serving %s\n", $host);

while (true) {
    if ($c = stream_socket_accept($socket, 10, $peer)) {
        $connections[$peer] = $c;
    }

    $read = $connections;

    if (!stream_select($read, $write, $except, 10)) {
        continue;
    }

    foreach ($read as $c) {
        $peer = stream_socket_get_name($c, true);
        $input = fread($c, 1024);
        fwrite($c, $msg);

        if (empty($input)) {
            echo 'Connection closed '.$peer.PHP_EOL;
            print($input);
            fclose($c);
            unset($connections[$peer]);
        }
    }
}

Discussion