Aplicação de WebSocket em tecnologia de comunicação em tempo real

Autor: Zen e a arte da programação de computadores

1. Introdução

WebSocket (Web Socket) é um protocolo de comunicação de rede para comunicação full-duplex em uma única conexão TCP. Ele fornece um método de comunicação bidirecional, permitindo que o servidor envie ativamente informações ao cliente. Com o surgimento do HTML5, o WebSocket se tornou uma das formas importantes de comunicação entre navegadores e servidores modernos. O WebSocket pode introduzir uma variedade de cenários de aplicativos em aplicativos da Internet. Este artigo discute principalmente alguns cenários típicos de aplicação, conceitos básicos, princípios de algoritmos e exemplos de código específicos de WebSocket em aplicações práticas. Por fim, prospecta-se a direção futura do desenvolvimento e os problemas existentes. Espero que ao ler este artigo, os leitores possam dominar o conhecimento relevante do WebSocket e utilizá-lo adequadamente no trabalho prático.

2. Conceito WebSocket

WebSocket é definido no documento padrão RFC 6455. Seu objetivo é fornecer um canal de comunicação full-duplex em uma única conexão TCP, permitindo que o servidor envie dados ativamente para o cliente, e o protocolo WebSocket faz a troca de dados entre o cliente e o servidor mais simples., eficiente. O protocolo WebSocket é um protocolo de camada opcional que depende do protocolo HTTP. Se o usuário solicitar o uso do protocolo WebSocket para acessar a página, o navegador usará automaticamente o protocolo WebSocket para estabelecer uma conexão com o servidor para troca de dados.

2.1 Conceitos básicos

  • WebSocket é um protocolo de comunicação baseado no protocolo HTTP. É um protocolo independente que pode ser executado na camada TCP/IP 4 ou acima da camada de transporte. É composto por dois endpoints - o cliente e o servidor. O protocolo WebSocket é construído em TCP/IP e requer o estabelecimento de duas conexões TCP, uma para a conexão do cliente ao servidor e outra para a conexão do servidor ao cliente.
  • WebSocket possui dois modos de funcionamento: modo cliente WebSocket e modo servidor WebSocket.
  • O fluxo de trabalho do cliente WebSocket é o seguinte:
    • O usuário primeiro envia uma solicitação HTTP ao servidor para estabelecer uma conexão WebSocket. Se o servidor aceitar a solicitação, ele retornará um código de status 101 indicando que concorda em estabelecer uma conexão WebSocket;
    • Se o estabelecimento for bem-sucedido, a transmissão de dados poderá ser realizada entre o cliente e o servidor, utilizando o mecanismo de conexão longa TCP.
  • O fluxo de trabalho do servidor WebSocket é o seguinte:
    • Depois de receber a solicitação HTTP, o servidor cria um soquete e escuta as solicitações de conexão do cliente;
    • Quando o cliente inicia uma solicitação de conexão, o servidor recebe a solicitação e atribui um ID exclusivo como identificador de conexão WebSocket;
    • O servidor envia uma resposta 101, indicando que concordou em estabelecer uma conexão WebSocket e, em seguida, aguarda o envio dos dados pelo cliente;
    • Assim que o cliente envia os dados, o servidor os processa imediatamente e os envia para todos os outros clientes online.
  • O protocolo WebSocket é um protocolo de comunicação bidirecional, tanto o cliente quanto o servidor podem enviar mensagens um ao outro, portanto, tanto o cliente quanto o servidor precisam implementar o protocolo correspondente. Por exemplo, o cliente WebSocket precisa implementar a interface API WebSocket e o servidor precisa implantar o programa de servidor WebSocket correspondente.
  • Existem muitos cenários de aplicação diferentes no protocolo WebSocket, incluindo: sistemas de chat, envio de dados em tempo real, desenvolvimento de jogos, etc. O mais comumente usado é o envio de dados em tempo real, ou seja, o servidor envia os dados mais recentes para o cliente.

    2.2 Quadro de dados

    Os quadros de dados WebSocket são divididos em dois tipos: quadros de dados de texto e quadros de dados binários. Os quadros de dados de texto geralmente são usados ​​para enviar dados de texto, enquanto os quadros de dados binários são usados ​​para enviar arquivos binários, como imagens, vídeos e áudios. O protocolo WebSocket define as seguintes regras para distinguir frames de dados:
  • Cada quadro de dados começa com um cabeçalho de mensagem de comprimento fixo, que especifica o tipo, comprimento, campos de extensão, etc. do quadro de dados.
  • Há também um bit FIN (Quadro Final) no cabeçalho do quadro de dados, que é usado para marcar se o quadro de dados é o último quadro de dados. Ou seja, em uma mensagem completa, se houver vários quadros de dados, o FIN do primeiro quadro de dados é 0, o FIN dos quadros de dados intermediários é 1 e o FIN do último quadro de dados é 0.
  • Após o cabeçalho da mensagem, segue o corpo dos dados. Para quadros de dados do tipo texto, o corpo dos dados é uma sequência de texto; para quadros de dados do tipo binário, o corpo dos dados é uma matriz de bytes ou fluxo de arquivo.

    2.3 Tipo de mensagem

    O protocolo WebSocket define 4 tipos diferentes de mensagens:
  • Tipo de texto (TEXT): usado para enviar dados de texto codificados em UTF-8.
  • Tipo binário (BINÁRIO): usado para enviar dados binários arbitrários, como imagens, vídeos, áudio, etc.
  • Mensagem Ping: utilizada para verificar se a conexão entre o cliente e o servidor está normal.
  • Mensagem Pong: Após receber a mensagem Ping, o servidor deverá retornar uma mensagem Pong.

    2.4 Processo de negociação de handshake

    O protocolo WebSocket especifica o processo de negociação de handshake entre o cliente e o servidor. Especificamente, o processo de negociação do handshake é dividido em três etapas:
  1. Solicitar conexão: primeiro, o cliente envia uma solicitação de conexão WebSocket, incluindo o URI do recurso solicitado e alguns campos de cabeçalho da solicitação (como Cookie).
  2. O servidor responde à conexão: Em seguida, o servidor recebe a solicitação de conexão do cliente, confirma e responde com um código de status 101, indicando que concordou em estabelecer uma conexão WebSocket. Ao mesmo tempo, o servidor pode enviar alguns campos de cabeçalho relacionados à conexão WebSocket.
  3. Estabelecimento da conexão WebSocket: Na terceira etapa, o cliente e o servidor concluem a negociação do handshake e atualizam para o protocolo WebSocket. Neste ponto, a conexão WebSocket é estabelecida.

    2.5 Esquemas de URI

    O esquema URI do protocolo WebSocket é ws:// ou wss://, que representam a conexão não criptografada e a conexão criptografada do WebSocket respectivamente, usando o protocolo http.

