2016-01-08 3 views
0

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

<?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, но это либо отбрасываются или используется в опасный путь, прежде чем ожидало (Typing [4015])

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

Но я не хочу, чтобы блокировать и ждать 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.

Я настоятельно рекомендую вам прочитать (недавно переписанный) official documentation of async, который объясняет, для чего он хорош и как его использовать.

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

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

+0

Спасибо за ответ! Должен быть [EventLoop] (https://en.wikipedia.org/wiki/Event_loop) в качестве поддержки async/awac для bacground. Поэтому, когда я вызываю функцию async без ожидания, я просто ожидаю добавить новое событие в EventLoop и продолжить выполнение текущей функции. У меня есть бесконечный сервер [Coroutine] (https://en.wikipedia.org/wiki/Coroutine). Поэтому я ожидаю, что обработчики handClient будут гарантированы. – Aleksandrlat

+0

Возможно, причиной моей проблемы является эта ошибка https://github.com/facebook/hhvm/issues/6500.Но я точно не знаю. Может быть, я делаю что-то неправильно. – Aleksandrlat

+0

Вы делаете что-то не так :) Контур события/сопрограммы не совсем так, как вы хотите думать о async в Hack. Выполнение функции async не добавляет ее в какой-либо автоматический цикл событий. Пожалуйста, прочтите документацию, описанную выше - у вас неправильная ментальная модель для того, как async работает полностью. –