WebSocket протокол

В данный момент версия WebSocket протокола в Workerman составляет 13.

WebSocket протокол является новым протоколом HTML5. Он реализует двустороннюю связь между браузером и сервером.

Отношение WebSocket к TCP

WebSocket, как и HTTP, является протоколом прикладного уровня и основан на передаче данных через TCP. WebSocket сам по себе не имеет много общего с сокетом и не может быть с ним приравнен.

Рукопожатие WebSocket протокола

WebSocket протокол включает в себя процесс рукопожатия, в котором браузер и сервер общаются по протоколу HTTP. В Workerman можно вмешаться в процесс рукопожатия следующим образом.

Когда workerman <= 4.1

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Connection\TcpConnection;
use Workerman\Worker;

$ws = new Worker('websocket://0.0.0.0:8181');
$ws->onConnect = function($connection)
{
    $connection->onWebSocketConnect = function($connection , $httpBuffer)
    {
        // Здесь можно проверить, законен ли источник подключения, и закрыть соединение, если нет
        // $_SERVER['HTTP_ORIGIN'] указывает, с какого сайта инициировано websocket соединение
        if($_SERVER['HTTP_ORIGIN'] != 'https://www.workerman.net')
        {
            $connection->close();
        }
        // Внутри onWebSocketConnect доступны $_GET и $_SERVER
        // var_dump($_GET, $_SERVER);
    };
};
Worker::runAll();

Когда workerman >= 5.0

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;

$worker = new Worker('websocket://0.0.0.0:12345');
$worker->onWebSocketConnect = function (TcpConnection $connection, Request $request) {
    if ($request->header('origin') != 'https://www.workerman.net') {
        $connection->close();
    }
    var_dump($request->get());
    var_dump($request->header());
};
Worker::runAll();

Передача бинарных данных по WebSocket протоколу

WebSocket протокол по умолчанию может передавать только utf8 текст. Если необходимо передать бинарные данные, ознакомьтесь с нижеприведенной частью.

В WebSocket протоколе используется флажок в заголовке протокола, чтобы отметить, передаются ли бинарные данные или utf8 текстовые данные. Браузер проверит соответствие флажка и типа передаваемого содержимого, и если они не соответствуют, возникнет ошибка и соединение будет разорвано.

Таким образом, при отправке данных сервером необходимо установить этот флажок в зависимости от типа передаваемых данных. В Workerman, если это обычный utf8 текст, то нужно установить (по умолчанию это значение, обычно не нужно устанавливать вручную)

use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_BLOB;

Если это бинарные данные, то необходимо установить

use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;

Внимание: Если $connection->websocketType не установлен, то $connection->websocketType по умолчанию будет BINARY_TYPE_BLOB (то есть тип utf8 текста). Обычно передаются utf8 текстовые данные, такие как json, поэтому не нужно вручную устанавливать $connection->websocketType. Устанавливать это свойство на BINARY_TYPE_ARRAYBUFFER требуется только при передаче бинарных данных (например, данных изображений, данных протобуффера и т. д.).

Использование Workerman в качестве WebSocket клиента

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