Exemplo:

ws://example.com/websocket
wss://secure.example.com:8080/websocket

3. Princípios básicos do algoritmo WebSocket

O protocolo WebSocket está na camada 7 da pilha de protocolos, portanto pode participar de vários processos de comunicação na pilha de protocolos da Internet, como solicitações HTTP, solicitações HTTPS, solicitações FTP, etc. WebSocket adota o modelo cliente/servidor, que consiste em duas partes: cliente e servidor, e cada parte pode iniciar ativamente solicitações de conexão ou aceitar passivamente solicitações de conexão. Para estabelecer uma conexão WebSocket, o cliente e o servidor realizarão um handshake através do protocolo HTTP e, após a conexão ser estabelecida, ambas as partes poderão transferir mensagens diretamente. O protocolo WebSocket define uma série de funções. Por exemplo, o WebSocket permite que o servidor envie informações ativamente para o cliente e oferece suporte ao servidor para enviar dados ao cliente. O servidor WebSocket pode suportar mensagens push, multiplexação, compactação, etc. Abaixo, combinamos os princípios básicos do algoritmo do protocolo WebSocket para analisar os cenários de aplicação específicos, conceitos básicos, princípios de algoritmo e exemplos de código específicos.

4. Caso prático WebSocket – sistema de publicação e assinatura

O padrão publicar/assinar (Publish/Subscribe) é um modelo de computação distribuída orientado a mensagens. É um padrão de comunicação assíncrona em um canal de mensagens que permite que um grupo de terminais (chamados editores) envie mensagens sem saber quem é o responsável por elas. .Interessado nas novidades. As mensagens geralmente são limitadas, portanto o número de editores e assinantes costuma ser um relacionamento muitos para muitos. Cada terminal pode atuar como editor ou assinante, portanto, os assinantes devem permanecer saudáveis ​​para receber quando necessário. A mensagem do editor.

