介紹
WebSocket
用於在Web瀏覽器和服務器之間進行任意的雙向數據傳輸的一種技術。WebSocket
協議基於TCP
協議實現,包含初始的握手過程,以及后續的多次數據幀雙向傳輸過程。其目的是在WebSocket
應用和WebSocket
服務器進行頻繁雙向通信時,可以使服務器避免打開多個HTTP
連接進行工作來節約資源,提高了工作效率和資源利用率。
API介紹
- 構造函數
WebSocket(url, protocols)
:構造WebSocket
對象,以及建立和服務器連接;protocols
可選字段,代表選擇的子協議 - 狀態變量
readyState
: 代表當前連接的狀態,短整型數據,取值為CONNECTING
(值為0),OPEN
(值為1),CLOSING
(值為2),CLOSED
(值為3) - 方法變量
close(code, reason)
: 關閉此WebSocket
連接。 - 狀態變量
bufferedAmount: send
函數調用后,被緩存並且未發送到網絡上的數據長度 - 方法變量
send(data)
: 將數據data通過此WebSocket
發送到對端 - 回調函數
onopen/onmessage/onerror/onclose
: 當相應的事件發生時會觸發此回調函數
代碼
這里采用封裝的思想 WBT
1 var WBT = function (obj) { 2 /* 3 websocket接口地址 4 1、http請求還是https請求 前綴不一樣 5 2、ip地址host 6 3、端口號 7 */ 8 const config = obj ? obj : {} 9 const protocol = (window.location.protocol == 'http:') ? 'ws://' : 'wss://'; 10 const host = window.location.host; 11 const port = ':8087'; 12 //接口地址url 13 this.url = config.ip || protocol + host + port; 14 //socket對象 15 this.socket; 16 //心跳狀態 為false時不能執行操作 等待重連 17 this.isHeartflag = false; 18 //重連狀態 避免不間斷的重連操作 19 this.isReconnect = false; 20 //自定義Ws連接函數:服務器連接成功 21 this.onopen = ((e) => { 22 this.isHeartflag = true; 23 console.log(e) 24 }) 25 //自定義Ws消息接收函數:服務器向前端推送消息時觸發 26 this.onmessage = ((e) => { 27 //處理各種推送消息 28 // console.log(message) 29 this.handleEvent(message) 30 }) 31 //自定義Ws異常事件:Ws報錯后觸發 32 this.onerror = ((e) => { 33 console.log('error') 34 this.isHeartflag = false; 35 this.reConnect(); 36 }) 37 //自定義Ws關閉事件:Ws連接關閉后觸發 38 this.onclose = ((e) => { 39 this.reConnect() 40 console.log('close') 41 }) 42 //初始化websocket連接 43 this.initWs() 44 }
初始化 initWs
1 //初始化websocket連接 2 WBT.prototype.initWs = function () { 3 window.WebSocket = window.WebSocket || window.MozWebSocket; 4 if (!window.WebSocket) { // 檢測瀏覽器支持 5 console.error('錯誤: 瀏覽器不支持websocket'); 6 return; 7 } 8 var that = this; 9 this.socket = new WebSocket(this.url); // 創建連接並注冊響應函數 10 this.socket.onopen = function (e) { 11 that.onopen(e); 12 }; 13 this.socket.onmessage = function (e) { 14 that.onmessage(e); 15 }; 16 this.socket.onclose = function (e) { 17 that.onclose(e); 18 that.socket = null; // 清理 19 }; 20 this.socket.onerror = function (e) { 21 that.onerror(e); 22 } 23 return this; 24 }
斷線重連 reConnect
1 WBT.prototype.reConnect = function () { 2 if (this.isReconnect) return; 3 this.isReconnect = true; 4 //沒連接上會一直重連,設置延遲避免請求過多 5 setTimeout(function () { 6 this.initWs() 7 this.isReconnect = false; 8 }, 2000); 9 }
處理消息 handle
1 //處理消息 2 WBT.prototype.handleEvent = function (message) { 3 const action = message.action; 4 const retCode = message.params.retCode.id; 5 //根據action和retCode處理事件 6 // console.log(action,retCode) 7 if (this.handleAction[action][retCode]) this.handleAction[action][retCode](); 8 } 9 //事務處理 根據action 10 WBT.prototype.handleAction = { 11 //登錄反饋 12 'loginRsp': { 13 '0': function () { 14 console.log(0) 15 }, 16 '3': function () { 17 console.log(3) 18 } 19 } 20 }
發送消息-登錄login
1 let defaultParam = { 2 action: "loginReq", 3 tsxId: "1", 4 params:{} 5 } 6 WBT.prototype.login = function (params) { 7 //ws還沒建立連接(發生錯誤) 8 if (!this.isHeartflag) { 9 console.log('連接中……') 10 return; 11 } 12 let loginParam = defaultParam; 13 loginParam.params = params; 14 //組裝json數據 15 this.socket.send(JSON.stringify(loginParam)) 16 }
使用 index.html
1 var WS = new WBT() 2 var b = { 3 dc: { 4 id: "admin", 5 passwd: "21232f297a57a5a743894a0e4a801fc3", 6 version: "UDT-0.3.0" 7 } 8 } 9 //發送消息 10 WS.login(b)