Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real

Quando o assunto é WebSocket, o PHP raramente é mencionado devido à sua falta de suporte nativo. Além disso, o Apache, o servidor HTTP em que o PHP normalmente é executado, não foi criado com conexões persistentes em mente, o que força a resp…


This content originally appeared on Twilio Blog and was authored by Luís Leão

Quando o assunto é WebSocket, o PHP raramente é mencionado devido à sua falta de suporte nativo. Além disso, o Apache, o servidor HTTP em que o PHP normalmente é executado, não foi criado com conexões persistentes em mente, o que força a responsabilidade da implementação em bibliotecas de terceiros.

Embora muitos já tenham tentado falar sobre o PHP no desenvolvimento "em tempo real", a maioria dos argumentos perdeu força em comparação com o projeto Ratchet, que é uma biblioteca WebSocket PHP que exclusivamente envia mensagens bidirecionais em tempo real entre clientes e servidores.

Neste tutorial, usaremos Ratchet com PHP para aprender a criar um servidor WebSocket simples que processa mensagens enviadas de um formulário HTML em tempo real. Nosso formulário exibirá um único <input> e <button> para o envio de mensagens a todos os navegadores do cliente. Sempre que o usuário enviar uma mensagem, ela será exibida em tempo real nas outras telas.

Este aplicativo de exemplo é criado de acordo com o padrão para aplicativos de chat modernos e ajudará você a começar a criar seu próprio aplicativo baseado em WebSocket.

O que são WebSockets?

Os WebSockets são conexões persistentes de baixa latência (ou rápidas) entre um servidor e um ou mais clientes. Ao contrário das solicitações AJAX, os WebSockets são bidirecionais (push-pull), o que significa que tanto o cliente quanto o servidor podem ouvir uns aos outros em tempo real e responder a quaisquer alterações.

Ferramentas necessárias para este tutorial

Neste tutorial, os seguintes pré-requisitos são necessários:

  • PHP 7 ou posterior instalado localmente
  • Composer para o armazenamento das dependências de aplicativos
  • ngrok para criarmos um túnel para o aplicativo do lado do cliente

Criar o diretório de aplicativos e arquivos

No terminal, execute os seguintes comandos para gerar o diretório de projetos e todos os arquivos necessários:

$ mkdir php-sockets && cd php-sockets
$ touch composer.json index.html app.php
$ mkdir app && cd app && touch socket.php

Navegue até o diretório raiz do projeto.

NOTA: caso você queira avançar as etapas, o código-fonte completo está disponível aqui.

Configurar o projeto Composer e incluir o Ratchet

O aplicativo usará o Composer para gerenciar as dependências e fornecer a funcionalidade de carregamento automático. Já criamos o arquivo composer.json necessário para armazenar as dependências do Ratchet. No IDE de sua preferência, abra o arquivo e adicione o seguinte código para incluir o Ratchet.

{
    "autoload": {
        "psr-4": {
            "MyApp\\": "app"
        }
    },
    "require": {
        "cboden/ratchet": "^0.4"
    }
}

Observe que esta declaração usa o protocolo PSR-4 para o carregador automático e mapeia o MyApp para a pasta app que criamos na configuração do projeto. Esse namespace será usado nas etapas subsequentes para incluir as classes de projeto. Conforme exigido por padrão, o arquivo composer.json utiliza a chave require para especificar o pacote Ratchet no projeto.

Agora que o arquivo composer.json está configurado, precisamos instalar as dependências. Para isso, execute o comando a seguir no terminal. Verifique se você está na pasta raiz do projeto.

$ composer install

Criar a classe WebSocket

Agora, chegou a hora de programar! Retorne ao IDE e abra o arquivo app/socket.php. Esse arquivo abrigará a classe necessária para a definição de como as conexões com o servidor WebSocket serão tratadas. Cole o seguinte código conforme mostrado abaixo:

<?php

namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Socket implements MessageComponentInterface {

    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {

        // Store the new connection in $this->clients
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {

        foreach ( $this->clients as $client ) {

            if ( $from->resourceId == $client->resourceId ) {
                continue;
            }

            $client->send( "Client $from->resourceId said $msg" );
        }
    }

    public function onClose(ConnectionInterface $conn) {
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

A classe abstrata MessageComponentInterface requer a implementação de todos os quatro métodos, onOpen, onMessage, onClose e onError, sejam eles utilizados ou não. Aqui está uma breve soma das responsabilidades de cada método:

onOpen: esse método permite responder quando uma nova conexão é estabelecida com o servidor. Pode ser usado para armazenar o ID de conexão em um banco de dados, fazer referência cruzada com outro serviço ou, como neste caso, armazenar a conexão em um conjunto de clientes.

onMessage: esse método provavelmente é a parte mais importante do aplicativo e gerencia a mensagem ou os dados enviados para o servidor. Além de capturar o parâmetro $msg, ele também aceita o $from para que o aplicativo possa decidir o que fazer com base em qual cliente está conectado. Neste exemplo, estamos enviando uma mensagem para cada cliente em tempo real. Também nos certificamos de que não enviamos a mensagem de volta ao cliente que a enviou.

onClose: como o próprio nome já diz, esse método será acionado se uma conexão for fechada pelo cliente.

onError: esse método será acionado se um erro for lançado pela nossa conexão.

Criar o servidor HTTP

Até agora, criamos com sucesso toda a lógica necessária para o processamento das conexões de entrada com o servidor. A última peça que precisamos implementar é o HttpServer que escutará na porta 8080. Abra o arquivo app.php e adicione o seguinte código:

<?php

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Socket;

require dirname( __FILE__ ) . '/vendor/autoload.php';

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Socket()
        )
    ),
    8080
);

$server->run();

Como você pode ver acima, o objeto $server contém o servidor HTTP, gerado por Socket(), e um servidor WebSocket WsServer e é atribuído à porta 8080. Esse arquivo é o que executaremos na linha de comando para ativar o servidor.

Criar o aplicativo cliente

O último item que precisamos criar é o aplicativo de navegador real. Esta página simples conterá <textarea> que captura as tecla pressionadas e as envia ao WebSocket. Dê uma olhada no código abaixo e cole-o no arquivo index.html.

<html>
    <head>
        <style>
            input, button { padding: 10px; }
        </style>
    </head>
    <body>
        <input type="text" id="message" />
        <button onclick="transmitMessage()">Send</button>
        <script>
            // Create a new WebSocket.
            var socket  = new WebSocket('ws://localhost:8080');

            // Define the 
            var message = document.getElementById('message');

            function transmitMessage() {
                socket.send( message.value );
            }

            socket.onmessage = function(e) {
                alert( e.data );
            }
        </script>
    </body>
</html>

O aplicativo do lado do cliente é simples. Ele estabelece uma conexão WebSocket com o servidor em ws://localhost:8080 e, quando o botão "Send" (Enviar) é pressionado, a mensagem é enviada ao servidor. A parte mais interessante é que, uma vez recebida a mensagem, ela é transmitida de volta para cada cliente usando um alert() com o conteúdo da mensagem.

Testar o servidor WebSocket

No seu terminal, execute o seguinte comando para iniciar o servidor WebSocket:

$ php app.php

Em um terminal separado, execute o ngrok para expor o servidor HTTP à Internet.

$ ngrok http 80

tela do ngrok

Copie o endereço HTTPS de encaminhamento e cole-o em duas janelas separadas do navegador. Digite uma mensagem em cada entrada e pressione o botão "Send" (Enviar). Ele acionará o alerta em cada uma das janelas.

GIF testando o funcionamento do websocket

Recursos adicionais

Veja o "Tutorial para Websockets PHP que eu gostaria que existisse", criado por Samuel Attard, para saber mais sobre WebSockets PHP.

Conclusão

Estou muito empolgado com o que criamos; você também deve estar! Este tutorial prova que podemos realmente implementar WebSockets no PHP!

Se você já conhece o PHP, sabe que não podemos deixar este script em execução como está: uma vez que a conexão é fechada, o servidor deixará de existir.

Para remover essa limitação, podemos criar um serviço e executar o servidor em segundo plano.

Este artigo foi traduzido do original "How to Create a WebSocket Server in PHP with Ratchet for Real-Time Applications". Enquanto melhoramos nossos processos de tradução, adoraríamos receber seus comentários em help@twilio.com - contribuições valiosas podem render brindes da Twilio.


This content originally appeared on Twilio Blog and was authored by Luís Leão


Print Share Comment Cite Upload Translate Updates
APA

Luís Leão | Sciencx (2021-07-08T20:00:03+00:00) Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real. Retrieved from https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/

MLA
" » Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real." Luís Leão | Sciencx - Thursday July 8, 2021, https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/
HARVARD
Luís Leão | Sciencx Thursday July 8, 2021 » Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real., viewed ,<https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/>
VANCOUVER
Luís Leão | Sciencx - » Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/
CHICAGO
" » Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real." Luís Leão | Sciencx - Accessed . https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/
IEEE
" » Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real." Luís Leão | Sciencx [Online]. Available: https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/. [Accessed: ]
rf:citation
» Como criar um servidor WebSocket no PHP com Ratchet para aplicativos em tempo real | Luís Leão | Sciencx | https://www.scien.cx/2021/07/08/como-criar-um-servidor-websocket-no-php-com-ratchet-para-aplicativos-em-tempo-real/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.