前端Websocket的使用

前段時間因工做業務須要,簡單瞭解了一下Websocket的概念和前端的使用。總結以下:html

概念:

Websocket是一種協議,經過客戶端和服務器之間的長久的TCP通訊,使客戶端和服務器之間能夠隨時交換數據。前端

使用場景:

因爲http協議只能由客戶端發起通訊,若是服務器有連續的狀態變化,客戶端要獲知就很是麻煩。咱們只能使用"輪詢":每隔一段時候,就發出一個詢問,瞭解服務器有沒有新的信息。最典型的場景就是聊天室。Websocket在解決這樣的需求上很是方便。web

說明:

  • 創建在 TCP 協議之上
  • 與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器
  • 數據格式比較輕量,性能開銷小,通訊高效
  • 能夠發送文本,也能夠發送二進制數據
  • 沒有同源限制,客戶端能夠與任意服務器通訊
  • 協議標識符是ws(若是加密,則爲wss),服務器網址就是 URL。

API介紹:

  • WebSocket構造函數: 新建WebSocket實例後,會建立客戶端與服務端的WebSocket鏈接
    let ws = new WebSocket(url)
  • WebSocket實例的當前狀態:
ws.readyState // 0: 'CONNECTING',表示正在鏈接
                  // 1: 'OPEN', 表示鏈接成功,能夠通訊了
                  // 2: 'CLOSING', 表示鏈接正在關閉
                  // 3: 'CLOSED', 表示鏈接已經關閉,或者打開鏈接失敗。
  • WebSocket實例的事件:
ws.onopen = function () {} // 指定鏈接成功後的回調函數
    ws.onclose = function () {} // 指定鏈接關閉後的回調函數
    ws.onmessage = function () {} // 指定收到服務器數據後的回調函數
    ws.onerror = function () {} // 指定報錯時的回調函數
  • WebSocket實例向後臺推送消息的方法:
    ws.send(message)

WebSocket應用實例

/* WebSocket封裝
 * @param url: WebSocket接口地址與攜帶參數必填
 * @param onOpenFunc: WebSocket的onopen回調函數,若是不須要可傳null
 * @param onMessageFunc: WebSocket的onmessage回調函數,若是不須要可傳null
 * @param onCloseFunc: WebSocket的onclose回調函數,若是不須要可傳null
 * @param onErrorFunc: WebSocket的onerror回調函數,若是不須要可傳null
 * @param heartMessage: 發送後臺的心跳包參數,必填 (給服務端的心跳包就是按期給服務端發送消息)
 * @param timer: 給後臺傳送心跳包的間隔時間,不傳時使用默認值3000毫秒
 * @param isReconnect: 是否斷掉當即重連,不傳true時不重連
*/
function useWebSocket (url, onOpenFunc, onMessageFunc, onCloseFunc, onErrorFunc, heartMessage, timer, isReconnect) {
  let isConnected = false // 設定已連接webSocket標記
  // websocket對象
  let ws = null
  // 建立並連接webSocket
  let connect = () => {
    // 若是未連接webSocket,則建立一個新的webSocket
    if (!isConnected) {
      ws = new WebSocket(url)
      isConnected = true
    }
  }
  // 向後臺發送心跳消息
  let heartCheck = () => {
    ws.send(JSON.stringify(heartMessage))
  }
  // 初始化事件回調函數
  let initEventHandle = () => {
    ws.addEventListener('open', (e) => {
      console.log('onopen', e)
      // 給後臺發心跳請求,在onmessage中取得消息則說明連接正常
      heartCheck()
      // 若是傳入了函數,執行onOpenFunc
      if (!onOpenFunc) {
        return false
      } else {
        onOpenFunc(e)
      }
    })
    ws.addEventListener('message', (e) => {
      console.log('onmessage', e)
      // 接收到任何後臺消息都說明當前鏈接是正常的
      if (!e) {
        console.log('get nothing from service')
        return false
      } else {
        // 若是獲取到後臺消息,則timer毫秒後再次發起心跳請求給後臺,檢測是否斷連
        setTimeout(() => {
          heartCheck()
        }, !timer ? 3000 : timer)
      }
      // 若是傳入了函數,執行onMessageFunc
      if (!onMessageFunc) {
        return false
      } else {
        onMessageFunc(e)
      }
    })
    ws.addEventListener('close', (e) => {
      console.log('onclose', e)
      // 若是傳入了函數,執行onCloseFunc
      if (!onCloseFunc) {
        return false
      } else {
        onCloseFunc(e)
      }
      if (isReconnect) { // 若是斷開當即重連標誌爲true
        // 從新連接webSocket
        connect()
      }
    })
    ws.addEventListener('error', (e) => {
      console.log('onerror', e)
      // 若是傳入了函數,執行onErrorFunc
      if (!onErrorFunc) {
        return false
      } else {
        onErrorFunc(e)
      }
      if (isReconnect) { // 若是斷開當即重連標誌爲true
        // 從新連接webSocket
        connect()
      }
    })
  }
  // 初始化webSocket
  (() => {
    // 1.建立並連接webSocket
    connect()
    // 2.初始化事件回調函數
    initEventHandle()
    // 3.返回是否已鏈接
    return ws
  })()
}

// WebSocket函數使用實例
useWebSocket( url, // url
              null, // onopen回調
              (e) => { // onmessage回調
                let res = JSON.parse(e.data) // 後端返回的數據
                console.log(res)
              },
              null, // onclose回調
              null, // onerror回調
              { // 心跳包消息
                "action": "9999",
                "eventType": "100",
                "requestId": ""
              },
              null, // 傳送心跳包的間隔時間
              true // 斷掉當即重連
)
參考地址: http://www.ruanyifeng.com/blo...
相關文章
相關標籤/搜索