Tempo real por WebSocket
Guia de uso do canal ao vivo. A referência completa do canal está na navegação lateral, em Canais assíncronos.
O ciclo
Seção intitulada “O ciclo”- Abra a conexão, autenticando conforme o seu tipo de cliente (ver autenticação).
- Envie um
subscribecom os ids das estações. - Receba
subscription.updated, depoisreadinga cada leitura nova.
Uma conexão sem assinatura não recebe nada: abrir e esperar não funciona.
De servidor, o handshake leva a credencial no cabeçalho:
// Node, biblioteca wsconst ws = new WebSocket('wss://stream.radar-sandbox.kitelife.com.br/v1/stream', { headers: { Authorization: `Bearer ${process.env.RADAR_API_KEY}` },})
ws.on('open', () => ws.send(JSON.stringify({ action: 'subscribe', stations: ['stn_barra-da-tijuca-01'],})))
ws.on('message', (raw) => { const msg = JSON.parse(raw) if (msg.type === 'reading') gravar(msg.data) if (msg.type === 'station.status' && msg.status === 'offline') marcarComoAntigo(msg.stationId)})Do navegador, onde não há como definir cabeçalhos, o handshake usa um ticket pedido antes na REST:
const ws = new WebSocket(`wss://stream.radar-sandbox.kitelife.com.br/v1/stream?ticket=${ticket}`)Assinatura substitui, não acumula
Seção intitulada “Assinatura substitui, não acumula”Cada subscribe troca a lista inteira. Para acompanhar mais uma estação,
mande as antigas junto com a nova. Mandar só a nova cancela as outras, e este é
o erro mais comum nesta API.
Confira o subscription.updated que volta: ele traz o que ficou assinado de
fato. Um id inexistente ou fora do escopo da sua chave é omitido em silêncio,
sem erro, então a única forma de perceber o engano é comparar o que você pediu
com o que voltou.
Reconexão
Seção intitulada “Reconexão”Conexão de longa duração cai, e isso não é falha de ninguém. Rede móvel oscila, proxies encerram conexões ociosas, e de vez em quando publicamos uma versão nova. Nenhuma dessas situações está sob o seu controle, então o cliente precisa saber reconectar sozinho.
Três regras:
Espere antes de tentar de novo, e espere cada vez mais. Comece em 1 segundo e dobre até um teto de 30. Reconexão imediata em laço, multiplicada por todos os clientes que caíram ao mesmo tempo, transforma uma implantação de rotina em uma indisponibilidade.
Adicione aleatoriedade. Se todos os clientes esperam exatamente 1, 2, 4 segundos, todos voltam no mesmo instante. Um desvio aleatório de até 30% no intervalo resolve.
No navegador, peça um ticket novo a cada tentativa. O ticket é de uso único
e expira em 60 segundos. Reaproveitar o da conexão anterior falha com
Ticket.Expired, e tentar em laço com um ticket morto queima a sua cota sem
nunca conectar.
let tentativa = 0
async function conectar() { const ticket = await pedirTicket() const ws = new WebSocket(`wss://…/v1/stream?ticket=${ticket}`)
ws.onopen = () => { tentativa = 0; assinar(ws) } ws.onclose = () => { const base = Math.min(1000 * 2 ** tentativa++, 30000) setTimeout(conectar, base * (0.85 + Math.random() * 0.3)) }}O que você perde ao cair
Seção intitulada “O que você perde ao cair”Tudo o que passou enquanto você estava fora. O canal não tem fila nem reposição: ao reconectar, você recebe a próxima leitura, não as anteriores.
Se a lacuna importa, preencha pela REST, com GET /stations/{id}/readings e
from no instante da última leitura recebida. Se lacunas importam sempre e em
volume, o canal certo é o relay AMQP, que guarda.
Erros não derrubam a conexão
Seção intitulada “Erros não derrubam a conexão”Uma mensagem error é informativa: a conexão segue aberta e a assinatura
anterior continua valendo. A exceção é fatal: true, quando o servidor fecha
logo depois. Aí reconectar imediatamente não adianta, porque o problema é a
credencial ou a requisição, e vai se repetir.
Estação offline
Seção intitulada “Estação offline”Quando uma estação assinada cai, chega um station.status com offline. As
estações não têm bateria, então uma queda de energia no local as derruba por
inteiro, em segundos.
O que a sua interface faz com isso importa mais do que parece. O último valor recebido continua na tela, correto quando chegou e cada vez mais velho depois. Marque-o como antigo: mostre a hora da medição, esmaeça o número, o que couber no seu desenho. Um vento de 20 nós exibido como atual, medido há três horas, é pior do que não mostrar nada.
Limites
Seção intitulada “Limites”| Limite | Valor |
|---|---|
| Estações por conexão | 50 |
| Conexões simultâneas por chave | negociável |
| Validade do ticket | 60 s, uso único |
Precisando de mais de 50 estações, abra outra conexão ou vá de AMQP. Trinta estações de 8 segundos já são cerca de quatro mensagens por segundo: verifique se o seu cliente aguenta antes de aumentar.