ホームページ > ウェブフロントエンド > フロントエンドQ&A > WebSocket について 10 分で簡単に学びましょう! !

WebSocket について 10 分で簡単に学びましょう! !

青灯夜游
リリース: 2021-02-15 09:18:19
転載
3109 人が閲覧しました

WebSocket について 10 分で簡単に学びましょう! !

WebSocket とは

定義

WebSocket は、単一の TCP 接続で実行できる永続的なネットワーク通信プロトコルです。フルダブル産業用通信には、RequestResponseという概念はなく、両者は完全に同等の状態であり、一度接続が確立されれば双方向のデータ通信が可能となります。クライアントとサーバー間のリアルタイムの通信

関係と相違点

  • ##HTTP
#HTTP は非永続的なプロトコルです。クライアントは、サーバーの処理の進行状況を知りたいと考えています。これは、ポーリングに常に
    Ajax
  1. を使用するか、long poll を使用することによってのみ行うことができますが、前者では大量の時間がかかります。サーバーに負荷がかかり、後者は応答の待機によりブロックを引き起こしますhttp1.1 はデフォルトで有効になっていますが
  2. キープアライブ
  3. 長い接続この TCP チャネル を維持すると、HTTP 接続で複数のリクエストを送信し、複数のレスポンスを受信できますが、1 つのリクエストに含めることができるレスポンスは 1 つだけです。さらに、この反応も受動的であり、能動的に開始することはできません。 websocket は HTTP から独立したプロトコルですが、websocket は
  4. ハンドシェイク
  5. (ハンドシェイク フェーズは同じです) では HTTP プロトコルに依存する必要があります。ハンドシェイクが成功した後、データが転送されます。 TCP からの直接送信 チャネル送信は HTTP とは何の関係もありません。図を使用して 2 つの共通点を理解できますが、すべてを理解できるわけではありません。
socket
  • ##socket は
  • ソケットとも呼ばれます ## という単語# HTTP や WebSocket とは異なり、ソケットはプロトコルではなく、トランスポート層プロトコル (主に TCP/IP として理解できます) をプログラム レベルでカプセル化したインターフェイスです。これは、エンドツーエンド通信を提供できる呼び出しインターフェイス (API) として理解できます。プログラマの場合、A 側でソケット インスタンスを作成し、このインスタンスに接続先の B 側の IP を提供する必要があります。アドレスとポート番号を指定して、B 側に別のソケット インスタンスを作成し、リッスンするローカル ポート番号をバインドします。 A と B が接続を確立すると、両者はエンドツーエンドの TCP 接続を確立し、双方向通信が可能になります。 WebSocket はソケットの概念を利用し、クライアントとサーバーの間に同様の双方向通信メカニズムを提供します
  1. アプリケーション シナリオWebSocket は集中砲火、メッセージ サブスクリプション、マルチ攻撃を行うことができます。 - プレイヤー ゲーム、共同編集、株式ファンドのリアルタイム相場、ビデオ会議、オンライン教育、チャット ルーム、その他のアプリケーションはサーバー側の変更をリアルタイムで監視できます
  2. Websocket ハンドシェイク

Websocket ハンドシェイク要求メッセージ:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
ログイン後にコピー

従来の HTTP メッセージとの違いは次のとおりです:

Upgrade: websocket
Connection: Upgrade
ログイン後にコピー

は、WebSocket プロトコルが開始されたことを示します
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13
    ログイン後にコピー
  • # #Sec-WebSocket-Key
  • は、悪意のある接続や意図しない接続を防ぐために、WebSocket 通信が可能かどうかを検証するためにブラウザによってランダムに生成されます。

Sec_WebSocket-Protocol

は、サービスに必要なプロトコルを識別するために使用されるユーザー定義の文字列です。

Sec-WebSocket-Version は、WebSocket のサポートを示しますバージョン。

サーバー応答:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
ログイン後にコピー

101 応答コード は、プロトコルを変換する必要があることを示します。

  • Connection: Upgrade
  • 新しいプロトコルをアップグレードするリクエストを表します。

アップグレード: websocket は、WebSocket プロトコルへのアップグレードを意味します。

Sec-WebSocket-Accept は、サーバーによって確認され、暗号化された Sec-WebSocket-Key です。クライアントとサーバー間で通信が可能であることを証明するために使用されます。

Sec-WebSocket-Protocol は、使用される最終プロトコルを示します。

この時点で、クライアントとサーバーはハンドシェイクを介して Websocket 接続を正常に確立しました。HTTP はすべての作業を完了しました。次のステップは、Websocket プロトコルに完全に従って通信することです。 Websocket について

WebSocket ハートビートSOCKET が切断される原因となる未知の状況が存在する可能性がありますが、クライアントとサーバーはそれを認識せず、クライアントはそれを認識する必要があります。 ##Heartbeat Ping

サーバーにオンラインであることを知らせ、サーバーも

Heartbeat Ping

で応答してクライアントに利用可能であることを伝える必要があります。切断されたとみなされます

WebSocket ステータス

WebSocket オブジェクトのreadyState 属性には 4 つの状態があります。

#0: 接続が確立されていることを示します1: 接続が成功し、通信が可能であることを示します。

2: 接続がクローズ中であることを示します。

