Criar um chat em tempo real com CodeIgniter e WebSocket: guia prático
Um guia prático para criar um chat em tempo real com CodeIgniter 4 e a biblioteca PHP Ratchet, abordando arquitetura, servidor WebSocket e conexão com o frontend.
Se você já usou um chat online — do WhatsApp Web a uma janela de suporte ao vivo — deve ter notado que as mensagens aparecem instantaneamente, sem precisar recarregar a página. Isso é possível graças aos WebSocket, uma tecnologia que permite ao navegador e ao servidor trocarem dados em tempo real por meio de uma única conexão que permanece aberta, em vez de abrir uma nova para cada requisição como faz o HTTP tradicional.
Neste guia vamos construir um chat simples em tempo real usando CodeIgniter, um framework PHP leve e muito usado, combinado com uma biblioteca PHP dedicada ao gerenciamento de conexões WebSocket. O objetivo é entender a arquitetura e as etapas principais, para depois poder adaptar o projeto às suas próprias necessidades.
Por que o HTTP tradicional não basta para um chat
O protocolo HTTP, aquele que o navegador usa para carregar páginas web, funciona por requisições: o cliente (o navegador) pede algo ao servidor, o servidor responde e a conexão se encerra. Para um chat, essa abordagem seria incômoda: o navegador teria que perguntar o tempo todo "há mensagens novas?" a cada poucos segundos (uma técnica chamada polling), desperdiçando recursos e causando atrasos perceptíveis.
Os WebSocket resolvem esse problema abrindo um canal de comunicação bidirecional que permanece ativo: uma vez estabelecida a conexão, tanto o servidor quanto o navegador podem enviar mensagens em qualquer momento, sem precisar refazer a requisição do zero. É o mesmo princípio usado por aplicativos de mensagens, notificações em tempo real em painéis administrativos e jogos multijogador no navegador.
A arquitetura: dois processos distintos
Um detalhe importante antes de começar: o CodeIgniter, como a maioria dos frameworks PHP tradicionais, foi projetado para lidar com requisições HTTP "clássicas" por meio de um servidor web como Apache ou Nginx com PHP-FPM. Esse modelo de execução do PHP não foi feito para manter milhares de conexões persistentes abertas — que é exatamente o que um servidor WebSocket precisa fazer.
A solução mais comum, e que usaremos aqui, é separar as duas responsabilidades:
- A aplicação CodeIgniter continua cuidando de todo o resto: páginas, autenticação, gravação do histórico de mensagens no banco de dados, APIs REST.
- Um processo PHP separado, iniciado pela linha de comando e mantido em execução contínua, cuida exclusivamente das conexões WebSocket usando uma biblioteca dedicada (no nosso caso, Ratchet, uma das bibliotecas PHP mais usadas para essa finalidade).
Os dois processos se comunicam entre si quando necessário (por exemplo, para salvar uma mensagem no banco de dados), mas permanecem independentes: se o servidor WebSocket reiniciar, o site principal continua funcionando normalmente.
Pré-requisitos
- PHP 8.2 ou superior: o requisito mínimo das versões recentes do CodeIgniter 4 (a 4.7.4, a mais recente no momento da escrita, também é compatível com o PHP 8.5).
- Composer, o gerenciador de dependências do PHP, para instalar o CodeIgniter e as bibliotecas necessárias.
- Um projeto CodeIgniter 4 já criado (com
composer create-project codeigniter4/appstarter nome-do-projeto). - A extensão PHP
socketsativada, necessária para o funcionamento do servidor WebSocket.
Passo 1: instalar a biblioteca WebSocket
Dentro da pasta do projeto CodeIgniter, instalamos o Ratchet via Composer:
composer require cboden/ratchet
O Ratchet é uma biblioteca que implementa o protocolo WebSocket em PHP com base no ReactPHP, um framework de programação assíncrona: ele permite que nosso script PHP gerencie várias conexões ao mesmo tempo sem bloquear à espera de cada uma.
Passo 2: escrever a lógica do chat
Vamos criar uma classe que implementa a interface MessageComponentInterface do Ratchet. Essa classe define o que acontece quando um usuário se conecta, envia uma mensagem ou se desconecta. Um exemplo simplificado, salvo por exemplo em app/Libraries/ChatServer.php:
class ChatServer implements MessageComponentInterface {
protected $clients;
public function __construct() { $this->clients = new \SplObjectStorage; }
public function onOpen($conn) { $this->clients->attach($conn); }
public function onMessage($from, $msg) {
foreach ($this->clients as $client) {
if ($from !== $client) { $client->send($msg); }
}
}
public function onClose($conn) { $this->clients->detach($conn); }
public function onError($conn, $e) { $conn->close(); }
}
Na prática: quando chega uma mensagem de um usuário (onMessage), nós a retransmitimos a todos os outros usuários conectados, exceto quem a enviou. Essa é a lógica básica de um chat em grupo; a partir daí é possível adicionar salas separadas, nomes de usuário, mensagens privadas e gravação no banco de dados.
Passo 3: iniciar o servidor WebSocket
É necessário um pequeno script para ser executado pelo terminal, separado do fluxo normal do CodeIgniter, por exemplo chat_server.php na raiz do projeto:
$server = IoServer::factory(new HttpServer(new WsServer(new ChatServer())), 8080);
$server->run();
Ao executá-lo com php chat_server.php, o servidor ficará ouvindo na porta 8080, pronto para aceitar conexões WebSocket. Em produção, esse script deve ser mantido ativo com uma ferramenta como o Supervisor, que o reinicia automaticamente em caso de falha, e colocado atrás de um proxy reverso (Nginx ou Apache) que gerencie o certificado SSL, para expor a conexão segura wss:// em vez do simples ws://.
Passo 4: conectar o frontend
Na view do CodeIgniter da página de chat, bastam algumas linhas de JavaScript nativo para se conectar ao servidor WebSocket, sem precisar de bibliotecas externas:
const socket = new WebSocket('wss://seusite.com:8080');
socket.onmessage = (event) => { /* exibir a mensagem recebida na página */ };
document.getElementById('enviar').onclick = () => { socket.send(textoMensagem); };
A partir daqui, é possível enriquecer a interface com um framework CSS como o Bootstrap (muito usado junto com o CodeIgniter) para deixar o chat mais agradável, ou integrar a autenticação já gerenciada pela aplicação CodeIgniter, enviando um token no momento da conexão para verificar quem está escrevendo.
Uma alternativa pronta
Quem preferir não escrever o servidor WebSocket do zero pode considerar pacotes Composer pensados especificamente para se integrar aos comandos spark do CodeIgniter 4, como o takielias/codeigniter4-websocket, que oferece uma estrutura já pronta com callbacks para autenticação, salas e temporizadores, iniciável com um comando dedicado em vez de um script separado. É útil para prototipar rapidamente, embora continue se baseando na mesma biblioteca Ratchet descrita acima.
Conclusão
Adicionar um chat em tempo real a um projeto CodeIgniter não significa abandonar o framework: significa apenas acompanhá-lo com um pequeno processo PHP dedicado, construído sobre uma biblioteca como o Ratchet, que cuida apenas da parte "sempre conectada". Uma vez compreendido esse esquema — uma aplicação clássica de um lado, um servidor WebSocket persistente de outro — é possível estender a mesma lógica para notificações em tempo real, painéis atualizados automaticamente ou qualquer outra funcionalidade que exija comunicação instantânea entre servidor e navegador.
Fontes oficiais
Partilhar
Qual é a sua reação?
Gosto
0
Não gosto
0
Adoro
0
Divertido
0
Irritado
0
Triste
0
Uau
0