(Web Sockets) - это передовая технология, которая позволяет создавать интерактивное соединение между клиентом (браузером) и сервером для обмена сообщениями в режиме реального времени. Веб-сокеты, в отличие от HTTP, позволяют работать с двунаправленным потоком данных, что делает эту технологию совершенно уникальной. Давайте разберемся, как работает эта технология и чем она отличается от HTTP.
Как работает HTTP?Схема обмена сообщениями по HTTP
Вы наверняка знаете, что такое HTTP (или HTTPS), поскольку встречаетесь с этим протоколом каждый день в своём браузере. Браузер постоянно спрашивает у сервера, есть ли для него новые сообщения, и получает их.
Вы также можете знать, что HTTP позволяет использовать разные типы запросов, такие как POST, GET или PUT, каждый из которых имеет своё назначение.
Как работают веб-сокеты?Схема обмена сообщениями при использовании веб-сокетов
Веб-сокетам же для ответа не нужны ваши повторяющиеся запросы. Достаточно выполнить один запрос и ждать отклика. Вы можете просто слушать сервер, который будет отправлять вам сообщения по мере готовности.
Веб-сокеты можно использовать, если вы разрабатываете:
- приложения реального времени;
- чат-приложения;
- IoT-приложения;
- многопользовательские игры.
Практически никогда. Единственный минус - это несовместимость с некоторыми браузерами, но уже 95 % браузеров поддерживают веб-сокеты.
В некоторых случаях веб-сокеты вам всё же не понадобятся. Если вы создаёте простую CMS, вам вряд ли пригодится функциональность в режиме реального времени. Также не стоит использовать веб-сокеты в REST API, поскольку вам хватит таких HTTP-запросов, как GET, POST, DELETE и PUT.
Практические примерыВ примерах ниже для клиента используется JavaScript, а для сервера - Node.js. Примеры очень просты и вряд ли пригодятся на практике, но зато позволят разобраться в сути.
Веб-сокетыПример чата с веб-сокетом let ws = new WebSocket("ws://localhost:8080"); // выводим новые сообщения в консоль ws.onmessage = ({data}) => { console.log(data); } // отправляем сообщение ws.onopen = () => ws.send("Text");
Const WebSocket = require("ws"); // создаём новый websocket-сервер const wss = new WebSocket.Server({ port: 8080 }); // отправляем клиентам, когда функция clientValidator возвращает true. this - это wss. wss.broadcast = function(data, clientValidator = () => true) { this.clients.forEach(client => { if (clientValidator(client)) { client.send(data); } }); } wss.on("connection", ws => { // событие будет вызвано, когда клиент отправит сообщение ws.on("message", message => { // отправляем сообщение всем, кроме автора wss.broadcast(message, client => client !== ws); }); });
Вот иллюстрация работы веб-сокетов:
Демонстрация работы веб-сокетов
Эквивалент в HTTPТак как HTTP должен постоянно проверять канал на наличие новых сообщений, можно использовать «грязную» проверку (dirty check) - подход, при котором клиент с заданной периодичностью (допустим, каждые 200 мс) проверяет наличие новых сообщений на сервере.
Как Яндекс использует ваши данные и машинное обучение для персонализации сервисов - .
Сатья посвещена сетевому програамированию, а в частности — программированию сокетов на PHP. Для сетевого взаимодействия в PHP существует две категории функций:
Рассматриваться будут только функции под номером 2, т.к. они более интересны.
Для начала проверим, подключена ли у Вас библиотека работы с сокетами.
Проверить это можно следующим скриптом:
If(extension_loaded("sockets")) echo "расширение загружено"; else echo "расширение не загружено"; ?>
Если расширение не загружено, то Вам следует его загрузить.
И так. Наиболее простой в рамках статьи пример — echo-сервер. Эхо-сервер — это означает, что строка отправленная клиентом серверу, возвращается обратно. То есть сервер получает какое-то сообщение от клиента, что-то с ним делает и отправляет ему обратно.
У нас будет 2 скрипта:
Для реализации клиента нам понадобятся следующие функции работающие с сокетами:
Листинг 1.0 — Клиент
Set_time_limit(0); ob_implicit_flush(); echo "- Клиент
";
$address = "127.0.0.1"; // адресс localhost. $port = 5555; // порт с которым будет установленно соединение.
echo "Создание сокета... "; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket "; } else { echo "OK
"; }
echo "Подключение к сокету... "; $connect = socket_connect($socket, $address, $port);
if($connect === false) { echo "Ошибка: ".socket_strerror(socket_last_error())."
"; } else { echo "OK
";
$msg = "Hello Сервер!"; echo "Говорим серверу \"".$msg."\"..."; socket_write($socket, $msg, strlen($msg)); echo "OK
";
echo "Сервер сказал: "; $awr = socket_read($socket, 1024); echo $awr."
";
$msg = "exit"; echo "Говорим серверу \"".$msg."\"..."; socket_write($socket, $msg, strlen($msg)); echo "OK
"; }
if(isset($socket)) { echo "Закрываем соединение... "; socket_close($socket); echo "OK
"; } ?>
Для реализации сервера нам понадобятся следующие функции работающие с сокетами:
Листинг 1.1 — Сервер
Set_time_limit(0); ob_implicit_flush(); echo "- Сервер
";
$address = "127.0.0.1"; $port = 5555;
echo "Создание сокета... "; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if($socket "; } else { echo "OK
"; }
echo "Привязывание сокета... "; $bind = socket_bind($socket, $address, $port); if($bind "; } else { echo "OK
"; }
echo "Прослушивание сокета... "; $listen = socket_listen($socket, 5); if($listen "; } else { echo "OK
"; }
while(true) { echo "Ожидаем... "; $accept = socket_accept($socket); if($accept "; break; } else { echo "OK
"; }
$msg = "Hello, Клиент!"; echo "Отправить клиенту \"".$msg."\"... "; socket_write($accept, $msg, strlen($msg)); echo "OK
";
while(true) { $awr = socket_read($accept, 1024); if (false === $awr) { echo "Ошибка: ".socket_strerror(socket_last_error())."
"; break 2; } else { if (trim($awr) == "") break; else echo "Клиент сказал: ".$awr."
"; }
if ($awr == "exit") { socket_close($accept); break 2; }
echo "Сказать клиенту \"".$msg."\"... "; socket_write($accept, $awr, strlen($awr)); echo "OK
"; }
}
if (isset($socket)) { echo "Закрываем соединение... "; socket_close($socket); echo "OK
"; } ?>
Вот собственно и всё. Вначале запустите скрипт сервер, он создаст, привяжет, начнёт прослушивание сокета и установится в режим ожидания клиента. Далее запустите клиента.
Так же хочу отметить что наиболее полезной является функция:
socket_select
(array read, array write, array except, integer timeout_seconds, integer timeout_microseconds); — Функция контролирует изменения происходящие на узлах. PHP просматривает поступления новых дынных на сокетах, заданных в массиве read. PHP просматривает готовность к приёму данных на сокетах, заданных в массиве write. PHP просматривает на наличие ошибок потоки, заданные в аргументе except. В таймаутах задается время, по истечению которого функция будет возвращать кол-во сокетов изменивших своё состояние или FALSE.
Эта функция не заменима для мониторинга клиентов висящих на сокете.
В статье приведена малая часть всех функций работающих сокетами, кого заинтересовало, откапывайте мануалы, читайте… Удачных экспериментов…
В предыдущей статье я рассказывал про . Мы с Вами с использованием сокетов создали сервер на PHP . А в этой статье мы с Вами напишем клиента на PHP , который будет отправлять запрос на сервер и получать от него ответ.
Привожу код клиента на PHP :
Код хорошо прокомментирован, поэтому, думаю, что здесь всё предельно понятно. Алгоритм работы клиента тривиальный: создание сокета, подключение к серверу, отправка запросов, получение ответов, закрытие соединения. Мы с Вами отправили число 15 . Если Вы читали предыдущую статью, то помните, что задача сервера это число возвести в квадрат и вернуть его. Поэтому если Вы запустите этот клиент, то увидите от сервера 225 (15*15 ). Потом мы подаём команду shutdown , которая останавливает сервер.
Теперь у Вас есть минимальный набор знаний по работе с сокетами, а вообще тема очень интересная, поэтому Вы можете изучить её более детально. Вы можете создавать очень сложные клиент-серверные приложения, к котором Вы всегда сможете подключиться и отправлять самые различные запросы, которые сервер будет обрабатывать.