Nodejs教程19:WebSocket之一:使用Socket.io建立WebSocket應用

LeeChen發表於2019-03-11

閱讀更多系列文章請訪問我的GitHub部落格,示例程式碼請訪問這裡

WebSocket的優勢

  1. 效能高。

    根據測試環境資料的不同,大約會比普通Ajax請求高2-10倍。 HTTP是文字協議,資料量比較大。

    而WebSocket是基於二進位制的協議,在建立連線時用的雖然是文字資料,但之後傳輸的都是二進位制資料,因此效能比Ajax請求高。

  2. 雙向通訊。

    如果是普通Ajax請求,需要實時獲取資料,只能用計時器定時傳送請求,這樣會浪費伺服器資源和流量。

    而通過WebSocket,伺服器可以主動向前端傳送資訊。

  3. 安全性高

    由於WebSocket出現較晚,相比HTTP協議,在安全性上考慮的更加充分。

接下來,嘗試用Socket.io建立一個基於WebSocket的雙向通訊。

Socket.io

Socket.io是在使用WebSocket時的一個常用庫,它會自動判斷在支援WebSocket的瀏覽器中使用WebSocket,在其他瀏覽器中,會使用如flash等方式完成通訊。

  1. 操作簡單
  2. 相容低端瀏覽器,如IE6
  3. 自動進行資料解析
  4. 自動重連 若出現連線斷開的情況,WebSocket會進行自動重連。

使用Socket.io建立一個WebSocket應用

服務端示例程式碼:/lesson19/server.js

const http = require('http')
const io = require('socket.io')

// 1. 建立HTTP伺服器。
const server = http.createServer((req, res) => {

})

server.listen(8080)

// 2. 建立WebSocket,讓socket.io監聽HTTP伺服器,一旦發現是WebSocket請求,則會自動進行處理。
const ws = io.listen(server)

// 建立連線完成後,觸發connection事件。
// 該事件會返回一個socket物件(https://socket.io/docs/server-api/#Socket),可以利用socket物件進行傳送、接收資料操作。
ws.on('connection', (socket) => {
  // 根據事件名,向客戶端傳送資料,資料數量不限。
  socket.emit('msg', '服務端向客戶端傳送資料第一條', '服務端向客戶端傳送資料第二條')

  // 根據事件名接收客戶端返回的資料
  socket.on('msg', (...msgs) => {
    console.log(msgs)
  })

  // 使用計時器向客戶端傳送資料
  setInterval(() => {
    socket.emit('timer', new Date().getTime())
  }, 500);
})
複製程式碼

客戶端示例程式碼:/lesson19/index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <!-- 引用Socket.io的客戶端js檔案,由於Socket.io已在服務端監聽了HTTP伺服器的請求,一旦收到對該檔案的請求,則會自動返回該檔案,不需要開發人員配置。 -->
  <!-- 該檔案在服務端的位置為/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js -->
  <script src="http://localhost:8080/socket.io/socket.io.js"></script>
  <script>
    // 與伺服器建立WebSocket連線,該連線為ws協議,socket.io不需要擔心跨域問題。
    const socket = io.connect('ws://localhost:8080/')

    // 根據事件名,向服務端傳送資料,資料數量不限。
    socket.emit('msg', '客戶端向服務端傳送資料第一條', '客戶端向服務端傳送資料第二條')

    // 根據事件名接收服務端返回的資料
    socket.on('msg', (...msgs) => {
      console.log(msgs)
    })

    // 接收服務端通過計時器傳送來的資料
    socket.on('timer', (time) => {
      console.log(time)
    })
  </script>
</body>

</html>
複製程式碼

用瀏覽器開啟index.html,即可在控制檯看到列印的訊息。

相關文章