最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Websocket的用法及常見應用場景

 更新時間:2025年12月16日 10:02:32   作者:英子的搬磚日志  
本文詳細介紹了WebSocket的基本概念、特點、與HTTP的區(qū)別、常見應用場景、實例以及心跳機制,WebSocket是一種在單個TCP連接上進行全雙工通信的協(xié)議,適用于實時數(shù)據(jù)傳輸場景,如實時聊天、實時協(xié)作、實時數(shù)據(jù)推送等

一、什么是Websocket

WebSocket 是一種在單個 TCP 連接上進行 全雙工 通信的協(xié)議,它可以讓客戶端和服務器之間進行實時的雙向通信。

WebSocket 使用一個長連接,在客戶端和服務器之間保持持久的連接,從而可以實時地發(fā)送和接收數(shù)據(jù)。

在 WebSocket 中,客戶端和服務器之間可以互相發(fā)送消息,客戶端可以使用 JavaScript 中的 WebSocket API 發(fā)送消息到服務器,也可以接收服務器發(fā)送的消息。

二、Websocket特點

簡單來說,websocket 具有 雙向通信,實時性強,支持二進制,控制開銷 的特點。

1、協(xié)議標識符是ws(如果加密,則為wss),服務器網(wǎng)址就是 URL。

2、實時通信,服務器可以隨時主動給客戶端下發(fā)數(shù)據(jù)。

3、保持連接狀態(tài),Websocket需要先創(chuàng)建連接,所以是一種有狀態(tài)的協(xié)議,之后通信時就可以省略部分狀態(tài)信息。

4、控制開銷,連接創(chuàng)建后,服務器和客戶端之間交換數(shù)據(jù)時,用于協(xié)議控制的數(shù)據(jù)包頭部相對較小。在不包含擴展的情況下,對于服務器到客戶端的內容,此頭部大小只有2至10字節(jié)(和數(shù)據(jù)包長度有關);對于客戶端到服務器的內容,頭部還需要加上額外的4字節(jié)的掩碼。

5、實現(xiàn)簡單,建立在 TCP 協(xié)議之上,服務器端的實現(xiàn)比較容易,并且沒有同源限制,客戶端可以與任意服務器通信。

6、支持二進制傳輸,Websocket定義了二進制幀,可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)。

7、與 HTTP 協(xié)議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器。

8、支持擴展,用戶可以擴展協(xié)議、實現(xiàn)部分自定義的子協(xié)議,如部分瀏覽器支持壓縮等。

三、WebSocket與HTTP的區(qū)別

websocket和http都是基于TCP的應用層協(xié)議,使用的也是 80 端口(若運行在 TLS 之上時,默認使用 443 端口)。

區(qū)別主要就在于連接的性質和通信方式

WebSocket是一種雙向通信的協(xié)議,通過一次握手即可建立持久性的連接,服務器和客戶端可以隨時發(fā)送和接收數(shù)據(jù)。

而HTTP協(xié)議是一種請求-響應模式的協(xié)議,每次通信都需要發(fā)送一條請求并等待服務器的響應。

WebSocket的實時性更好,延遲更低,并且在服務器和客戶端之間提供雙向的即時通信能力,適用于需要實時數(shù)據(jù)傳輸?shù)膱鼍啊?/p>

四、常見應用場景

  1. 實時聊天:WebSocket能夠提供雙向、實時的通信機制,使得實時聊天應用能夠快速、高效地發(fā)送和接收消息,實現(xiàn)即時通信。
  2. 實時協(xié)作:用于實時協(xié)作工具,如協(xié)同編輯文檔、白板繪畫、團隊任務管理等,團隊成員可以實時地在同一頁面上進行互動和實時更新。
  3. 實時數(shù)據(jù)推送:用于實時數(shù)據(jù)推送場景,如股票行情、新聞快訊、實時天氣信息等,服務器可以實時將數(shù)據(jù)推送給客戶端,確保數(shù)據(jù)的及時性和準確性。
  4. 多人在線游戲:實時的雙向通信機制,適用于多人在線游戲應用,使得游戲服務器能夠實時地將游戲狀態(tài)和玩家行為傳輸給客戶端,實現(xiàn)游戲的實時互動。
  5. 在線客服:WebSocket可以用于在線客服和客戶支持系統(tǒng),實現(xiàn)實時的客戶溝通和問題解決,提供更好的用戶體驗,減少等待時間。

