Асинхронный сервер в хакланге

Я пытаюсь создать асинхронный сервер в Hacklang. Имя файла first.php:

<?hh

namespace MyExperiment;

async function server(string $host, int $port): Awaitable<void> {
    $master = stream_socket_server("tcp://$host:$port");
    stream_set_blocking($master, 0);

    while (true) {
        await stream_await($master, STREAM_AWAIT_READ, 1.0);

        $clientSocket = stream_socket_accept($master);
        stream_set_blocking($clientSocket, 0);

        handleClient($clientSocket);
    }
}

async function handleClient($socket): Awaitable<void> {
    await stream_await($socket, STREAM_AWAIT_READ, 1.0);

    $data = fread($socket, 1024);
    echo $data;

    await stream_await($socket, STREAM_AWAIT_WRITE, 1.0);

    fwrite($socket, 'aaaaaaaa');

    fclose($socket);
}

function run(): void {
    \HH\Asio\join(server('192.168.0.97', 8080));
}

run();

Но это не работает. hh_client в этом коде говорит:

first.php: 16: 3,29: Это выражение относится к типу Awaitable, но оно либо отбрасывается, либо используется опасным образом перед ожиданием (набрав [4015])

first.php: 20: 39,47: Вот почему я думаю, что это ожидаемый

Но я не хочу блокировать и ждать handleClient.

Затем я запускаю код следующим образом: hhvm -d hhvm.hack.lang.auto_typecheck=0 first.php

Сервер запускается. Но когда я начинаю отправлять запросы на сервер http://192.168.0.97:8080/ из браузера, сервер блокирует после нескольких запросов в течение очень долгого времени и больше не принимает новые подключения.

Я делаю что-то не так? Можно ли вообще создать такой сервер в хакланге?

$ hhvm --version
HipHop VM 3.11.0 (rel)
Compiler: tags/HHVM-3.11.0-0-g3dd564a8cde23e3205a29720d3435c771274085e
Repo schema: 52047bdda550f21c2ec2fcc295e0e6d02407be51

1 ответ

Но я не хочу блокировать и ждать handleClient.

Ну, если ты не await их, то нет гарантии, что они будут работать! Асинхронная функциональность Hack позволяет асинхронно запускать различные выборки данных, но вам нужно как-то получить результат. Поскольку вы написали этот код, HHVM не дает никаких обещаний о том, сколько handleClient собирается бежать. Это может быть все это, это может быть ни одно из этого, это может приостановить handleClient случайно await заявление в середине этого.

Непонятно, что именно вы пытаетесь сделать здесь, но асинхронность может быть не подходящим средством для этого. Асинхронность Hack не является многопоточностью, и, похоже, вы пытаетесь использовать ее таким образом. Для этого придерживайтесь модели PHP "один запрос - один поток".

Я настоятельно рекомендую вам прочитать (недавно переписанную) официальную документацию async, в которой объясняется, для чего она нужна и как ее использовать.

Затем я запускаю код следующим образом: hhvm -d hhvm.hack.lang.auto_typecheck=0 first.php

Не выключайте проверку типов - это означало, что с вашим кодом что-то не так с самого начала.:)

Другие вопросы по тегам