WebSocket em PHP: criação de aplicações real-time de nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

WebSocket em PHP: da teoria às soluções de produção

\n\n

O protocolo WebSocket revolucionou o desenvolvimento web, permitindo criar aplicações real-time completas que funcionam sobre uma única conexão TCP. Diferentemente do HTTP clássico, onde o cliente inicia constantemente requisições, o WebSocket estabelece um canal de comunicação bidirecional, pelo qual o servidor pode enviar dados a qualquer momento. Isso é criticamente importante para chats, plataformas de negociação, jogos online e sistemas de monitoramento.

\n\n

Muitos desenvolvedores acreditam erroneamente que o PHP não é adequado para tarefas real-time devido à sua natureza síncrona. No entanto, ferramentas modernas, como Ratchet e ReactPHP, mudam completamente essa percepção. Neste artigo, abordaremos técnicas avançadas para criar aplicações WebSocket escaláveis em PHP.

\n\n

Arquitetura do servidor WebSocket em PHP

\n\n

Escolhendo a pilha de tecnologia correta

\n\n

Para soluções de produção, bibliotecas simples que funcionam através de socket_create não são adequadas. É necessária uma abordagem orientada a eventos. A pilha recomendada:

\n\n
    \n
  • ReactPHP — event-loop para entrada/saída assíncrona
  • \n
  • Ratchet — componente WebSocket sobre ReactPHP
  • \n
  • Redis — pub/sub para comunicação entre processos
  • \n
  • Supervisor — gerenciador de processos para garantir uptime
  • \n
\n\n

Servidor básico com Ratchet

\n\n

Vamos considerar a criação de um servidor WebSocket completo, capaz de lidar com milhares de conexões:

\n\n
use Ratchet\\MessageComponentInterface;\nuse Ratchet\\ConnectionInterface;\nuse React\\EventLoop\\Factory;\nuse React\\Socket\\Server;\nuse Ratchet\\Server\\IoServer;\nuse Ratchet\\Http\\HttpServer;\nuse Ratchet\\WebSocket\\WsServer;\n\nclass ChatServer implements MessageComponentInterface {\n    protected $clients;\n    protected $redis;\n\n    public function __construct() {\n        $this->clients = new \\SplObjectStorage;\n        $this->redis = new \\Predis\\Client([\n            'scheme' => 'tcp',\n            'host'   => '127.0.0.1',\n            'port'   => 6379,\n        ]);\n        // Inscrição no canal Redis para sincronização entre servidores\n        $this->redis->subscribe(['chat_messages'], function($redis, $channel, $message) {\n            $this->broadcast(json_decode($message, true));\n        });\n    }\n\n    public function onOpen(ConnectionInterface $conn) {\n        $this->clients->attach($conn);\n        echo "Nova conexão: {$conn->resourceId}\\n";\n    }\n\n    public function onMessage(ConnectionInterface $from, $msg) {\n        $data = json_decode($msg, true);\n        \n        // Validação da mensagem\n        if ($this->validateMessage($data)) {\n            // Publicação no Redis para outros servidores\n            $this->redis->publish('chat_messages', json_encode($data));\n            // Envio para clientes locais\n            $this->broadcast($data, $from);\n        }\n    }\n\n    public function onClose(ConnectionInterface $conn) {\n        $this->clients->detach($conn);\n        echo "Conexão fechada: {$conn->resourceId}\\n";\n    }\n\n    public function onError(ConnectionInterface $conn, \\Exception $e) {\n        echo "Erro: {$e->getMessage()}\\n";\n        $conn->close();\n    }\n\n    protected function broadcast(array $data, ?ConnectionInterface $exclude = null) {\n        foreach ($this->clients as $client) {\n            if ($exclude === null || $client !== $exclude) {\n                $client->send(json_encode($data));\n            }\n        }\n    }\n\n    protected function validateMessage(array $data): bool {\n        return isset($data['type'], $data['payload']) && \n               in_array($data['type'], ['message', 'typing', 'status']);\n    }\n}\n\n// Inicialização do servidor\n$loop = Factory::create();\n$webSock = new Server('0.0.0.0:8080', $loop);\n$webServer = n                

Blogs

Book Recommendations