Anwendung von WebSocket in der Echtzeit-Kommunikationstechnologie

Autor: Zen und die Kunst der Computerprogrammierung

1. Einleitung

WebSocket (Web Socket) ist ein Netzwerkkommunikationsprotokoll für die Vollduplex-Kommunikation über eine einzelne TCP-Verbindung. Es bietet eine bidirektionale Kommunikationsmethode, die es dem Server ermöglicht, aktiv Informationen an den Client zu übertragen. Mit dem Aufkommen von HTML5 ist WebSocket zu einem der wichtigsten Kommunikationsmittel zwischen modernen Browsern und Servern geworden. WebSocket kann eine Vielzahl von Anwendungsszenarien in Internetanwendungen einführen. In diesem Artikel werden hauptsächlich einige typische Anwendungsszenarien, Grundkonzepte, Algorithmusprinzipien und spezifische Codebeispiele von WebSocket in praktischen Anwendungen erläutert. Abschließend werden die zukünftige Entwicklungsrichtung und bestehende Probleme prospektiert. Ich hoffe, dass die Leser durch die Lektüre dieses Artikels das relevante Wissen über WebSocket beherrschen und es in der tatsächlichen Arbeit richtig anwenden können.

2. WebSocket-Konzept

WebSocket ist im Standarddokument RFC 6455 definiert. Sein Ziel besteht darin, einen Vollduplex-Kommunikationskanal auf einer einzelnen TCP-Verbindung bereitzustellen, der es dem Server ermöglicht, aktiv Daten an den Client zu übertragen, und das WebSocket-Protokoll sorgt für den Datenaustausch zwischen dem Client und dem Server einfacher. , effizient. Das WebSocket-Protokoll ist ein optionales Layer-Protokoll, das auf dem HTTP-Protokoll basiert. Wenn der Benutzer die Verwendung des WebSocket-Protokolls für den Zugriff auf die Seite anfordert, verwendet der Browser automatisch das WebSocket-Protokoll, um eine Verbindung mit dem Server für den Datenaustausch herzustellen.