五、websocket實例

為了建立一個 WebSocket 連接,客戶端瀏覽器首先要向服務器發(fā)起一個 HTTP 請求,這個請求和通常的 HTTP 請求不同,包含了一些附加頭信息,其中附加頭信息"Upgrade: WebSocket"表明這是一個申請協(xié)議升級的 HTTP 請求,服務器端解析這些附加的頭信息然后產(chǎn)生應答信息返回給客戶端,客戶端和服務器端的 WebSocket 連接就建立起來了,雙方就可以通過這個連接通道自由的傳遞信息,并且這個連接會持續(xù)存在直到客戶端或者服務器端的某一方主動的關閉連接。

1)Websocket事件

  • onopen: 客戶端和服務器建立連接后觸發(fā),被稱為客戶端和服務器之間的初始握手。如果接收到open, 說明已經(jīng)連接成功,可以進行通信了。
  • onmessage: 接收到消息時觸發(fā)。服務器發(fā)送給客戶端的消息可包括純文本消息,二進制數(shù)據(jù)(Blob消息或者ArrayBuffer消息)。
  • onerror: 響應意外故障時觸發(fā),在錯誤之后總是會終止連接。
  • onclose:連接關閉時觸發(fā)。一旦連接關閉后,客戶端和服務端將不會再進行消息的收發(fā)。也可主動調用close()方法關閉連接。

2)Websocket方法

  • send() : 在連接成功后關閉前,發(fā)送消息(onopen后和onclose前才可發(fā)送消息)

參數(shù):

  • data: 要發(fā)送的數(shù)據(jù),可以是字符串、二進制數(shù)據(jù)或者 Blob 對象。
  • close() : 關閉連接

參數(shù):

  • code (可選): 一個數(shù)字,表示連接關閉的狀態(tài)碼。常見的狀態(tài)碼有 1000 表示正常關閉,1001 表示端點離開,等等。
  • reason (可選): 一個字符串,表示連接關閉的原因。

3)Websocket對象屬性

  • readyState:只讀屬性,表示W(wǎng)ebsocket的連接狀態(tài)。
    1. CONNECTING — 正在連接中,對應的值為 0;
    2. OPEN — 已經(jīng)連接并且可以通訊,對應的值為 1;
    3. CLOSING — 連接正在關閉,對應的值為 2;
    4. CLOSED — 連接已關閉或者沒有連接成功,對應的值為 3。
  • bufferedAmount:未發(fā)送至服務器的字節(jié)數(shù),只讀屬性。已被 send() 放入正在隊列中等待傳輸,但是還沒有發(fā)出的 UTF-8 文本字節(jié)數(shù)。
  • binaryType:使用二進制的數(shù)據(jù)類型連接,可以是 “blob” 或 “arraybuffer”。
  • extensions:服務器選擇的通信擴展。
  • protocol:打開握手期間使用的協(xié)議(服務器選擇的子協(xié)議)。
  • url: webSocket 的絕對路徑。

4)websocket請求報文

