一、簡介:
websocket 建立網路長連結,最開始存在的意義就是為了解決我們使用 '輪詢' 的方式進行網路請求,輪詢的效率很低並且浪費網路資源,一般使用定時器來實現,而 websocket 的出現就解決了這個問題。它實現了伺服器端直接向客戶端推送訊息,並且客戶端也可以直接向服務端傳送訊息,這是一個真正的雙向平等對話。最典型的例子就是聊天室。
二、客戶端的簡單實現方法:
1.例項化一個 ws 物件 ,即:
var ws = new WebSocket(' url ');
複製程式碼
2.簡單的步驟:
①連結開啟的事件監聽:
ws.onopen = function(event) {
console.log("Connection open ...");
ws.send("Hello WebSockets!"); // 向伺服器傳送資料
};
複製程式碼
②監聽訊息事件,當有訊息到達就會直接觸發:
ws.onmessage = function(event) {
console.log( "Received Message: " + evt.data);
ws.close(); // 關閉請求
};
複製程式碼
③監聽關閉事件,當使用close 時觸發:
ws.onclose = function(event) {
console.log("Connection closed.");
};
複製程式碼
④錯誤監聽:
ws.onerror = function( err ){
console.error(err)
}
複製程式碼
此處注意事項:
使用 onmessage 接受訊息的時候,我們可以指定資料型別,伺服器的資料可能是文字,也可能是二進位制資料, 以上就是一個最基本的客戶端的 websocket 實現;
三、WebSocket.readyState 例項物件的當前狀態:
通過 switch 可以直接檢視;
switch (ws.readyState){
case WebSocket.CONNECTING:
console.log('值為0,表示正在建立連結');
break;
case WebSocket.OPEN:
console.log('值為1,表示連線成功,可以通訊');
break;
case WebSocket.CLOSING:
console.log('值為0,表示正在關閉連結');
break;
case WebSocket.CLOSED:
console.log('值為0,表示連線已經關閉或者開啟連線失敗');
break;
default:
break;
}
複製程式碼
四、日常程式碼開發封裝:
在平時我們寫程式碼的時候,可以通過封裝一個類來實現 socket 長連結,具體程式碼如下:
class SocketManager {
_socketMsgQueue = [];
_isOpen = false;
_messageCbs = [];
constructor(url) {
if(!url) {
console.error('SocketManager: url is required');
return;
}
this._url = url;
this._init();
// 判斷是否有url 的存在,如果沒有就return,否則執行init () 方法;
}
_init() {
// 建立WebSocket 連結:
this._socketInstance = new WebSocket(this._url);
// 開啟連結併傳送資料:
this._socketInstance.onopen = () => {
this._isOpen = true;
for (let i = 0; i < this._socketMsgQueue.length; i += 1) {
this.sendMessage(this._socketMsgQueue[i]);
}
this._socketMsgQueue.length = 0;
};
this._socketInstance.onmessage = (e) => {
for (let i = 0; i < this._messageCbs.length; i += 1) {
this._messageCbs[i](e.data);
}
};
this._socketInstance.onclose = () => {
this.destroy();
this._init();
};
}
//呼叫的回撥,這個地方比較繞,我想了大半天!!!和上述的onmessage 時間相對應
的。我們呼叫的時候,將一個函式出入,所以此時陣列中儲存的多個函式!!!所以在
onmessage 中,我們拿到的e.data 就是資料使用for 迴圈,呼叫每一個函式!!!
registerMessage(cb) {
if (typeof cb === 'function') {
this._messageCbs.push(cb);
}
}
// 傳送資料,可通過this._isOpen 來判斷是否開啟了長連結;
sendMessage(msg) {
if (this._isOpen) {
this._socketInstance.send(msg);
} else {
this._socketMsgQueue.push(msg);
}
}
// 銷燬此次長連結
destroy() {
this._socketInstance.close();
this._socketInstance.onmessage = null;
this._socketInstance.onopen = null;
this._socketInstance.onclose = null;
delete this._socketInstance;
}
}
export default SocketManager;
複製程式碼
五、封裝物件的呼叫:
1.首先引入我們封裝物件的檔案;import ....
2.由於我們封裝的時候是將這個物件暴露出去的,所以在引入之後,直接new 這個物件即可:
const socketMng = new SocketManager(xcxSocketUrl);
複製程式碼
注意:這個地方的 url 是必須傳入的,在物件中也做了一個判斷!
3.執行方法:
socketMng.sendMessage('這是資料!!!');
socketMng.registerMessage((msg)=>{
if(...){
// 執行相應的操作!
}
})
複製程式碼
注意:此時的這個箭頭函式,就是我們在registerMessage ()中傳入的值,即cb;
以上就是最近寫 WebSocket 所學習到的所有知識了,希望對大家有所幫助!!!不喜勿碰....