2.1 Grundkonzepte

  • WebSocket ist ein Kommunikationsprotokoll, das auf dem HTTP-Protokoll basiert. Es ist ein unabhängiges Protokoll, das auf der Transportschicht der TCP/IP-Schicht 4 oder höher ausgeführt werden kann. Es besteht aus zwei Endpunkten – dem Client und dem Server. Das WebSocket-Protokoll basiert auf TCP/IP und erfordert den Aufbau von zwei TCP-Verbindungen, eine für die Verbindung vom Client zum Server und die andere für die Verbindung vom Server zum Client.
  • WebSocket verfügt über zwei Arbeitsmodi: den WebSocket-Client- und den WebSocket-Servermodus.
  • Der WebSocket-Client-Workflow ist wie folgt:
    • Der Benutzer sendet zunächst eine HTTP-Anfrage an den Server, um eine WebSocket-Verbindung herzustellen. Wenn der Server die Anfrage akzeptiert, gibt er den Statuscode 101 zurück, der angibt, dass er dem Aufbau einer WebSocket-Verbindung zustimmt.
    • Wenn der Aufbau erfolgreich ist, kann die Datenübertragung zwischen dem Client und dem Server mithilfe des TCP-Mechanismus für lange Verbindungen durchgeführt werden.
  • Der WebSocket-Server-Workflow ist wie folgt:
    • Nach dem Empfang der HTTP-Anfrage erstellt der Server einen Socket und wartet auf Client-Verbindungsanfragen.
    • Wenn der Client eine Verbindungsanforderung initiiert, empfängt der Server die Anforderung und weist eine eindeutige ID als WebSocket-Verbindungskennung zu;
    • Der Server sendet eine 101-Antwort, die angibt, dass er dem Aufbau einer WebSocket-Verbindung zugestimmt hat, und wartet dann darauf, dass der Client Daten sendet.
    • Sobald der Client die Daten sendet, verarbeitet der Server diese sofort und sendet die Daten an alle anderen Online-Clients.
  • Das WebSocket-Protokoll ist ein bidirektionales Kommunikationsprotokoll. Sowohl der Client als auch der Server können Nachrichten aneinander senden, sodass sowohl der Client als auch der Server das entsprechende Protokoll implementieren müssen. Beispielsweise muss der WebSocket-Client die WebSocket-API-Schnittstelle implementieren und der Server muss das entsprechende WebSocket-Serverprogramm bereitstellen.
  • Es gibt viele verschiedene Anwendungsszenarien im WebSocket-Protokoll, darunter: Chat-Systeme, Echtzeit-Daten-Push, Spieleentwicklung usw. Die am häufigsten verwendete Methode ist der Echtzeit-Datenpush, d. h. der Server überträgt die neuesten Daten an den Client.

    2.2 Datenrahmen

    WebSocket-Datenrahmen werden in zwei Typen unterteilt: Textdatenrahmen und binäre Datenrahmen. Textdatenrahmen werden im Allgemeinen zum Senden von Textdaten verwendet, während Binärdatenrahmen zum Senden von Binärdateien wie Bildern, Videos und Audios verwendet werden. Das WebSocket-Protokoll definiert die folgenden Regeln zur Unterscheidung von Datenrahmen:
  • Jeder Datenrahmen beginnt mit einem Nachrichtenheader fester Länge, der den Typ, die Länge, Erweiterungsfelder usw. des Datenrahmens angibt.
  • Es gibt auch ein FIN-Bit (Final Frame) im Header des Datenrahmens, mit dem markiert wird, ob der Datenrahmen der letzte Datenrahmen ist. Das heißt, in einer vollständigen Nachricht, wenn mehrere Datenrahmen vorhanden sind, das FIN des ersten Datenrahmens ist 0, die FIN der mittleren Datenrahmen ist alle 1 und die FIN des letzten Datenrahmens ist 0.
  • Nach dem Nachrichtenkopf folgt der Datenkörper. Bei Datenrahmen vom Typ „Text“ ist der Datenkörper eine Textzeichenfolge; bei Datenrahmen vom Binärtyp ist der Datenkörper ein Byte-Array oder ein Dateistream.

    2.3 Nachrichtentyp

    Das WebSocket-Protokoll definiert 4 verschiedene Arten von Nachrichten:
  • Texttyp (TEXT): Wird zum Senden von UTF-8-codierten Textdaten verwendet.
  • Binärtyp (BINARY): Wird zum Senden beliebiger Binärdaten wie Bilder, Videos, Audio usw. verwendet.
  • Ping-Nachricht: Wird verwendet, um zu überprüfen, ob die Verbindung zwischen dem Client und dem Server normal ist.
  • Pong-Nachricht: Nach dem Empfang der Ping-Nachricht sollte der Server eine Pong-Nachricht zurücksenden.

    2.4 Handshake-Verhandlungsprozess

    Das WebSocket-Protokoll spezifiziert den Handshake-Aushandlungsprozess zwischen dem Client und dem Server. Konkret ist der Handshake-Aushandlungsprozess in drei Schritte unterteilt:
  1. Verbindung anfordern: Zunächst sendet der Client eine WebSocket-Verbindungsanforderung, einschließlich des URI der angeforderten Ressource und einiger Anforderungsheaderfelder (z. B. Cookie).
  2. Der Server antwortet auf die Verbindung: Anschließend empfängt der Server die Verbindungsanfrage des Clients, bestätigt sie und antwortet mit dem Statuscode 101, der angibt, dass er dem Aufbau einer WebSocket-Verbindung zugestimmt hat. Gleichzeitig sendet der Server möglicherweise einige Header-Felder im Zusammenhang mit der WebSocket-Verbindung.
  3. Aufbau einer WebSocket-Verbindung: Im dritten Schritt schließen Client und Server die Handshake-Aushandlung ab und führen ein Upgrade auf das WebSocket-Protokoll durch. Zu diesem Zeitpunkt wird die WebSocket-Verbindung hergestellt.

    2.5 URI-Schemata

    Das URI-Schema des WebSocket-Protokolls ist ws:// oder wss://, was die unverschlüsselte Verbindung bzw. die verschlüsselte Verbindung von WebSocket unter Verwendung des http-Protokolls darstellt.