##3: 接続がクローズされたか、接続のオープンに失敗したことを示します。

    WebSocket の実践
  • サーバーはメッセージを送受信します
  • WebSocket サーバー部分、この記事では Node.js を使用して
  • インストール#を構築しますWebSocket プロトコルの処理を担当する ##express
  • ws
:

npm install express ws
ログイン後にコピー

installation 成功後の Package.json:

次に、server.js ファイルをルートディレクトリ:

//引入express 和 ws
const express = require('express');
const SocketServer = require('ws').Server;
//指定开启的端口号
const PORT = 3000;
// 创建express,绑定监听3000端口,且设定开启后在consol中提示
const server = express().listen(PORT, () => console.log(`Listening on ${PORT}`));
// 将express交给SocketServer开启WebSocket的服务
const wss = new SocketServer({ server });
//当 WebSocket 从外部连接时执行
wss.on('connection', (ws) => {
  //连接时执行此 console 提示
  console.log('Client connected');
  // 对message设置监听,接收从客户端发送的消息
  ws.on('message', (data) => {
    //data为客户端发送的消息,将消息原封不动返回回去
    ws.send(data);
  });
  // 当WebSocket的连接关闭时执行
  ws.on('close', () => {
    console.log('Close connected');
  });
});
ログイン後にコピー

ノードserver.jsを実行してサービスを開始します。ポートが開いた後、サービスを説明するリスニングタイムの印刷プロンプトが実行されます。正常に開始されました

WebSocketを開いた後、サーバーはメッセージをリッスンし、パラメーター データを受信して​​クライアントから送信されたメッセージをキャプチャし、send を使用してメッセージを送信します。クライアントはメッセージを受信および送信します。

Createそれぞれルート ディレクトリにあるindex.html ファイルとindex.js ファイル

  • index.html
<html>
  <body>
    <script src="./index.js"></script>
  </body>
</html>
ログイン後にコピー
  • index.js
// 使用WebSocket的地址向服务端开启连接
let ws = new WebSocket(&#39;ws://localhost:3000&#39;);
// 开启后的动作,指定在连接后执行的事件
ws.onopen = () => {
  console.log(&#39;open connection&#39;);
};
// 接收服务端发送的消息
ws.onmessage = (event) => {
  console.log(event);
};
// 指定在关闭后执行的事件
ws.onclose = () => {
  console.log(&#39;close connection&#39;);
};
ログイン後にコピー

上面的url就是本机node开启的服务地址,分别指定连接(onopen),关闭(onclose)和消息接收(onmessage)的执行事件,访问html,打印ws信息

打印了open connection说明连接成功,客户端会使用onmessage处理接收

其中event参数包含这次沟通的详细信息,从服务端回传的消息会在event的data属性中。

手动在控制台调用send发送消息,打印event回传信息:

服务端定时发送

上面是从客户端发送消息,服务端回传。我们也可以通过setInterval让服务端在固定时间发送消息给客户端:

server.js修改如下:

//当WebSocket从外部连接时执行
wss.on(&#39;connection&#39;, (ws) => {
  //连接时执行此 console 提示
  console.log(&#39;Client connected&#39;);
+  //固定发送最新消息给客户端
+  const sendNowTime = setInterval(() => {
+    ws.send(String(new Date()));
+  }, 1000);
-  //对message设置监听,接收从客户端发送的消息
-  ws.on(&#39;message&#39;, (data) => {
-    //data为客户端发送的消息,将消息原封不动返回回去
-    ws.send(data);
-  });
  //当 WebSocket的连接关闭时执行
  ws.on(&#39;close&#39;, () => {
    console.log(&#39;Close connected&#39;);
  });
});
ログイン後にコピー

客户端连接后就会定时接收,直至我们关闭websocket服务

多人聊天

如果多个客户端连接按照上面的方式只会返回各自发送的消息,先注释服务端定时发送,开启两个窗口模拟:

如果我们要让客户端间消息共享,也同时接收到服务端回传的消息呢?

我们可以使用clients找出当前所有连接中的客户端 ,并通过回传消息发送到每一个客户端 中:

修改server.js如下:

...
//当WebSocket从外部连接时执行
wss.on(&#39;connection&#39;, (ws) => {
  //连接时执行此 console 提示
  console.log(&#39;Client connected&#39;);
-  //固定发送最新消息给客户端
-  const sendNowTime = setInterval(() => {
-    ws.send(String(new Date()));
- }, 1000);
+  //对message设置监听,接收从客户端发送的消息
+   ws.on(&#39;message&#39;, (data) => {
+    //取得所有连接中的 客户端
+    let clients = wss.clients;
+    //循环,发送消息至每个客户端
+    clients.forEach((client) => {
+      client.send(data);
+    });
+   });
  //当WebSocket的连接关闭时执行
  ws.on(&#39;close&#39;, () => {
    console.log(&#39;Close connected&#39;);
  });
});
ログイン後にコピー

这样一来,不论在哪个客户端发送消息,服务端都能将消息回传到每个客户端 : 可以观察下连接信息:

总结 

纸上得来终觉浅,绝知此事要躬行,希望大家可以把理论配合上面的实例进行消化,搭好服务端也可以直接使用测试工具好好玩耍一波

更多编程相关知识,请访问:编程教学!!

以上がWebSocket について 10 分で簡単に学びましょう! !の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート