日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WebSocket - 一篇文章读懂websocket

發布時間:2023/12/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WebSocket - 一篇文章读懂websocket 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一篇文章了解WebSocket

WebSocket 產生背景

在我們開發過程中使用最多的就是 HTTP協議,當我們想要獲取某些數據時由客戶端發起請求,服務端接受請求并返回相對應的數據。

但是這種單項請求方式存在一定的弊端,那就是只能由客戶端發起請求,服務端響應,服務端不能夠直接給客戶端發送數據。而在實際開發中我們往往會遇到這些情況:數據在不斷的發生變化,需要實時從服務器請求數據。例如:系統的實時運行日志、實時通信消息、系統的實時狀態等等。

如果我們繼續使用 http協議就需要定時請求,即常說的 ‘ 輪詢 ’。輪詢的效率較低,而且對于實時性并不是很友好,此時我們便需要使用到 WebSocket。

什么是WebSoket?

定義

WebSocket 是 html5 新增的一種協議,是一種網絡通信協議。WebSocket協議不是一種全新的協議,而是利用 HTTP協議來建立的一種協議。

WebSocket的連接過程

WebSocket的連接必須是客戶端發起,因為請求協議是一個標準的 http 協議,請求過程如下:

GET ws://localhost:3000/ws/chat HTTP/1.1 Host: localhost Upgrade: websocket Connection: Upgrade Origin: http://localhost:3000 Sec-WebSocket-Key: client-random-string Sec-WebSocket-Version: 13

websocket 的請求與普通的 http 的請求存在以下幾種區別點:

  • GET請求的地址不是類似/path/,而是以ws://開頭的地址;
  • 請求頭Upgrade: websocket和Connection: Upgrade表示這個連接將要被轉換為WebSocket連接;
  • Sec-WebSocket-Key是用于標識這個連接,并非用于加密數據;
  • Sec-WebSocket-Version指定了WebSocket的協議版本。

當請求成功后,服務器會返回以下響應:

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: server-random-string

服務器返回的響應中,應該注意以下幾點:

  • 響應代碼:101 表示本次連接的http協議即將被更改,更改后的協議就是 upgrade:websocket 指定的 websocket協議

此時,一個完成的 websocket 連接已經建立成功,瀏覽器和服務器可以隨時通信,發送消息。

websocket連接的特點

websocket連接最大的特點就是 服務器 可以主動向 客戶端發送消息,客戶端也可以向服務器端發送消息,是真正平等的對話。

