
專案概述
這是一個以 Discord 為樣板製作的即時聊天應用,包含前端(Vue 3)和後端(Go)兩個部分。支援伺服器(Server/Guild)、頻道(Channel/Room)、私訊(DM)、好友系統等完整功能。採用 WebSocket 實現即時通訊,MongoDB 儲存數據,Redis 處理部分資料快取。
技術挑戰與解決方案
後端系統架構
這是我學習Golang的第一個專案,所以只有PHP經驗的我,對於Golang的生態和最佳實踐完全不懂,加上我原本預想是要直接朝向高效能架構設計。
解決方案:
花了不少時間了解與重構架構,最後考慮到真實情況通常不會直上最高效能,反而是要在可維護性和效能中取得平衡,所以我選擇了MVC架構,並且使用依賴注入(DI)來降低模組間的耦合度,讓程式碼更易於測試和維護。
會員系統
要實現SPA的會員系統,並且確保安全性。
解決方案:
採用 JWT Access/Refresh Token 雙重驗證,refresh token存放在httpOnly cookie中,防止XSS攻擊。後端資料庫也有存放refresh token,確保token的有效性。
WebSocket 即時通訊
需要實現高效能且穩定的即時通訊系統。
解決方案:
使用 Go 的 Gorilla WebSocket 庫來處理 WebSocket 連線,並且設計了 Hub、Client、Room 三個主要結構來管理連線和訊息傳遞:
- Hub 負責管理所有 Client 和 Room
- Client 負責處理單一用戶的連線
- Room 負責管理聊天室內的訊息傳遞
具體實作上:
- 在每個 Client 建立獨立的 readPump / writePump goroutine,使用 channel 傳遞要寫出的訊息,避免在同一 goroutine 同時處理讀寫造成阻塞
- Hub 的 broadcast 與註冊/取消註冊可各自放在 goroutine,但共享狀態要透過 channel 或 mutex 保護,推薦以 channel 作為單一變更入口以避免競爭條件
- Room 的訊息分發可在獨立 goroutine 處理大量廣播工作,並用緩衝 channel 控制回壓(backpressure)
注意資源回收:連線關閉時應關閉相關 channel、使用 context 或 close channel 取消 goroutine,避免 goroutine 泄漏。
聊天室設計
需要處理 Channel 與 DM 不同種類的聊天室。
解決方案:
雖然兩者是不同的資料表,但是在記憶體 Room 結構中,Channel 和 DM 都是 Room 的一種,所以在記憶體中只需要一個 Room 結構,並且用 Type 來區分是 Channel 還是 DM。
前端Vue狀態管理
前端需要有效管理多個聊天室、用戶狀態和即時訊息。
解決方案:
使用 Pinia 進行全局狀態管理,將用戶資料、聊天室列表、訊息等狀態集中管理,確保各組件能夠同步更新。
系統架構

前端使用 Vue 3 + TypeScript,後端採用 Go + Gin 框架,三層架構設計(Controller → Service → Repository),WebSocket 提供即時通訊,MongoDB 儲存聊天記錄,Redis 處理資料快取。
學習與心得
通過這個專案深入學習了 WebSocket 即時通訊技術,掌握了 Go 語言的 Gin 框架開發,以及 Vue 3 Composition API 的使用。特別是在處理複雜的狀態管理和即時訊息推播方面積累了寶貴經驗。
技術棧
前端
Vue 3TypeScriptElement PlusUnoCSSPinia
後端
GoGinWebsSocketJWTODMDIMVC
資料庫
MongoDBRedis