Beispiel:

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

3. Grundlegende Algorithmusprinzipien von WebSocket

Das WebSocket-Protokoll befindet sich auf Schicht 7 im Protokollstapel und kann daher an verschiedenen Kommunikationsprozessen im Internetprotokollstapel teilnehmen, z. B. HTTP-Anfragen, HTTPS-Anfragen, FTP-Anfragen usw. WebSocket übernimmt das Client/Server-Modell, das aus zwei Teilen besteht: Client und Server, und jeder Teil kann Verbindungsanfragen aktiv initiieren oder Verbindungsanfragen passiv akzeptieren. Um eine WebSocket-Verbindung herzustellen, führen der Client und der Server einen Handshake über das HTTP-Protokoll durch. Nach dem Verbindungsaufbau können beide Parteien Nachrichten direkt übertragen. Das WebSocket-Protokoll definiert eine Reihe von Funktionen. Beispielsweise ermöglicht WebSocket dem Server, Informationen aktiv an den Client zu übertragen, und unterstützt den Server dabei, Daten an den Client zu übertragen. Der WebSocket-Server kann Push-Nachrichten, Multiplexing, Komprimierung usw. unterstützen. Im Folgenden kombinieren wir die grundlegenden Algorithmusprinzipien des WebSocket-Protokolls, um die spezifischen Anwendungsszenarien, Grundkonzepte, Algorithmusprinzipien und spezifischen Codebeispiele zu analysieren.

4. WebSocket-Praxisfall – Veröffentlichungs- und Abonnementsystem

Das Publish/Subscribe-Muster (Publish/Subscribe) ist ein nachrichtenorientiertes verteiltes Rechenmodell. Es handelt sich um ein Muster der asynchronen Kommunikation auf einem Nachrichtenkanal, das es einer Gruppe von Terminals (sogenannten Herausgebern) ermöglicht, Nachrichten zu senden, ohne zu wissen, wer dafür verantwortlich ist . Interessiert an den Neuigkeiten. Nachrichten sind in der Regel begrenzt, sodass die Anzahl der Herausgeber und Abonnenten oft eine Viele-zu-Viele-Beziehung darstellt. Jedes Terminal kann als Herausgeber oder Abonnent fungieren, daher müssen die Abonnenten funktionsfähig bleiben, um bei Bedarf empfangen zu können. Nachricht des Herausgebers.

Über das WebSocket-Protokoll können wir problemlos ein Veröffentlichungs- und Abonnementsystem erstellen. Lassen Sie uns das Veröffentlichungs- und Abonnementsystem verwenden, um eine einfache Chatroom-Funktion zu implementieren. Zuerst schreiben wir den WebSocket-Servercode:

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);
});

Der obige Code ist hauptsächlich für den Start des WebSocket-Dienstes, das Speichern der Client-Abonnentenliste und die Verwaltung von Nachrichtensendungen zwischen Abonnenten verantwortlich. Unter anderem wird die Broadcast-Funktion verwendet, um Nachrichten an alle Abonnenten zu senden, einschließlich Willkommensnachrichten nach dem Beitritt neuer Abonnenten und Benachrichtigungsnachrichten nach der Trennung.

Als nächstes schreiben wir den WebSocket-Client-Code:

<!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>

Der obige Code ist hauptsächlich für die Initialisierung der WebSocket-Verbindung, die Überwachung von Nachrichten, den Empfang von Willkommensnachrichten und das Hinterlassen von Nachrichten sowie das Senden von Benutzereingabenachrichten verantwortlich. Da das WebSocket-Protokoll keine strikte Client-Server-Modus-Implementierung aufweist, hat der WebSocket-Client hier auch den Effekt, den Client zu „simulieren“, sodass Sie nur eine normale HTML-Seite und keine besonders komplexen Bibliotheken oder Plug-Ins vorbereiten müssen sind erforderlich. .

Ich denke du magst

Origin blog.csdn.net/universsky2015/article/details/133446696
Empfohlen
Rangfolge