Neste artigo vou explicar a tecnologia SSE – Server-Sent Events que permite trabalhar com conexões em páginas da web de uma maneira diferente do convencional. Com SSE, o servidor pode enviar dados para uma página a qualquer momento na forma de mensagens, que são recebidas automaticamente pelo navegador, e que podem ser acessadas dentro do JavaScript através de uma API chamada EventSource.
O que é Server-Sent Events?
A Internet é construída em cima de diversos padrões. Um dos mais importantes é o protocolo HTTP (Hyper Text Transfer Protocol), que descreve o funcionamento da interação entre cliente e servidor. De um modo geral, a web funciona de forma linear, isto é, o cliente solicita um recurso ao servidor, e este retorna para o cliente. No entanto, alguns tipos de aplicações web dependem de atualizações frequentes, como feeds de redes sociais e sites estilo “minuto-a-minuto”. Este tipo de fluxo já era possível, mas o navegador tinha que ficar acessando o servidor continuamente (em inglês, pooling) em busca de novas atualizações.
Como eu uso?
A implementação do SSE nos navegadores define uma API chamada `EventSource`. Esta API mantém aberta a conexão com o servidor e oferece métodos para gerenciar e fechar conexões, receber dados e tratar eventuais erros. Para usar esta API, deve-se criar (no cliente) um objeto do tipo `EventSource` e registrar alguns eventos:
// cria a conexão persistente var source = new EventSource('meu-updater.php'); // define um evento que é executado quando o servidor envia uma mensagem source.onmessage = function (event) { console.log(event.data); };
Com a conexão estabelecida, o cliente está pronto para receber mensagens do servidor. A implementação é barbada: o documento retornado deve ter o `Content-Type` `text/event-stream`, e o corpo deve seguir um formato simples, explicado logo adiante. Um exemplo de servidor (em PHP) segue abaixo:
header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $num = 0; for (;;) { echo "Numero agora: {$num}"; $num++; flush(); sleep(1); }
A resposta dada pelo servidor acima é a seguinte:
data: Numero agora: 0
e depois:
data: Numero agora: 1
e assim por diante.
O corpo do retorno enviado pelo servidor deve estar de acordo com o seguinte formato:
* `data`: texto que se quer retornar. Quando for retornado, vai acionar o evento `onMessage` que foi definido no cliente. Esse texto pode ser qualquer tipo de dado em formato texto: uma `string`, numeros, JSON, XML, etc.
* `retry`: especifica o intervalo entre tentativas de reconexão em caso de erros. Informado em millisegundos. O navegador tenta reconectar automaticamente respeitando esse valor.
* `id”:` Identificação única usado para definir a sequência dos eventos. Ao informar um `id`, o navegador sabe qual foi o ultimo evento disparado, e automaticamente envia um header `Last-Event-Id` na tentativa de reconexão. O servidor pode usar este header para saber quais dados deve enviar para o cliente (por exemplo, em qual ponto do feed estava).
* `event`: usado para criar eventos personalizados.
O tipo de evento pode ser capturado dentro do JavaScript com um `EventListener` padrão, buscando pelo nome deste. Por exemplo, o servidor pode retornar o seguinte:
event: teste
data: “dados de teste”
Neste caso, pra capturar este evento no cliente, pode-se utilizar:
source.addEventListener('teste', function(e) { console.warn('ok'); });
Para suportar CORS (Cross-Origin Resource Sharing) basta incluir um argumento opcional ao instanciar o objeto`EventSource`:
var es = new EventSource('servidor.php', { withCredentials: true });
A API do SSE também oferece outros eventos de controle de erro e conexão: `onOpen` (quando a conexão com o servidor foi aberta) e `onError` (quando ocorre um erro de conexão).
Comparação com outras alternativas
AJAX (programming) é um conjunto de tecnologias web que possibilita disparar requisições em background, sem recarregar a página, usando JavaScript. O AJAX usa conexões HTTP/HTTPS normais, e cria uma conexão para cada solicitação que for feita para o servidor. O SSE cria menos tráfego que AJAX pooling, já que o servidor só envia dados para o cliente quando existe algo novo para enviar. Isso reduz o número de conexões necessárias, o que pode ocasionar melhor desempenho.
Websockets é outra tecnologia que possibilita comunicações entre cliente/servidor. Ambos são bidirecionais, mas SSE funciona com HTTP normal, enquanto websockets usam um protocolo diferente. Como o formato das mensagens é definido pela aplicação, o overhead é potencialmente menor do que o SSE; além disso, as mensagens podem trafegar comprimidas e websockets não obriga o uso de TLS. Isso também significa que tudo que pode ser feito com SSE pode também ser feito com websockets. Apesar disso, o SSE é mais fácil de implementar, e usa a mesma segurança HTTP.
Compatibilidade do Server-Sent Events
A API que implementa o uso de SSE foi publicada como um padrão do WHATWG e é implementada pela maioria dos navegadores. SSE ainda não é suportado nativamente no MS Edge, mas está como Under Consideration, ou seja, é provável que seja implementado nas próximas versões.
Pessoal, espero que tenham gostado do artigo sobre Server-Sent Events. Caso tenham alguma dúvida, deixe nos comentários, que terei prazer em responder! Em breve, mais conteúdos meus aqui no Blog da KingHost.
O que você achou deste conteúdo?