Типичная функциональность сокета PHP является синхронной и останавливает поток при ожидании входящих соединений и данных. (например, socket_read
и socket_listen
)
Как сделать то же самое асинхронно? поэтому я могу отвечать на данные в полученном данных, вместо опроса для данных и т. д.
Да, это то, что для socket_set_nonblock()
. Код взаимодействия сокетов должен быть написан по-разному, учитывая особые значения, которые EWOULDBLOCK
коды ошибок 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);
Как сделать то же самое асинхронно? поэтому я могу отвечать на данные в полученном данных, вместо опроса для данных и т. д.
Вам нужно будет выполнить свой скрипт и выпустить stream_select, чтобы проверить, есть ли какие-либо данные для получения. Обработайте и отправьте данные назад.
Термин «асинхронный» часто используется в сетевом программировании. Для ввода / вывода асинхронный часто используется как другое слово для неблокирования. Это означает, что процесс может продолжаться до того, как вызов в сети api завершит передачу.
Для выполнения процесса в целом асинхронный означает, что несколько команд могут быть вычислены сразу (одновременно).
Другими словами, асинхронный ввод-вывод не является по-настоящему асинхронным, если только несколько потоков используются для одновременного одновременного выполнения нескольких операций чтения / записи / принятия – все сокеты должны подождать синхронного неблокирующего вызова, если у него есть данные для чтения / написано или иначе не будет блокироваться, а чтение / запись большого файла может занимать секунды или даже минуты, если не прерывается. Обратите внимание, что для этого потребуется идеальный поток между клиентом и сервером, а сам TCP прервет передачу. Например, загрузка сервера быстрее, чем клиент может загрузить, приведет к блокировке записи.
Таким образом, с жесткой точки зрения PHP не способен выполнять асинхронную сеть, только не блокируя. Короче говоря, прогрессирование процесса прекратится, когда сетевой вызов сможет с пользой читать / писать и т. Д. Однако процесс будет продолжаться, когда вызов не сможет с пользой читать / писать или в противном случае блокируется. В действительно асинхронной системе процесс будет продолжаться независимо, а чтение / запись будет выполняться в другом потоке. Обратите внимание, что блокирование ввода-вывода все равно может выполняться асинхронно, если выполняется в другом потоке.
Более того, PHP не может выполнять операции ввода-вывода с событиями без установки расширения, которое его поддерживает. В противном случае вам нужно будет сделать какую-либо форму опроса, чтобы делать неблокирующие операции ввода-вывода в PHP. Код из Chaos был бы функциональным неблокирующим примером чтения, если он использовал socket_select.
С учетом сказанного функция выбора по-прежнему допускает истинное неблокирующее поведение в PHP. В C службы опроса имеют потерю производительности по сравнению с управляемым событием, поэтому я уверен, что он будет таким же для PHP. Но эта потеря находится в наносекундах-микросекундах в зависимости от количества сокетов, где время, сохраненное от неблокирующего вызова, обычно составляет миллисекунды или даже секунды, если вызов заставит ждать.
AFAIK PHP строго singlethreaded, что означает, что вы не можете делать это асинхронно, потому что выполнение скрипта всегда линейно.
Прошло некоторое время с тех пор, как я это сделал, но, насколько я помню, вы можете только открыть сокет и продолжить выполнение скрипта при получении данных.