WebSocket 網絡通訊協議介紹

1、WebSocket是什麼?

WebSocket 是一種網絡通訊協議。RFC6455定義了它的通訊標準。javascript

WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。html

2、爲何須要WebSocket?

咱們知道,傳統的HTTP協議是無狀態的,每次請求(request)都要由客戶端(如 瀏覽器)主動發起,服務端進行處理後返回response結果,而服務端很難主動向客戶端發送數據;這種客戶端是主動方,服務端是被動方的傳統Web模式 對於信息變化不頻繁的Web應用來講形成的麻煩較小,而對於涉及實時信息的Web應用卻帶來了很大的不便。vue

  所以,隨着HTML5的誕生,一種新的通訊協議應運而生---WebSocket,他最大的特色就是服務端能夠主動向客戶端推送消息,客戶端也能夠主動向服務端發送消息,實現了真正的平等。java

舉個例子:如帶有即時通訊、實時數據、訂閱推送等功能的應用。在WebSocket規範提出以前,開發人員若要實現這些實時性較強的功能,常常會使用折衷的解決方法:ajax輪詢(最原始的實現實時Web應用的解決方案)web

ajax輪詢的原理:ajax輪詢的原理很是簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。明顯地,這種方法會致使過多沒必要要的請求,浪費流量和服務器資源。
場景再現:
客戶端:有沒有新信息(Request)
服務端:沒有(Response)
客戶端:有沒有新信息(Request)
服務端:沒有。。(Response)
客戶端:有沒有新信息(Request)
服務端:你好煩啊,沒有啊。。(Response)
客戶端:有沒有新消息(Request)
服務端:有啦,給你。(Response)
客戶端:有沒有新消息(Request)
服務端:。。。。。沒。。。。沒。。。沒有(Response) ---- loopajax

websocket的原理:當服務器完成協議升級後(HTTP->Websocket),服務端就能夠主動推送信息給客戶端啦。
場景再現:
客戶端:我要創建Websocket協議,須要的服務:chat,Websocket協議版本:17(HTTP Request)
服務端:確認,已升級爲Websocket協議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務端:好的,有的時候會告訴你的。
服務端:balabalabalabala
服務端:哈哈哈哈哈啊哈哈哈哈
服務端:笑死我了哈哈哈哈哈哈哈瀏覽器

3、WebSocket其餘特色以下:

(1)創建在 TCP 協議之上,服務器端的實現比較容易。服務器

(2)與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器。websocket

(3)數據格式比較輕量,性能開銷小,通訊高效。網絡

(4)能夠發送文本,也能夠發送二進制數據。

(5)沒有同源限制,客戶端能夠與任意服務器通訊。

(6)協議標識符是ws(若是加密,則爲wss),服務器網址就是 URL。

4、建立WebSocket對象

瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。當你獲取 WebSocket 鏈接後,你能夠經過 send() 方法來向服務器發送數據,並經過 onmessage 事件來接收服務器返回的數據。

// url, 指定鏈接的 URL
// protocol 是可選的,指定可接受的子協議。
let Socket = new WebSocket(url, [protocol] );
複製代碼

5、WebSocket屬性

假設咱們建立了一個Socket對象

屬性 描述
Socket.readyState

只讀屬性 readyState 表示鏈接狀態,能夠是如下值:

0 - 表示鏈接還沒有創建。

1 - 表示鏈接已創建,能夠進行通訊。

2 - 表示鏈接正在進行關閉。

3 - 表示鏈接已經關閉或者鏈接不能打開。

Socket.bufferedAmount 只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數。

6、WebSocket事件

假設咱們建立了一個Socket對象

事件 事件處理程序 描述
open Socket.onopen 鏈接創建時觸發
message Socket.onmessage 客戶端接收服務端數據時觸發
error Socket.onerror 通訊發生錯誤時觸發
close Socket.onclose 鏈接關閉時觸發

7、WebSocket方法

假設咱們建立了一個Socket對象

方法 描述
Socket.send()

使用鏈接發送數據

Socket.close()

關閉鏈接

8、WebSocket實例

【1】原生JavaScript實現WebSocket鏈接

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <style> </style> <body> <input id="text" type="text" /> <button onclick="send()">發送消息</button> <button onclick="closeWebSocket()">關閉WebSocket鏈接</button> <div id="message"></div> <script> let websocket = null; //判斷當前瀏覽器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:8080/websocket"); } else { alert('當前瀏覽器不支持websocket!') } //鏈接發生錯誤的回調方法 websocket.onerror = function () { console.log("WebSocket鏈接發生錯誤"); }; //鏈接成功創建的回調方法 websocket.onopen = function () { console.log("WebSocket鏈接成功"); } //接收到消息的回調方法 websocket.onmessage = function (event) { document.getElementById('message').innerHTML += event.data + '<br/>'; } //鏈接關閉的回調方法 websocket.onclose = function () { console.log("WebSocket鏈接關閉"); } //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。 window.onbeforeunload = function () { closeWebSocket(); } //關閉WebSocket鏈接 function closeWebSocket() { websocket.close(); } //發送消息 function send() { let message = document.getElementById('text').value; websocket.send(message); } </script> </body> </html>複製代碼

【2】在vue項目中實現WebSocket鏈接

<template> <div> <el-input v-model="params" clearable/> <el-button type="primary" @click="send">發消息</el-button> </div> </template> <script> export default { data() { return { params: '', path: "ws://localhost:8080/websocket", socket: "" } }, mounted() { // 初始化 this.init() }, destroyed() { // 銷燬監聽 this.socket.onclose = this.close }, methods: { init: function () { if (typeof (WebSocket) === "undefined") { console.log("您的瀏覽器不支持socket") } else { // 實例化socket this.socket = new WebSocket(this.path) // 監聽socket鏈接成功回調 this.socket.onopen = this.open // 監聽socket鏈接失敗回調 this.socket.onerror = this.error // 監聽後臺返回的socket消息 this.socket.onmessage = this.getMessage } }, open: function () { console.log("socket鏈接成功") }, error: function () { console.log("鏈接錯誤") }, getMessage: function (msg) { console.log(msg.data) }, send: function () { this.socket.send(params) }, close: function () { console.log("socket已經關閉") } } } </script>複製代碼
相關文章
相關標籤/搜索