// websocket握手:客戶端發(fā)送的請求頭
GET wss://www.example.cn/webSocket HTTP/1.1  // 使用的https協(xié)議, 對應的wss請求
Host: www.example.cn
Connection: Upgrade  // 帶upgrade頭的http1.1消息必須含有connection頭,表示任何接受此消息的人都在轉發(fā)此消息之前處理掉connection中指定的域(即不轉發(fā)upgrade域)
Upgrade: websocket  				// 定義轉換協(xié)議的header域,如果服務器支持,客戶端希望使用已經(jīng)建立好的http(tcp)連接
Sec-WebSocket-Version: 13 	// 客戶端支持的WebSocket協(xié)議的版本列表
Origin: http://example.cn 	// Origin為安全使用,防止跨站攻擊,瀏覽器一般會使用這個來標識原始域,類似于Referer。但與Referer 不同的是,Origin 只包含了協(xié)議和主機名稱
Sec-WebSocket-Key: afmbhhBRQuwCLmnWDRWHxw== // 客戶端隨機生成的字符串,服務器會使用此字段組裝成另一個key值(構造出一個SHA-1 的信息摘要)放在握手返回信息里,用于客戶端到服務器websocket的初始握手,避免夸協(xié)議攻擊
Sec-WebSocket-Protocol: chat, superchat 		// 首標,告訴客戶端應用程序可使用的協(xié)議
Sec-WebSocket-Extensions: permessage-deflate // 首標,permessage-deflate:協(xié)商使用傳輸數(shù)據(jù)壓縮,client_max_window_bits:擦采用LZ77壓縮算法時,滑動窗口相關SIZE大小

// websocket握手:服務器發(fā)出的響應頭
HTTP/1.1 101 // 服務端響應101狀態(tài)碼、Upgrade和Sec-WebSocket-Accept首標才算連接成功,否則不能連接成功。
Server: nginx/1.12.2
Date: Sat, 11 Aug 2018 13:21:27 GMT
Connection: upgrade // 指定一項或多項協(xié)議名,按優(yōu)先級排序,以逗號分隔,這里表示升級為 WebSocket 協(xié)議
Upgrade: websocket
Sec-WebSocket-Accept: sLMyWetYOwus23qJyUD/fa1hztc= // 根據(jù)Sec-WebSocket-Key加上特殊字符串,計算SHA-1摘要,再進行 Base64編碼協(xié)議生成(可盡量避免普通HTTP請求被誤認為WebSocket協(xié)議)
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15


5)websocket連接生命周期

6)簡單應用示例

<template>
  <div>
    <input type="text" :value="inputVal" />
    <button @click="handleSend">send</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
  
const inputVal = ref("");

const handleSend = () => {
  socket.send(inputVal.value);
};

// 創(chuàng)建WebSocket對象,并指定服務器的地址
const socket = new WebSocket("ws://82.157.123.54:9010/ajaxchattest");

// 與服務器建立連接:發(fā)送消息到服務器
socket.onopen = () => {
  console.log("connect: ");
};
// 收到服務器發(fā)送的消息:event處理服務器返回的數(shù)據(jù)
socket.onmessage = (event) => {
  console.log("receive: ", event.data);
};
// 連接或通信過程中發(fā)生錯誤
socket.onerror = (event) => {
  console.log("errror: ", event.error);
};
// 與服務器斷開連接
socket.onclose = (event) => {
  console.log("close: ", event.code);
};
</script>

六、websocket心跳機制

1、作用:使 WebSocket 連接保持長連接,避免斷開連接的情況發(fā)生。同時,心跳機制也可以檢查WebSocket連接的狀態(tài),及時處理異常情況。還可以減少WebSocket連接及服務器資源的消耗。

2、原理:是利用心跳包及時發(fā)送和接收數(shù)據(jù),保證WebSocket長連接不被斷開。

3、詳細流程

  • 客戶端建立WebSocket連接。
  • 客戶端向服務器發(fā)送心跳數(shù)據(jù)包(心跳包是指在一定時間間隔內,WebSocket發(fā)送的空數(shù)據(jù)包),服務器接收并返回一個表示接收到心跳數(shù)據(jù)包的響應。
  • 當服務器沒有及時接收到客戶端發(fā)送的心跳數(shù)據(jù)包時,服務器會發(fā)送一個關閉連接的請求。
  • 服務器定時向客戶端發(fā)送心跳數(shù)據(jù)包,客戶端接收并返回一個表示接收到心跳數(shù)據(jù)包的響應。
  • 當客戶端沒有及時接收到服務器發(fā)送的心跳數(shù)據(jù)包時,客戶端會重新連接WebSocket

