[Из песочницы] Класс веб-сокетов на PHP

На днях опубликовал свой класс для развёртывания веб-сокет сервера.

Веб-сокеты — это технология, позволяющая устанавливать непрерывное соединение между клиентом и сервером. Особенность такой системы также в том, что сервер может по своей инициативе отправлять данные одному или нескольким клиентам. Это позволяет создавать real-time мессенджеры, онлайн-игры и прочие проекты.
PHP, казалось бы, не подходит для такой цели. Он обычно используется для создания динамических веб-страниц и работает по принципу «открыл-ответил-закрыл». Что же, стереотипы пора ломать.

Данный класс избавляет вас от необходимости скачивания сторонних демонов или написания сервера самостоятельно. Всё, что вам потребуется — подключить класс и написать функции приёма сообщений, при желании ещё и сердцебиения.

Чтобы использовать класс, просто включите его в ваш скрипт

require_once('../src/websocket.class.php');


Сразу должен предупредить, что запускаться сервер будет не через браузер, как вы привыкли, а через консоль. В репозиторий на GitHub я включил примеры BAT и SH файлов для исполнения.

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

Чтобы уберечь сервер от падений, напишите данный код:

error_reporting(E_ERROR);
set_time_limit(0);
ob_implicit_flush();


Для начала нужно создать экземпляр данного класса:

$socket = new WebSocket('tcp://', '127.0.0.1', '7777');


Как видите, во время создания надо указать протокол, IP и порт будущего сервера. Обязательно убедитесь, что данный порт открыт и IP правильный.

При желании можете записывать логи в файл:

$socket->setOutput('ws-log.txt');


Дальше надо создать обработчик сообщений клиента. Сразу обязан предупредить, что javascript-программисты сейчас возрадуются, а к остальным просто просьба не брать близко к сердцу.

$socket->handler = function($connection, $data) 
{
 fwrite($connection, WebSocket::encode($data)); 
};


Наследуя добрые традиции JS, вы должны записать в переменную handler анонимную функцию. Она будет вызываться каждый раз, когда клиент отправит сообщение серверу. Если вы собираетесь прямо оттуда отправлять ответ, не забывайте кодировать данные при помощи статической функции WebSocket: encode.

Немножко отклонений. Соединение — это ресурс. Его можно читать и дополнять так же, как и обычный открытый файл — при помощи fwrite и fread.

Теперь о функции «сердцебиения». Данная функция будет вызываться во время каждой итерации (чаще, чем раз в секунду).

$socket->hearthbeat = function($connects)
{

}


Во время вызова функции в первом аргументе будет содержаться массив со всеми установленными соединениями. «Сердцебиение» может использоваться для регулярных проверок и других подобных целей.

Последнее, что нам пригодится — собственно запустить сервер. Делается это при помощи метода runServer:

$socket->runServer();


После этого будет запущен вечный цикл. Ваш веб-сокет сервер готов.

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

© Habrahabr.ru