Тонкий принцип работы сокетов PHP

Мизантроп777

Новичок
Приветствую всех.
Я перечитал кучу документаций, запускал на локальном сервере кучу примеров, но до конца не могу понять по какому принципу все это работает, уже более 4 дней долблюсь.
Буду очень благодарен за любую помощь.

Какой принцип работы у сокетов PHP?
Создается сокет функцией socket_create() затем к нему привязывается домен и порт, с эти в теории понятно, но оптом он прослушивается функцией socket_listen(). Так вот, по какому принципу осуществляется прослушка? Эта функция постоянно прослушивает? Но ведь она не находится в цикле, какой у нее механизм работы? Как она взаимодействует с socket_accept и socket_select()?

И еще сильно мучает вопрос. Если создать эхо сервер на PHP, по сути, какое количество пользователей он потянет? Делаю ли сервера (сокеты) для серьезных проектов на PHP? Вот имеется у меня чат работающий на сокетах HTML5 и взаимодействующий с эхо сервером на PHP, сможет ли в этом чате 1000 пользователей или 5 тыс. сидеть?
 

hell0w0rd

Продвинутый новичок
Если хочется написать асинхронный веб-сервер, бери nodejs. PHP для этого не предназначен.
Но если мазохист, на: http://reactphp.org/
 

Мизантроп777

Новичок
Если хочется написать асинхронный веб-сервер, бери nodejs. PHP для этого не предназначен.
Но если мазохист, на: http://reactphp.org/
А на кой черт тогда эти сокеты в PHP сдались? Типа вещать футбольный матч и прочую невесомую фигню?
Разве nodejs не на PHP Написан? Я не в курсе, слышал про него, но не вдавался в детали.
 

WMix

герр M:)ller
Партнер клуба
а вот кстати про зокеты, они же не в реальном времени считывают, а из буфера типа tail -f, или ошибаюсь? в смысле на сколько велика задержка?
 

MiksIr

miksir@home:~$
socket_listen говорит операционной системе, что этот сокет будет принимать соединения.
А вот socket_accept проверяет на новые входящие соединения.
Дальше у вас два режима работы - в блокирующем режиме и неблокирующем.

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

Что бы обслужить больше - можно делать форк (pcnt_fork) - это "раздвоение" процесса, после которого получается два совершенно индентичных процесса. Один возвращается слушать новые соединения через socket_accept, второй же - общается с новым соединением сколько хочет.
Тут будет обслужено в секунду максимум 1/x*n, где х - время общения по открытому сокету, n - сколько параллельных процессов переживет ваш сервер

Далее, неблокирующий режим. На нем строятся мультиплексирующие сервера. У них один процесс может обслуживать много соединений. Как это работает.
Вызываем socket_select и передаем этой функции все открытые сокеты. Эта функция вернет вам список тех сокетов, которые готовы к чтению (ну или записи). Готовы - в том смысле, что оттуда уже есть что читать (лежит в буфере ОС). Например, для сокета созданного socket_create наличие "чего-то читать" значит, что там есть новое соединение - дергаем socket_accept, что бы его принять. А для сокета, уже ранее созданного через socket_accept - это значит, что поступили данные.
Вот и получается такой бесконечный цикл с socket_select - которая дает готовые к работе сокеты, а вы смотрите их и решаете что делать. Сложность тут в том, что нужно хранить состояния сокета, помнить - какой сокет какие данные уже прислал и т.п.
Количество обслуженного в секунду тут посчитать сложно - но в любом случае - не более 1/x (из первого варианта).

Чем же последний вариант отличается от первого? Если у вас логика "принять соединение, что-то быстро сделать на ПХП, дать ответ, завершить соединение" - то ничем. Плюсы вылезают, когда, например, вам нужно ждать входящих данных, ждать еще вопросов от клиента и т.п. В первом случае - это все засчитывалось бы в x, в последнем - нет, так как во время ожидания мы можем заниматься другими клиентами. По-этому, в последнем случае x - это чисто расчеты на PHP.

Вот тут пример такого сервера http://php.net/manual/ru/function.socket-select.php#56241

В любом случае socket-select не очень хорош, когда речь заходит о сотнях и тысячах соединений. Тут уже следует смотреть в сторону более современных аналогов http://php.net/manual/ru/ref.libevent.php

Для PHP есть проект phpdaemon - минифреймворк для написания мультиплексирующих серверов.

Это в общем базовая теория, дальше там еще много вариантов есть, в частности, форк нескольких мультиплекс серверов, использование тредов и т.п.
 

Redjik

Джедай-мастер
Не уловил мысль.
Браузеры работаю по протоколу http, а сокеты это всего лишь API для написания приложения разного рода
Я намеренно сделал этот вброс, чтобы ты наконец открыл хотя бы википедию.

Сокет - интерфейс межпроцессного взаимодействия.

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

хочу еще уточнить, у listen есть второй параметр, который на C обязательный - это как раз ограничение на очередь подключений

ЗЫ. MiksIr,респект, сам хотел описать подобным образом, но было поздно, жена со "шваброй стояла за спиной" и намекала, что пора идти спать. Это и хорошо, ты лучше написал, чем я планировал, я бы пропустил инфу про форки и режимы.
 
Последнее редактирование:
Сверху