前端培訓-中級階段(25)-Web Socket 網絡編程(2019-11-14期)

前端最基礎的就是 HTML+CSS+Javascript。掌握了這三門技術就算入門,但也僅僅是入門,現在前端開發的定義已經遠遠不止這些。前端小課堂(HTML/CSS/JS),本着提升技術水平,打牢基礎知識的中心思想,我們開課啦(每週四)。

這塊內容是我早就想下手的,但是因爲之前服務沒跑起來。所以文章沒寫成。今天經過一下午,終於鼓搗好了demo地址

websocket

webSocket 可以幫助瀏覽器服務器完成雙向通信
在 webSocket 出現之前,我們想接收到服務端的數據需要使用一些特殊手段,比如 輪詢長連接

構造函數

var protocol = 'wss'
if(location.protocol == "http:") protocol = 'ws'
ws = new WebSocket(protocol+"://ws.lilnong.top");

WebSocket(url[, protocols]) 傳入 webScoket服務的URL,即可建立連接。

屬性與方法

名稱 類型 描述
url 屬性 當前連接的絕對路徑
protocol 屬性 下屬協議,對應構造函數第二個參數
readyState 屬性 當前的鏈接狀態
bufferedAmount 屬性 當前連接的絕對路徑
binaryType 屬性 數據類型:blob
close() 方法 關閉當前鏈接
send() 方法 發送數據到服務端

readyState 狀態碼

常量 數值 描述
WebSocket.CONNECTING 0 正在連接中
WebSocket.OPEN 1 已經連接並且可以雙向通訊
WebSocket.CLOSING 2 正在關閉中
WebSocket.CLOSED 3 已關閉或者沒有連接成功

WebSocket.send() 方法

WebSocket.send(String | ArrayBuffer | Blob | ArrayBufferView);

var protocol = 'wss'
if(location.protocol == "http:") protocol = 'ws'
wsTest = new WebSocket(protocol+"://ws.lilnong.top");
wsTest.onclose = ()=>console.log('onclose');
wsTest.onerror = ()=>console.log('onerror');
wsTest.onmessage = ()=>console.log('onmessage');
wsTest.onopen = ()=>console.log('onopen')

var blob = new Blob(['lilnong.top','水的一批'])
filereader = new FileReader()
filereader.readAsArrayBuffer(blob);
filereader.onload = function(){
    wsTest.send(filereader.result)
    wsTest.send(new Int8Array(filereader.result))
}
wsTest.send(blob)
wsTest.send('lilnong.top水的一批1')

可以看到blob其實是發送失敗了。一般來說我們還是發送String居多。
image.png

WebSocket.close() 方法

WebSocket.close([code] [, reason]);

  1. code 表示錯誤碼。默認爲1005CloseEvent
  2. reason 爲錯誤碼的描述。

回調函數

函數名稱 觸發時機 備註
onclose 當連接關閉後的回調函數 主動close或者被動close都會觸發
onerror 當連接失敗後的回調函數 只有被動close會觸發
onmessage 當接收到服務端發送數據時的回調函數 e.data爲服務端返回的信息
onopen 當連接成功後的回調函數 之後就可以進行交互了

實現

node

依賴ws = require('ws');這個 websocket 模塊。
我們可以把connection 中的連接對象保存到全局的數組。這樣我們就可以廣播消息了。
close把連接對象移出數組。

var ws = require('ws');
var socketServer = ws.Server;
var wss = new socketServer({port: 8090});//創建服務,監聽8090端口
// 監聽連接
wss.on('connection', function(ws){
    // 推送消息
    ws.send(JSON.stringify({type: 'start',time: Date.now()}))
    // 接收瀏覽器端發送的消息
    ws.on('message',function(message){
        console.log(JSON.parse(message))
    })
    // 監聽連接斷開
    ws.on('close', function() {})
})

html

var initWs = function initWs(){
    var protocol = 'wss'
    if(location.protocol == "http:") protocol = 'ws'
    ws = new WebSocket(protocol+"://ws.lilnong.top");
    ws.onopen = function (e) {console.log('連接成功');}
    //收到消息處理
    ws.onmessage = function (e) {
        console.log(e.data)
    }
    //監聽連接關閉情況
    ws.onclose = function (e) {
        setTimeout(v=>initWs(), 2000);//自動重連
        console.log('連接關閉');
    }
}
initWs();
setInterval(v=>{ws.send(JSON.stringify({type: 'ping'}));}, 10 * 1000);// 保持心跳

總結

  1. socket 需要保存心跳,一般是 ping、pong 邏輯。
  2. 超時時間是可以人爲設置的,所以心跳時間也是可以選擇的。(我的是20s,所以心跳是10s。公司之前做的5m)。
  3. socket 如果斷線要注意重連。因爲都會落到close裏面,所以我們可以直接在close裏面重連。

    1. 部分情況要注意重連頻率、以及重連次數的策略。
  4. 發送和接受只能是字符串,所以要JSON.stringify()

微信公衆號:前端linong

clipboard.png

參考文獻

  1. 前端培訓目錄、前端培訓規劃、前端培訓計劃
  2. WebSockets
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章