Задать вопрос

Как работать с websocket в php без библиотек?

Всем привет ! Хочу понять как работать с websocket в php без библиотек.
Я вроде бы не тупой, но прочитав разные статьи и потратив больше недели, я все равно не понял, как работать с websocket.
У всех примеров php servera для приема разный код.
Я хочу понять вот это:
  1. Как написать сервер для работы с websocket, на php без использования библиотек (и почему именно так, а не по другому).
  2. Как индефицировать websocket (что бы по websocket я мог понять какому пользователю он принадлежит).
  3. Как принимать данные websocket-а отправленные со стороны клиента.
  4. В каком месте можно полученные данные подготовить к записи в бд.
  5. Как отправить ответ клиенту в json формате.
  6. Как отправить данный ответ определенному пользователю. (Push уведомление с определенным содержимым).
  7. Как отправить данный ответ всем пользователям, кроме пользователя, который добавлял запись в бд. (Push уведомление с определенным содержимым).
  8. Как отправить данный ответ определенной группе пользователей. (Push уведомление с определенным содержимым).
  9. Как сделать, что бы на стороне клиента, один websocket отвечал за сообщения, другой за статьи. (Или за эти два действия отвечает один websocket, тогда как мне на сервере это различать).
  10. Как при помощи websocket выводить статус пользователя (online или offline).
  11. Как проверять запущен сервер или нет (Если не запущен, как сделать, что бы он автоматически запускался).
  12. Как при помощи websocket пересылать файлы. (Например в чате от одного пользователя к другому)

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

А можно ли сделать сервер на php, а например чат при помощи node js + socket.io ?
  • Вопрос задан
  • 9026 просмотров
Подписаться 13 Средний 8 комментариев
Решения вопроса 1
@xfg
Прочитать соответствующий RFC https://tools.ietf.org/html/rfc6455 чтобы понять, как происходит рукопожатие и какие байты в переданном сообщении за что отвечают. После этого будет понятно как написать реализацию. Я досконально уже не помню, но фактически от клиента приходит обычный http запрос с определенными заголовками, сервер разбирает этот запрос и если всё ок, то сохраняет открытое соединение в массив, если нет, то отправляет соответствующий ответ и закрывает соединение. Дальше по открытому соединению начинает сыпаться поток байтов от клиента их нужно разбирать, чтобы понять длину сообщения, сами данные переданные в фрейме, закончился фрейм или еще нет и тому подобное. Обратно также кодировать данные в поток байтов и отправлять по открытому соединению. Каждый байт в переданном фрейме несет определенный смысл. Обо всем этом подробно написано в RFC, но на английском. Вообще это хорошо примерно понимать как работает, но глупо писать такую низкоуровневую реализацию, когда есть готовые. Такие вещи развивают и поддерживают годами. Вы же не пишите HTTP серверы, а берете готовые вроде nginx и тому подобное.

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

Как сделать, что бы на стороне клиента, один websocket отвечал за сообщения, другой за статьи. (Или за эти два действия отвечает один websocket, тогда как мне на сервере это различать).

Вебсокет это низкоуровневая штука, для передачи потока байтов от клиента на сервер, в отличии например от HTTP, где есть заголовки и тело сообщения. Поверх вебсокета нужно делать еще один протокол или самописный или выбрать один из готовых. Это проще говоря, то как выглядят ваши фреймы (сообщения), которые вы отправляете с клиента на сервер и назад. Например клиент может отправлять такой фрейм:
["id", "controller/action", {param1: value1, param2: value2}]

в ответ получать
["id", "OK"]
если запрос был обработан успешно или
["id", "ERR", {error: "action not found"}]
если произошла ошибка. По переданному id в массиве, можно понимать, к какому запросу относится ответ.
Для уведомлений (событий) сервер может отправлять клиентам что-то такое
["user_added", {user: {...}}]
и т.д. Этот протокол необходимо придумать самому или выбрать из готовых (популярных пока нет) и написать его реализацию (клиентскую и серверную часть) или опять же взять уже готовую.

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

Но это уже всё должно быть, просто возьми real-time фреймворк. Там за тебя написали и websocket сервер и протокол поверх него и экшены уже есть. Всё низкоуровневое уже готово. Бери и пиши приложение. В nodejs самый популярный это например https://github.com/socketio/socket.io, а в php я не знаю, но уверен, что тоже есть что-то популярное.

Своё написать не получится, без опыта и без попыток сделать приложение на чем-то готовом. Нужно как минимум прочитать RFC и посмотреть реализации других разработчиков. Для этого нужно быть кем-то больше, чем "программистом сайтов".
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
Sanasol
@Sanasol Куратор тега PHP
нельзя просто так взять и загуглить ошибку
Как работать с websocket в php без библиотек?

если в кратце, то никак.

в PHP нет реализации протокола websocket из коробки.

Библиотеки как раз нужны потому что в них и описан весь websocket причем с поддержкой старых/разных версий для разных браузеров.

И это вообще не fsockopen или socket_create. Эти функции вообще о другом и ничего общего с вебсокетом не имеют. Точнее это низкоуровневые функции для создания любого сервера, но они сами по себе ничего не умеют из коробки на них как вебсокет можно реализовать так и http сервер например.

https://github.com/ratchetphp/RFC6455/blob/master/...
Как-то так выглядит вебсокет на "чистом похапе".
Без этого работать не будет ничего.
Ответ написан
Комментировать
Я раньше тоже писал свой вебсокет-сервер на php с нуля, о чём написал статью на хабре, а весь код опубликован на гитхабе.
В комментах к статье были полезные советы и моменты, которых я изначально не учитывал. В итоге сделал несколько реализаций.
Сейчас же использую workerman. У него большое комьюнити, понятный код и никаких зависимостей от сторонних библиотек.
Ответ написан
ivankomolin
@ivankomolin
Начать следует отсюда
php.net/manual/en/function.fsockopen.php
Ответ написан
Комментировать
@frimuchkov
PHP не держит состояние, а если и заставить его держать, то он сильно по памяти течёт (в PHP-FPM даже есть параметр через какое время воркеры перезагружать).
Есть 2 варианта:
  1. Поднять рядом сервер на Node.js и из PHP слать на него запросы
  2. Использовать что-то вроде cloudws.io

Вариант равнозначны, но в первом случае придётся немного повозиться, а во втором только api дёргать
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы