Подтвердить что ты не робот

Может ли PHP асинхронно использовать сокеты?

Типичная функциональность сокета PHP является синхронной и останавливает поток при ожидании входящих соединений и данных. (например, socket_read и socket_listen)

Как сделать то же самое асинхронно? поэтому я могу отвечать на данные в полученном данных, вместо опроса для данных и т.д.

4b9b3361

Ответ 1

Yup, для чего socket_set_nonblock(). Предположим, что код взаимодействия сокетов должен быть написан по-разному, учитывая особые значения, которые допускают коды ошибок 11, EWOULDBLOCK и 115, EINPROGRESS.

Вот какой-то несколько вымышленный пример кода из цикла опроса сокетов PHP sync, по запросу:

$buf = '';
$done = false;
do {
    $chunk = socket_read($sock, 4096);
    if($chunk === false) {
        $error = socket_last_error($sock);
        if($error != 11 && $error != 115) {
            my_error_handler(socket_strerror($error), $error);
            $done = true;
        }
        break;
    } elseif($chunk == '') {
        $done = true;
        break;
    } else { 
        $buf .= $chunk;
    }
} while(true);

Ответ 2

Как сделать то же самое асинхронно? поэтому я могу реагировать на данные в данных полученное событие, вместо опроса для данные и т.д.

Вам нужно будет выполнить ваш script и выпустить stream_select, чтобы проверить, есть ли какие-либо данные для получения. Обработайте и отправьте данные назад.

Ответ 3

Термин "асинхронный" часто используется в сетевом программировании. Для ввода/вывода асинхронный часто используется как другое слово для неблокирования. Это означает, что процесс может продолжаться до того, как вызов в сети api завершил передачу.

Для выполнения процесса в целом асинхронный означает, что несколько команд могут быть вычислены сразу (одновременно).

Другими словами, асинхронный ввод-вывод не является по-настоящему асинхронным, если несколько потоков не используются, чтобы одновременно допускать множественные чтения/записи/принятия - все сокеты должны подождать синхронного неблокирующего вызова, если у него есть данные для чтения/записи или в противном случае не блокировать, а чтение/запись большого файла может занять секунды или даже минуты, если не прерваться. Обратите внимание, что для этого потребуется идеальный поток между клиентом и сервером, а сам TCP прервет передачу. Например, загрузка сервера быстрее, чем клиент может загрузить, приведет к блокировке записи.

Итак, со строгой точки зрения PHP не способен выполнять асинхронную сеть, только не блокируя. Короче говоря, прогрессирование процесса прекратится, когда сетевой вызов сможет с пользой читать/писать и т.д. Однако процесс будет продолжаться, когда вызов не сможет с пользой читать/писать или в противном случае блокируется. В действительно асинхронной системе процесс будет продолжаться независимо, а чтение/запись будет выполняться в другом потоке. Обратите внимание, что блокировка ввода-вывода все равно может выполняться асинхронно, если выполняется в другом потоке.

Кроме того, PHP не может выполнять операции ввода-вывода с событиями без установки расширения, которое его поддерживает. В противном случае вам нужно будет сделать какую-либо форму опроса, чтобы делать неблокирующие операции ввода-вывода в PHP. Код из Chaos был бы функциональным неблокирующим примером чтения, если он использовал socket_select.

С учетом сказанного функция выбора по-прежнему будет допускать истинное неблокирующее поведение в PHP. В C службы опроса имеют потерю производительности по сравнению с управляемым событием, поэтому я уверен, что он будет таким же для PHP. Но эта потеря находится в наносекундах-микросекундах в зависимости от количества сокетов, где время, сохраненное от неблокирующего вызова, обычно составляет миллисекунды или даже секунды, если вызов сделан для ожидания.

Ответ 4

AFAIK PHP строго односторонне, что означает, что вы не можете делать это асинхронно, потому что выполнение Script всегда линейно.

Прошло некоторое время с тех пор, как я это сделал, но, насколько я помню, вы можете только открыть сокет и продолжить выполнение Script при получении данных.