Através do protocolo WebSocket, podemos construir facilmente um sistema de publicação e assinatura. Vamos usar o sistema de publicação e assinatura para implementar uma função simples de sala de chat. Primeiro, escrevemos o código do servidor WebSocket:

const express = require('express');
const app = express();

// 保存订阅的客户端对象列表
let subscribers = [];

app.use(express.json());

// 启动WebSocket服务
const server = require('http').createServer(app);
const wss = new (require('ws')).Server({server});

// 监听新连接事件
wss.on('connection', ws => {
  // 将新的客户端添加到订阅者列表中
  console.log(`[Server] New client connected`);
  subscribers.push(ws);

  // 向所有订阅者发送消息
  const message = JSON.stringify({
    type:'message',
    data: `A new subscriber has joined`
  });
  broadcast(message);

  // 监听客户端关闭事件
  ws.on('close', () => {
    // 从订阅者列表中移除该客户端
    subscribers.splice(subscribers.indexOf(ws), 1);

    // 向所有订阅者发送消息
    const leftMessage = JSON.stringify({
      type: 'left',
      data: `${ws._socket.remoteAddress} disconnected`
    });
    broadcast(leftMessage);
    console.log(`[Server] ${ws._socket.remoteAddress} disconnected`);
  });
});

function broadcast(data) {
  for (let i = 0; i < subscribers.length; i++) {
    try {
      // 向订阅者发送消息
      subscribers[i].send(data);
    } catch (err) {}
  }
}

// 启动服务端口
server.listen(3000, function() {
  console.log('[Server] Listening on port %d', server.address().port);
});

O código acima é o principal responsável por iniciar o serviço WebSocket, salvar a lista de assinantes do cliente e gerenciar a transmissão de mensagens entre assinantes. Entre eles, a função de transmissão é usada para transmitir mensagens para todos os assinantes, incluindo mensagens de boas-vindas após a adesão de novos assinantes e mensagens de notificação após a desconexão.

A seguir, escrevemos o código do cliente WebSocket:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>WebSocket Chat</title>
</head>
<body>
  <!-- 欢迎信息 -->
  <h1 id="welcome"></h1>

  <!-- 消息列表 -->
  <ul id="messages"></ul>

  <!-- 输入框 -->
  <input type="text" id="messageBox" placeholder="Say something..." />

  <!-- 脚本 -->
  <script src="/socket.io/socket.io.js"></script>
  <script>
    // 创建Socket连接
    let socket = io();

    // 获取欢迎信息
    socket.emit('join', {username: prompt("Please enter your name:")});

    // 绑定收到的消息
    socket.on('message', msg => {
      const li = document.createElement('li');
      li.textContent = `${msg.username}: ${msg.content}`;
      document.getElementById('messages').appendChild(li);
    });

    // 绑定用户加入信息
    socket.on('joined', username => {
      document.getElementById('welcome').innerHTML = `<p>Welcome to the chat room, ${username}!</p>`;
    });

    // 绑定用户离开信息
    socket.on('left', username => {
      const li = document.createTextNode(`${username} left.`);
      document.getElementById('messages').appendChild(li);
    });

    // 绑定提交按钮点击事件
    document.getElementById('messageBox').addEventListener('keypress', e => {
      if (e.keyCode === 13 &&!e.shiftKey) {
        e.preventDefault();

        // 获取输入的内容
        const content = document.getElementById('messageBox').value;

        // 清空输入框
        document.getElementById('messageBox').value = '';

        // 发送消息
        socket.emit('message', {
          username: prompt("Enter your name:"),
          content: content
        });
      }
    });
  </script>
</body>
</html>

O código acima é o principal responsável por inicializar a conexão WebSocket, monitorar mensagens, receber mensagens de boas-vindas e deixar mensagens e enviar mensagens de entrada do usuário. Como o protocolo WebSocket não possui uma implementação estrita do modo cliente-servidor, o cliente WebSocket aqui também tem o efeito de "simular" o cliente, então você só precisa preparar uma página HTML comum, e nenhuma biblioteca ou plug-in particularmente complexo são obrigatórios. .

Acho que você gosta

Origin blog.csdn.net/universsky2015/article/details/133446696
Recomendado
Clasificación