其他的特點如下:

  • 建立在 tcp 協議之上,服務器端的實現比較容易
  • 與 http具有良好的兼容性,能夠通過各種 http 代理服務器
  • 數據格式比較輕,性能開銷小
  • 可以發送文本,也可以發送二進制數據
  • 沒有同源策略的限制,客戶端可以向任意服務器通信
  • 協議標識是 ws , 如果加密就是 wss
  • 客戶端的示例

    // 建立websocket連接 var ws = new WebSocket("wss://echo.websocket.org");// websocket建立成功之后的回調函數 ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); };// websocket接受到數據后的回調函數 ws.onmessage = function(evt) {console.log( "Received Message: " + evt.data);ws.close(); };// websocket關閉后的回調函數 ws.onclose = function(evt) {console.log("Connection closed."); };

    從 API 的角度理解websocket

    4-1 構造函數

    **WebSocket()**構造函器會返回一個 WebSocket 對象

    語法

    var ws = new WebSocket(url [, protocols]);

    示例

    var ws = new WebSocket('ws://localhost:8080');

    執行結果

    執行構造函數后,客戶端會返回一個websocket對象的實例,并且客戶端和服務器端建立連接

    4-2 屬性

    (1)binaryType

    作用

    WebSocket.binaryType 返回websocket連接所傳輸二進制數據的類型。

    語法

    var binaryType = aWebSocket.binaryType;

    返回值

    1) blob:傳輸的類型為 Blob

    2)arraybuffer:傳輸類型為 arraybuffer

    (2)bufferedAmount【只讀】

    作用

    是一個只讀屬性,用于返回當前websocket對象已經執行send方法后,還未發送到服務器的字節數。如果已經全部發送給服務器,則該值會被重置為0 , 如果連接斷開后還一直執行send方法,該值便會一直增加

    語法

    var bufferedAmount = ws.bufferedAmount;

    示例

    var data = new ArrayBuffer(10000000); ws.send(data);if (ws.bufferedAmount === 0) {// 發送完畢 } else {// 發送還沒結束 }
    (3)extensions【只讀】

    作用

    返回服務器已選擇的擴展值,目前鏈接支持的擴展值只有空字符串或者一個協議列表

    語法

    var extensions = ws.extensions;
    (4)protocol【只讀】

    作用

    返回服務器端選中的子協議的名稱,這是在創建websocket連接時,在參數中指定的字符串

    語法

    var protocol = ws.protocol;
    (5)readState【只讀】

    作用

    返回當前連接的鏈接狀態

    語法

    var readyState = ws.readyState;

    返回值

    • CONNECTING:值為0,表示正在連接。
    • OPEN:值為1,表示連接成功,可以通信了。
    • CLOSING:值為2,表示連接正在關閉。
    • CLOSED:值為3,表示連接已經關閉,或者打開連接失敗。
    (6)onopen

    作用

    創建連接成功后的回調函數

    語法

    ws.onopen = function(event) {console.log("WebSocket is open now."); };

    說明

    如果一個實例對象想要創建多個open的回調事件,可使用 addEventListen綁定事件

    ws.addEventListen('open' , funciton(event){console.log("創建監聽事件"); })
    (7)onclose

    作用

    連接關閉后的回調函數

    語法

    ws.onclose = function(event) {var code = event.code;var reason = event.reason;var wasClean = event.wasClean;// handle close event };ws.addEventListener("close", function(event) {var code = event.code;var reason = event.reason;var wasClean = event.wasClean;// handle close event });
    (8)onmessage

    作用

    連接接收到數據之后的回調函數

    語法

    ws.onmessage = function(event) {console.debug("WebSocket message received:", event.data); };
    (9)onerror

    作用

    連接發生錯誤之后的回調函數

    語法

    ws.onerror = function(event) {console.error("WebSocket error observed:", event); };
    (10)url【只讀】

    作用

    返回創建連接時url的絕對路徑

    4-3 方法

    (1)close()

    作用

    關閉 websocket 連接或連接嘗試,如果websocket連接已經關閉,該方法沒有任何作用

    語法

    WebSocket.close();
    (2)send()

    作用

    send方法將需要通過 WebSocket 鏈接傳輸至服務器的數據排入隊列

    語法

    WebSocket.send("Hello server!");

    可傳輸的數據類型

    • 字符串
    • ArrayBuffer
    • Blob
    • ArrayBufferView

    從 實例 角度理解websocket - 發送消息通信

    5-1 準備dom元素
    <div id="box"><div class="messageWrap"><input class="form-control urlInput" id="url" type="text" placeholder='請輸入連接地址'><button class="btn btn-primary" id="open" onclick="openWS()">連接</button><button class="btn btn-danger" onclick="closeWS()">關閉</button><textarea placeholder="請輸入發送的數據" class="form-control msg" name="" id="message" cols="30" rows="10"></textarea><button id="send" class="form-control btn btn-success" onclick="sendMessage()">發送</button></div><div class="resultWrap"></div> </div>
    5-2 創建websocket對象
    let myWebsocket = {ws: null ,init(url , event){// 判斷瀏覽器是否支持wsif ('WebSocket' in window){this.ws = new WebSocket( url );this.listenerEvent( event ) ;this.listenClose();}else {alert("當前瀏覽器不支持 websocket 通信");}},listenerEvent(event) {this.ws.onopen = function (e) {event.open(e);};this.ws.onmessage = function (e) {event.message(e);};this.ws.onclose = function (e) {event.close(e);};this.ws.onerror = function (e) {event.error(e);}},listenClose(){window.onbeforeunload = function () {this.ws.close();}window.onbeforeload = function () {this.ws.close();}} };
    5-3 使用websocket對象
    // 事件配置 function open( event ){let a = `<p class="alert alert-success">已經成功建立連接啦,可以發送數據呦!</p>`;$(".resultWrap").append(a); } function close( event ){let a = `<p class="alert alert-secondary ">已關閉連接</p>`;$(".resultWrap").append(a); } function error( event ){let a = `<p class="alert alert-danger ">連接失敗</p>`;$(".resultWrap").append(a); } function message( event ){let data = event.data;let a = `<b>從服務器接收到的數據:</b>`+data;$(".resultWrap").append(a);} // 創建連接 function openWS(){myWebsocket.init($("#url").val(),{ open:open , close:close , error:error , message:message }) }// 關閉連接 function closeWS() {myWebsocket.ws.close(); }// 發送數據 function sendMessage(){myWebsocket.ws.send(document.querySelector("#message").value)let a = `<b style="color: #1e7e34">你向服務端發送:</b>`+ document.querySelector("#message").value;$(".resultWrap").append(a);$("#message").val(""); }
    5-4 運行效果

    高級版 - websocket 心跳機制

    使用背景

    如果在連接后需要長時間保持連接,但又不是一直都在通信,可以在連接中添加心跳機制,每隔一段時間就從客戶端發送一個數據給后臺,后臺再返回一個數據給客戶端保持通信。

    6-1 準備元素

    同 5-1

    6-2 創建含有心跳機制的websocket對象
    // 心跳機制 let heartCheck = {timeout:600000,timeoutObj:null,serverTimeoutObj:null,reset(){clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);return this;},start: function(){let self = this;this.timeoutObj = setTimeout(function(){myWebsocket.ws.send("ping");let a = `<b style="color: #1e7e34">檢測心跳:ping</b>`;$(".resultWrap").append(a);self.serverTimeoutObj = setTimeout(function(){· myWebsocket.ws.close();}, self.timeout)}, this.timeout)} } // 含有心跳的websocket對象 let myWebsocket = {ws: null ,url:"",event: null ,init(url , event){try{if('WebSocket' in window){this.ws = new WebSocket( url );let a = `<b style="color: #1e7e34">再次連接</b>`;$(".resultWrap").append(a);this.url = url ;this.event = event;this.listenerEvent( event ) ;this.listenClose();}else{alert("您的瀏覽器不支持websocket協議,建議使用新版谷歌、火狐等瀏覽器,請勿使用IE10以下瀏覽器,360瀏覽器請使用極速模式,不要使用兼容模式!");}}catch(e){this.reconnect(url);console.log(e);}},listenerEvent(event) {let $this = this;$this.ws.onopen = function (e) {heartCheck.reset();heartCheck.start();event.open(e);};$this.ws.onmessage = function (e) {heartCheck.reset();heartCheck.start();event.message(e);};$this.ws.onclose = function (e) {event.close(e);$this.reconnect();};$this.ws.onerror = function (e) {$this.reconnect( $this.url );event.error(e);}},listenClose(){window.onbeforeunload = function () {this.ws.close();};window.onbeforeload = function () {this.ws.close();}},reconnect(){let $this = this;setTimeout(function () {$this.init($this.url , $this.event);}, 3000);}, };
    6-3 使用

    同 5-3

    參考鏈接

    • 【廖雪峰官方網站】https://www.liaoxuefeng.com/wiki/1022910821149312/1103332447876608
    • 【阮一峰教程】http://www.ruanyifeng.com/blog/2017/05/websocket.html
    • 【MDN API】https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
    • https://www.cnblogs.com/fuqiang88/p/5956363.html

    代碼演示

    代碼下載演示:https://github.com/jianyaoo/js/tree/master/websoket

    總結

    以上是生活随笔為你收集整理的WebSocket - 一篇文章读懂websocket的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。