4、實現(xiàn)方式

  • 使用setInterval定時發(fā)送心跳包。對服務器造成很大的壓力,因為即使WebSocket連接正常,也要定時發(fā)送心跳包,從而消耗服務器資源。
  • 在前端監(jiān)聽到WebSocket的onclose()事件時,重新創(chuàng)建WebSocket連接。減輕了服務器的負擔,但是在重連時可能會丟失一些數(shù)據(jù)。

5、WebSocket重連

重連意思就是在WebSocket斷開之后重新建立連接,這里指由于異常斷開需要重新連接。

常用實現(xiàn)方法有下:

  • 1)前端監(jiān)聽WebSocket的onclose()事件,重新創(chuàng)建WebSocket連接。
  • 2)使用WebSocket插件或庫,例如Sockjs、Stompjs等。
  • 3)使用心跳機制檢測WebSocket連接狀態(tài),自動重連。
  • 4)使用斷線重連插件或庫,例如ReconnectingWebSocket等。

6、通過WebSocket心跳機制,實現(xiàn)重連

思路: 在建立長連接的時候開啟心跳 > 通過和服務端發(fā)送信息,得到服務端給返回的信息,然后重置心跳 > 清除時間,再重新開啟心跳。(如果網(wǎng)絡斷開的話,會執(zhí)行方法,重新連接)

<template>
	<div>
		<input type="text" :value="inputVal" />
  		<button @click="handleSend">send</button>
	</div>
</template>

<script setup lang="ts">
import { ref } from "vue";

const inputVal = ref("");

let ws: any = null; // websocket實例
let isConnect: Boolean = false; // 連接標識 避免重復連接
let reciveCode: any = null; // 斷線重連后,延遲5秒重新創(chuàng)建WebSocket連接,reciveCode用來存儲延遲請求的代碼
let timeoutObj: any = null; // 延時發(fā)送消息對象(啟動心跳時新建這個對象,收到消息后重置這個對象)

// websocket重連
const reConnect = () => {
  // 如果已經(jīng)連上就不在重連了
  if (isConnect) {
    return;
  }
  clearTimeout(reciveCode);
  // 延遲5秒重連 避免過多次過頻繁請求重連
  reciveCode = setTimeout(() => {
    newWebSocket();
  }, 5000);
};

// 創(chuàng)建并初始化websocket實例
const newWebSocket = () => {
  // 判斷當前環(huán)境是否支持Websocket
  if (window.WebSocket) {
    if (!ws) {
      // 創(chuàng)建WebSocket對象,并指定服務器的地址
      ws = new WebSocket("ws://82.157.123.54:9010/ajaxchattest");
    }
    // 與服務器建立連接
    ws.onopen = () => {
      console.log("connect: ");
      isConnect = true;
      // 5分鐘發(fā)一次心跳,比server端設置的連接時間稍微小一點,在接近斷開的情況下以通信的方式去重置連接時間。
      timeoutObj = setTimeout(() => {
        if (isConnect) ws.send(inputVal.value);
      }, 300000);
    };
    // 收到服務器發(fā)送的消息
    ws.onmessage = (event: any) => {
      console.log("receive: ", event, event.data);
      clearTimeout(timeoutObj);
    };
    // 連接或通信過程中發(fā)生錯誤
    ws.onerror = (event: any) => {
      console.log("errror: ", event.error);
      isConnect = false; //連接錯誤 需要重連
      reConnect();
    };
    // 與服務器斷開連接
    ws.onclose = (event: any) => {
      console.log("close: ", event.code);
      isConnect = false;
      // 連接錯誤 需要重連
      reConnect();
    };
  } else {
    console.log("當前瀏覽器不支持websocket");
  }
};

