В настоящее время общение в режиме реального времени с помощью быстро меняющихся современных систем стало необходимостью, будь то обновление систем живого чата, многопользовательских игр или инструментов для совместной работы, поскольку все должно происходить мгновенно.
Именно здесь в игру вступают WebSockets: полнодуплексный канал связи между сервером и его клиентом. В этом руководстве мы обсудим, как именно WebSockets работает на PHP и как вы могли бы приступить к созданию высокопроизводительного приложения реального времени.
Что такое WebSocket?
Было бы здорово прояснить, что же на самом деле представляет собой WebSocket, прежде чем переходить непосредственно к деталям реализации.
WebSocket — это коммуникационный протокол, который обеспечивает полнодуплексную двунаправленную связь по постоянному серверному соединению.
В отличие от HTTP, который заставляет клиента постоянно запрашивать новые данные (опрос), WebSocket позволяет как клиенту, так и серверу отправлять друг другу любые новые данные без каких-либо дополнительных затрат.
Другими словами, с точки зрения непрофессионала, соединение WebSocket открыто и остается открытым; данными можно обмениваться в режиме реального времени без необходимости повторного подключения.
Зачем использовать WebSocket?
Основные ключевые преимущества использования WebSocket для приложений в реальном времени по сравнению с традиционными методами, такими как AJAX или длительный опрос (long-polling):
- Низкая задержка: становится возможным благодаря поддержанию единого открытого соединения, что помогает сократить задержки при отправке и получении данных. Это лучше всего работает в тех случаях, когда требуется мгновенная отправка обновлений, например, в чат-приложениях или торговых платформах в режиме реального времени.
- Двунаправленная связь в режиме реального времени: В отличие от HTTP, который является однонаправленным — от клиента к серверу — WebSocket позволяет и клиенту, и серверу отправлять сообщения в любое время. Таким образом, он действительно выглядит динамичным.
- Низкие накладные расходы: WebSocket выполняет рукопожатие только один раз при установке начального соединения. После этого обе стороны могут обмениваться данными без повторного цикла запроса-ответа HTTP, что позволяет экономить полосу пропускания и делает взаимодействие более эффективным.
Настройка WebSocket в PHP
Хотя PHP изначально не был разработан для работы с приложениями в реальном времени, вполне возможно реализовать WebSocket в PHP с использованием подходящих библиотек и инструментов.
1. Установите библиотеку WebSocket для PHP
Одной из самых популярных библиотек WebSocket для PHP является Ratchet. Это простая, гибкая и событийно-ориентированная библиотека, которая упрощает реализацию WebSocket связи.
composer require cboden/ratchet
2. Создание WebSocket сервера
Теперь давайте углубимся в создание базового сервера WebSocket с использованием PHP и Ratchet.
<?php
require __DIR__ . '/vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
protected $clients;
public function __construct() {
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn) {
// Store the new connection
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
foreach ($this->clients as $client) {
if ($from !== $client) {
// Send the message to everyone except the sender
$client->send($msg);
}
}
}
public function onClose(ConnectionInterface $conn) {
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
}
$server = \Ratchet\Server\IoServer::factory(
new \Ratchet\Http\HttpServer(
new \Ratchet\WebSocket\WsServer(
new Chat()
)
),
8080
);
$server->run();
3. Запуск сервера
Сохраните приведенный выше скрипт как server.php и запустите его с помощью командной строки PHP.
php server.php
Ваш WebSocket-сервер начнет прослушивать порт 8080. Теперь пришло время создать простой клиент для взаимодействия с этим сервером.
Создаем WebSocket-клиент
Давайте напишем простой HTML- и JavaScript-клиент, который подключается к нашему PHP WebSocket серверу. Это будет действовать как обычное подключение пользователя к приложению.

Усовершенствование вашего WebSocket-сервера
Несмотря на то, что мы создали базовый WebSocket-сервер, существует несколько способов его улучшения и масштабирования:
- Обработка более сложных событий: Вы можете создать систему, в которой различные типы сообщений (например, уведомления, команды или широковещательные рассылки) обрабатываются вашим WebSocket-сервером по-разному.
- Аутентификация: добавьте аутентификацию, чтобы гарантировать, что подключаться смогут только авторизованные пользователи. Это можно сделать, передав токены или информацию о сеансе во время подтверждения связи через WebSocket.
- Масштабирование с помощью Supervisord или Docker: Если вы планируете развернуть свой сервер WebSocket в рабочей среде, рассмотрите возможность использования таких инструментов, как Supervisord или Docker, для управления сервером и его масштабирования.
- Безопасный WebSocket (WSS): Реализуйте протокол SSL для защиты вашего WebSocket-соединения, используя wss:// вместо ws://. В рабочей среде защита ваших WebSocket-соединений необходима для защиты конфиденциальных данных.
Вывод
WebSockets позволяют создавать веб-приложения, работающие в режиме реального времени. Это действительно эффективное решение с низкой задержкой для таких случаев использования, как приложения для чата, оперативные обновления или инструменты для совместной работы.
Хотя изначально PHP не предназначался для таких задач, с помощью таких библиотек, как Ratchet, теперь можно быстро создавать мощные приложения реального времени.
Выполнив небольшую настройку и подобрав нужные инструменты, вы можете интегрировать PHP с WebSockets, чтобы обеспечить своим пользователям гораздо более быструю и динамичную работу.
Обсуждение закрыто.