Protocolo WebSocket
Atualmente, a versão do protocolo WebSocket do Workerman é 13.
O protocolo WebSocket é um novo protocolo do HTML5. Ele implementa a comunicação full-duplex entre o navegador e o servidor.
Relação entre WebSocket e TCP
Assim como o HTTP, o WebSocket é um protocolo de camada de aplicativo, ambos são baseados na transmissão TCP. O WebSocket em si não tem muita relação com Socket e não deve ser equiparado.
Handshake do protocolo WebSocket
O protocolo WebSocket tem um processo de handshake, no qual o navegador e o servidor se comunicam por meio do protocolo HTTP. No Workerman, você pode intervir neste processo de handshake da seguinte maneira.
Quando 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)
{
// Você pode verificar aqui se a origem da conexão é válida, caso contrário, feche a conexão
// $_SERVER['HTTP_ORIGIN'] identifica de qual site a conexão websocket foi iniciada
if($_SERVER['HTTP_ORIGIN'] != 'https://www.workerman.net')
{
$connection->close();
}
// em onWebSocketConnect $_GET $_SERVER estão disponíveis
// var_dump($_GET, $_SERVER);
};
};
Worker::runAll();
Quando 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();
Transmitindo dados binários pelo protocolo WebSocket
O protocolo websocket por padrão só pode transmitir texto em utf8. Se você quiser transmitir dados binários, por favor, leia a parte a seguir.
No protocolo websocket, um bit de marcação é utilizado no cabeçalho do protocolo para indicar se os dados transmitidos são binários ou texto em utf8. O navegador irá validar se a marcação e o tipo de conteúdo transmitido estão em conformidade; caso contrário, ocorrerá um erro e a conexão será encerrada.
Portanto, o servidor precisa definir esse bit de marcação com base no tipo de dados que está sendo transmitido. No Workerman, se forem dados normais em utf8, você deve definir (o valor padrão já é esse, geralmente não é necessário configurá-lo manualmente):
use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_BLOB;
Se forem dados binários, você deve definir:
use Workerman\Protocols\Websocket;
$connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;
Atenção: Se $connection->websocketType não estiver definido, o valor padrão de $connection->websocketType será BINARY_TYPE_BLOB (ou seja, tipo texto utf8). Em aplicações comuns, os dados transmitidos são geralmente em utf8, como a transmissão de dados em json, portanto não é necessário definir manualmente $connection->websocketType. Somente ao transmitir dados binários (como dados de imagem, dados de protobuffer, etc.) é necessário definir essa propriedade como BINARY_TYPE_ARRAYBUFFER.
Usando Workerman como cliente WebSocket
Você pode usar a classe AsyncTcpConnection em conjunto com o protocolo ws para fazer com que o Workerman atue como um cliente websocket e se conecte a um servidor websocket remoto, completando a comunicação em tempo real bidirecional.