асинхронный — реализация WebSockets, теория и реальность в переполнении стека

Этот вопрос связан с теорией, как и с программированием в реальной жизни. Я впервые задал этот вопрос на (cs.stackexchange.com), потому что это теория, и у меня была инструкция спросить здесь (https://cs.stackexchange.com/questions/81472/question-about-implementing-websockets-theory-and-the-reality-in-php)

Я экспериментирую с веб-сокетами и PHP уже много лет (часть этого кода уже работает), сначала я создал сервер WebSocket (WS) с нуля с неблокирующим вводом-выводом, и все работало нормально, за исключением реальных методов, необходимых для приложение не может быть неблокирующим (например, подключение к БД и запрос). Затем я ввел асинхронное программирование, то есть WS-сервер инициировал различные PHP-запросы к серверу и проверял в каждом цикле, закончили ли эти запросы результаты, чтобы отправить их клиенту. Это работало хорошо для немногих пользователей на стороне клиента, подключенных к этому WS-серверу, число было связано с тем, какова была операция, но не было бы больше 30 или 50. Это было потому, что если вы используете только один поток и у вас есть много одновременных запросы вы должны проверить каждый из них последовательно, если есть готовый результат.

Следующим шагом было проанализировать код популярных подходов, утверждающих, что он может одновременно хранить и обрабатывать множество (некоторые говорят, 10000) клиентов. Возможно, они знали что-то, чего я не знал (моя проблема не в том, лгут ли они, проблема в том, есть ли здесь что-то, чего я упускаю (или, может, я ошибаюсь)). Результаты были разочаровывающими. Большинство из них не используют асинхронность по умолчанию, советуя вам не использовать методы блокировки (что на самом деле невозможно в программировании в реальной жизни), но даже если вы добавите к ним модули, чтобы сделать их асинхронными, та же проблема, что у меня возникла.

Вопрос не в том, что является решением, потому что я реализовал PHP pthreads и смог заставить его работать, но без реальной выгоды (например, при совместном использовании объектов он должен был сериализовать и не сериализовать все), я пишу расширения C ++ PHP уже несколько лет, поэтому Я работаю в расширении PHP, которое будет делать это эффективно.

Вопрос здесь в том, что я что-то упустил? Как они могут утверждать, что могут обрабатывать большое количество запросов одновременно, в то время как даже при асинхронном программировании они должны проверять каждый запрос в завершенном цикле?

Заранее благодарим вас за любые новые знания или указания для поиска, что ваш ответ может привести меня.

1

Решение

Да, есть проекты, которые делают это возможным с помощью PHP. Одним из таких проектов является ампер с этими Aerys HTTP и WebSocket сервер. Да, вы не можете просто вызывать блокирующие функции в одном потоке. Да, pthreads не поможет, это, в основном, просто запуск другого процесса PHP, потому что все в PHP ничего не передается. Но как это работает тогда?

Используйте неблокирующие реализации, где это возможно. Существуют библиотеки, которые работают с неблокирующим вводом / выводом для доступа к базе данных, такие как amphp/mysql.

Если такой библиотеки нет, спросите, можно ли реализовать что-то подобное, если вы не хотите / не можете реализовать это самостоятельно.

Другая возможность заключается в использовании библиотек, таких как amphp/parallel которые используют постоянных работников для блокировки задач. Порождение другого работника для каждой задачи блокировки будет ужасно неэффективным, так что библиотека позволяет легко использовать рабочие пулы и поддерживать этих рабочих для выполнения нескольких задач каждая.

Одна такая библиотека, которая использует amphp/parallel является amphp/file, который использует эти рабочие для неблокирующего доступа к файловой системе, когда нет таких расширений, как uv или же eio доступны, может быть, вы хотите, чтобы посмотреть на его ParallelDriver.

Сколько соединений вы сможете обрабатывать одновременно, во многом зависит от вашего оборудования и от того, что вы делаете с этими соединениями. Если вы будете постоянно передавать данные каждому клиенту, вы сможете держать гораздо меньше открытых соединений, чем в ситуации, когда большинство соединений простаивают и отправляют / получают что-то только в небольшой части подключенного времени.

Если вы хотите обрабатывать более 1000 клиентов, вам, вероятно, понадобится расширение или перекомпиляция PHP из-за FD_MAXSIZE за stream_select, который компилируется и ограничивает stream_select для файловых дескрипторов ниже 1024.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]