Breve descrição da tecnologia
Websocket é um protocolo de comunicação através de uma conexão TCP, projetado para trocar mensagens entre um navegador e um servidor web em tempo real.
O cliente e o servidor usam um protocolo semelhante ao HTTP para estabelecer uma conexão WebSocket. O cliente faz uma solicitação HTTP especial à qual o servidor responde de uma maneira específica.
Comentários
Embora as novas solicitações e respostas sejam "semelhantes" às solicitações e respostas HTTP, não são. Por exemplo, uma solicitação tem um corpo, mas não há nenhum campo "Content-Length" nos cabeçalhos (o que viola as convenções HTTP). Você pode ler mais sobre isso na Wikipedia .
Uma das principais vantagens da tecnologia é a sua simplicidade. Existem apenas 4 eventos no cliente e servidor para processar:
- conexão
- erro
- mensagem
- perto
Por que Websocket?
Além do ws, existem dois outros métodos de transmissão contínua de dados: Eventos enviados pelo servidor (SSE) e Long Polling.
Vamos comparar os mecanismos de comunicação contínua entre o servidor e o cliente, e também tirar conclusões sobre porque vale (ou não vale) usar um websocket.
Websocket | sse | longa piscina | |
---|---|---|---|
protocolo | websocket (ws ou wss) | HTTP (S) | HTTP (S) |
Rapidez | Alto | baixo | baixo |
direcionalidade de fluxos de dados | bidirecional | unidirecional | bidirecional |
Além disso | transferência de dados binários, não
há suporte para alguns navegadores antigos |
reconexão automática quando a conexão é interrompida |
Uma das principais vantagens da tecnologia ws é a velocidade de transferência de dados. SSE e LP usam o protocolo HTTP (S) e funcionam da seguinte forma:
- Fazer um pedido de mudanças;
- Se alterações aparecerem no servidor, o servidor as enviará;
- , .
:
api.
const http = require("http");
const express = require( "express");
const WebSocket = require( "ws");
const app = express();
const server = http.createServer(app);
const webSocketServer = new WebSocket.Server({ server });
webSocketServer.on('connection', ws => {
ws.on('message', m => {
webSocketServer.clients.forEach(client => client.send(m));
});
ws.on("error", e => ws.send(e));
ws.send('Hi there, I am a WebSocket server');
});
server.listen(8999, () => console.log("Server started"))
O que está acontecendo aqui?
Para criar um servidor que suporte ws, criamos um servidor http regular e, em seguida, vinculamos um servidor a ele ao criar um websocket.
A função “on” ajuda a gerenciar eventos de websocket. O evento mais notável é o evento de mensagem, então vamos dar uma olhada nele.
Aqui a função recebe o parâmetro m - a mensagem, ou seja, o que o usuário enviou. Assim, podemos enviar uma string do cliente e processá-la no servidor. Nesse caso, o servidor simplesmente encaminha esta mensagem para todos os conectados ao servidor websocket. A matriz de clientes do objeto webSocketServer contém todas as conexões com o servidor. O objeto ws armazena apenas uma conexão por vez.
Comente
Você não deve usar essa abordagem em um aplicativo real. Se a API for descrita dessa forma, o servidor não poderá distinguir uma solicitação da outra. Como você pode construir uma API baseada em websocket será escrito mais tarde.
A interação com o servidor no cliente será assim:
export const wsConnection = new WebSocket("ws://localhost:8999");
wsConnection.onopen = function() {
alert(" .");
};
wsConnection.onclose = function(event) {
if (event.wasClean) {
alert(' ');
} else {
alert(' '); // , ""
}
alert(': ' + event.code + ' : ' + event.reason);
};
wsConnection.onerror = function(error) {
alert(" " + error.message);
};
export const wsSend = function(data) {
// readyState - true,
if(!wsConnection.readyState){
setTimeout(function (){
wsSend(data);
},100);
} else {
wsConnection.send(data);
}
};
API baseada em Websocket
Ao contrário da API REST, em que as solicitações são distribuídas em diferentes urls, a API Websocket tem apenas um url. Para construir uma API completa baseada em websockets, você precisa ensinar o sistema a distinguir uma solicitação de outra. Isso pode ser implementado da seguinte forma:
1) Do cliente, transmitiremos solicitações na forma de uma string json, que analisaremos no servidor:
const sendMessage = (message) => conn.send(JSON.stringify({ event: "chat-message", payload: { userName, message }}));
2) No servidor, analisamos a string e selecionamos o campo do evento - o tipo de solicitação. Vamos escrever a resposta correspondente para cada tipo:
const dispatchEvent = (message, ws) => {
const json = JSON.parse(message);
switch (json.event) {
case "chat-message": webSocketServer.clients.forEach(client => client.send(message));
default: ws.send((new Error("Wrong query")).message);
}
}
Assim, podemos enviar diferentes solicitações para o servidor e processar a resposta dependendo da solicitação.
Conclusão
Se você recebeu a tarefa de fazer uma API e descobriu que o cliente não está interessado em suportar navegadores antigos, uma API baseada em WebSocket é uma excelente escolha. Para sua comodidade, preparamos o código para as partes cliente e servidor no link .