const handleSend = () => {
  newWebSocket();
  if (ws.readyState === ws.OPEN) {
    // ws開啟狀態(tài)
    ws.send(inputVal.value);
  } else if (ws.readyState === ws.CONNECTING) {
    // 正在開啟狀態(tài),則等待1s后重新調用
    setTimeout(function () {
      handleSend();
    }, 1000);
  } else {
    // 若未開啟 ,則等待1s后重新調用
    setTimeout(function () {
      handleSend();
    }, 1000);
  }
};
</script>

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 怎樣刪除Git中緩存的用戶名和密碼

    怎樣刪除Git中緩存的用戶名和密碼

    這篇文章主要介紹了怎樣刪除Git中緩存的用戶名和密碼問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 網(wǎng)站程序員如何應對web標準

    網(wǎng)站程序員如何應對web標準

    網(wǎng)站程序員如何應對web標準...
    2007-04-04
  • HTTP協(xié)議詳解_動力節(jié)點Java學院整理

    HTTP協(xié)議詳解_動力節(jié)點Java學院整理

    這篇文章主要介紹了HTTP協(xié)議詳解,超文本傳輸協(xié)議(HTTP)是一種通信協(xié)議,它允許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器
    2017-07-07
  • GitHub倉庫權限更改方式

    GitHub倉庫權限更改方式

    文章指導如何在GitHub上設置倉庫權限,通過網(wǎng)站、CLI、API或移動端App切換公開/私有狀態(tài),并強調隱私保護需注意敏感信息檢查、定期權限審計及分支保護規(guī)則,確保代碼安全與合規(guī)
    2025-09-09
  • Windows系統(tǒng)下Git的詳細安裝步驟和基礎設置指南

    Windows系統(tǒng)下Git的詳細安裝步驟和基礎設置指南

    本文提供了Windows系統(tǒng)下Git的完整安裝配置指南,涵蓋下載安裝、驗證配置、基礎設置、環(huán)境變量配置、常用命令示例及常見問題解決方案,并推薦了常用的圖形化客戶端工具,需要的朋友可以參考下
    2026-04-04
  • tcp、udp、ip協(xié)議分析_動力節(jié)點Java學院整理

    tcp、udp、ip協(xié)議分析_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了tcp、udp、ip協(xié)議分析的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Git常用配置之遠程倉庫地址修改的四種方法

    Git常用配置之遠程倉庫地址修改的四種方法

    這篇文章主要為大家詳細介紹了Git遠程倉庫地址修改的四種方法,包括命令修改,刪除重建,配置文件修改等,下面小編就和大家詳細介紹一下吧
    2026-04-04
  • Mac如何給應用單獨設置語言

    Mac如何給應用單獨設置語言

    這篇文章主要介紹了Mac如何給應用單獨設置語言,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • 手把手教你使用Git(圖文教程)

    手把手教你使用Git(圖文教程)

    這篇文章主要介紹了手把手教你使用Git(圖文教程),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Systemd?入門實戰(zhàn)教程

    Systemd?入門實戰(zhàn)教程

    這篇文章主要介紹了Systemd?入門實戰(zhàn)教程,介紹如何使用它完成一些基本的任務,本文結合示例代碼給大家講解的非常詳細,需要的朋友可以參考下
    2022-12-12

最新評論

寿光市| 南康市| 芜湖市| 花莲市| 旬邑县| 桂东县| 贵定县| 滨州市| 沙洋县| 乌兰浩特市| 汤原县| 望都县| 凤山县| 莫力| 商南县| 霍州市| 茂名市| 永清县| 磴口县| 翼城县| 中阳县| 山丹县| 延吉市| 邻水| 宜宾市| 通辽市| 黄陵县| 桃园市| 天镇县| 明水县| 榆社县| 曲麻莱县| 大连市| 措勤县| 平武县| 福清市| 高雄县| 安达市| 宜君县| 绥滨县| 徐汇区|