後端設置 WebSocket 連接處理

針對更新共享購物車商品數量、刪除共享購物車中的商品

處理 WebSocket 的連接處理

這邊要處理當後端接收到 "更新共享購物車商品數量"、"刪除共享購物車商品" 時的行為。

前面有 new 一個 WebSocketServer 裡取用 server 方法的實例,並命名稱 wss,所以這邊用 wss.on 方法來設定情境:

wss.on("connection", (ws) => {
  console.log("新的 WebSocket 連接")
  clients.add(ws)

  ws.on("message", async (message) => {
    try {
      const parsedMessage = JSON.parse(message)
      console.log("收到消息:", parsedMessage)

      switch (parsedMessage.type) {
        case "cartUpdate":
          clients.forEach((client) => {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
              client.send(
                JSON.stringify({
                  type: "cartUpdate",
                  data: parsedMessage.data,
                })
              )
            }
          })
          break

        case "cartDelete":
          clients.forEach((client) => {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
              client.send(
                JSON.stringify({
                  type: "cartDelete",
                  data: parsedMessage.data,
                })
              )
            }
          })
          break
      }
    } catch (error) {
      console.error("處理消息時出錯:", error)
    }
  })

  ws.on("close", () => {
    console.log("連接關閉")
    clients.delete(ws)
  })
})

這邊可以看到有用一個 client 方法,這是在上面有進行定義,用於存儲所有 WebSocket 客戶端連接的集合。

const clients = new Set()

AI 小補充

const clients = new Set() 是用來管理和追蹤 WebSocket 連接的客戶端的一種數據結構。Set 是 JavaScript 中的一種特殊集合,具有以下特點:

  1. 唯一性:Set 中的每個元素都是唯一的,不會有重複值

  2. 高效的增刪查操作

在 WebSocket 服務中使用 Set 通常有以下目的:

  1. 追蹤所有當前的 WebSocket 連接

  2. 方便管理和廣播消息

  3. 快速添加或移除客戶端連接

不加 const clients = new Set() 的話,會導致以下問題:

  1. 無法追蹤當前的 WebSocket 連接

  2. 無法實現廣播功能

  3. 每個客戶端之間無法互相通訊

在共享購物車場景中,Set 的作用是:

  1. 存儲所有已連接的客戶端

  2. 當購物車更新或刪除時,可以將訊息發送給同一群組的其他用戶

  3. 確保只將訊息發送給開啟的連接,且排除發送訊息的客戶端本身

像是這邊

clients.forEach((client) => {
  // 條件:
  // 1. 不是發送消息的客戶端本身
  // 2. WebSocket 連接是打開的
  if (client !== ws && client.readyState === WebSocket.OPEN) {
    client.send(JSON.stringify({
      type: "cartUpdate",
      data: parsedMessage.data,
    }))
  }
})

如果沒有 clients,就無法實現這種群組內廣播的機制!

還有比較前面的 clients.add(ws),是將新建立的 WebSocket 連接(ws)添加到 clients 這個 Set 集合中。

具體意義是每當有新的客戶端連接 WebSocket 時,就將這個連接實例加入 clientsadd() 方法確保不會添加重複的連接。

wss.on("connection", (ws) => {
  // 新客戶端連接時
  console.log("新的 WebSocket 連接")
  
  // 將這個連接加入 clients 集合
  clients.add(ws)

  // 後續可以對這個連接進行操作
  ws.on("message", (message) => {
    // 處理消息
  })

  // 連接關閉時從 clients 中移除
  ws.on("close", () => {
    clients.delete(ws)
  })
})

參考資料

Last updated