Как использовать PHP stream_select() с фильтром zlib?

В настоящее время у меня есть демон сервера, написанный на PHP, который принимает входящие соединения и создает для них сетевые потоки, используя функции stream_socket_*, и опрашивает активные потоки, используя stream_select(). Я хотел бы иметь возможность добавить фильтр zlib (используя string_filter_append()) к произвольному потоку, но когда я это делаю, я получаю сообщение об ошибке, говорящее мне, что stream_select() нельзя использовать для опроса отфильтрованного потока.

Как я могу обойти это ограничение?


person drrcknlsn    schedule 26.08.2011    source источник


Ответы (1)


Вы можете использовать канал и вместо этого добавить фильтр в канал.

Это позволит вам использовать stream_select для потока, а канал будет служить буфером для zlib.

Прочитайте необработанные данные из потока select()ed, запишите их в канал и прочитайте декодированные данные на другой стороне :)

list($in, $out) = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);

stream_filter_append($out, 'zlib.inflate', STREAM_FILTER_READ);
stream_set_blocking($out, 0);

while (stream_select(...)) {
    // assuming that $stream is non blocking
    stream_copy_to_stream($stream, $in);

    $decoded_data = stream_get_contents($out);
}

То же самое, вероятно, может быть достигнуто с потоком памяти php://.

person Arnaud Le Blanc    schedule 26.08.2011
comment
Спасибо, этот метод, похоже, позволяет мне обойти ограничение, однако я использую zlib.deflate и не копирую поток в поток, а просто использую fwrite() для отправки сгенерированных сервером данных через исходящие сетевые потоки. Используя этот метод, stream_get_contents($out) возвращает 2-байтовый заголовок zlib и ничего больше. Если я записываю одни и те же данные в файл, а не записываю в $in и считываю $out, сжатые $данные записываются полностью. Есть ли что-то в этом методе, что помешало бы считывать полные сжатые данные из $out? - person drrcknlsn; 29.08.2011
comment
Фильтр может выполнять запись в поток только после того, как будет записано некоторое количество данных; попробуйте записать больше данных. Также попробуйте использовать фильтр zlib.deflate на стороне записи с STREAM_FILTER_WRITE VS на стороне чтения с STREAM_FILTER_READ. - person Arnaud Le Blanc; 29.08.2011