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

# 後端設置 WebSocket 連接處理

## 處理 WebSocket 的連接處理

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

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

```javascript
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 客戶端連接的集合。

```javascript
const clients = new Set()
```

{% hint style="info" %}
AI 小補充

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

1. 唯一性：`Set` 中的每個元素都是唯一的，不會有重複值
2. 高效的增刪查操作

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

1. 追蹤所有當前的 WebSocket 連接
2. 方便管理和廣播消息
3. 快速添加或移除客戶端連接
{% endhint %}

不加 `const clients = new Set()` 的話，會導致以下問題：

1. 無法追蹤當前的 WebSocket 連接
2. 無法實現廣播功能
3. 每個客戶端之間無法互相通訊

在共享購物車場景中，`Set` 的作用是：

1. 存儲所有已連接的客戶端
2. 當購物車更新或刪除時，可以將訊息發送給同一群組的其他用戶
3. 確保只將訊息發送給開啟的連接，且排除發送訊息的客戶端本身

像是這邊

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

<mark style="background-color:yellow;">如果沒有</mark> <mark style="background-color:yellow;"></mark><mark style="background-color:yellow;">`clients`</mark><mark style="background-color:yellow;">，就無法實現這種群組內廣播的機制！</mark>

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

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

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

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

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

***

#### 參考資料

* &#x20;[WebSocket - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
* [淺談 WebSocket 協定：實作一個簡單的即時聊天室吧！ - HackMD](https://hackmd.io/@Heidi-Liu/javascript-websocket)

