Go WebSocket 處理並發連線的方法:為每個連線使用一個 Goroutine。透過 Channel 進行連線通訊。使用第三方函式庫(如 [gowebsocket](https://github.com/gobwas/ws)、[gorilla/websocket](https://github.com/gorilla/websocket))來簡化處理。
WebSocket 是一種全雙工通訊協議,允許客戶端和伺服器進行即時雙向通訊。 Go 語言中處理 WebSocket 並發連線的常用方法如下:
1. Goroutine
一個簡單的解決方案是為每個連線使用一個 Goroutine。 Goroutine 是 Go 中的一種輕量級線程,可以並行執行。當一個新的WebSocket 連線建立時,我們可以建立一個新的Goroutine 來處理它:
package main import ( "fmt" "net/http" "os" "github.com/gorilla/websocket" ) var upgrader = websocket.Upgrader{} func main() { // WebSocket 服务器端口号 port := os.Getenv("PORT") if port == "" { port = "8080" } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 对请求进行 WebSocket 升级 conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) return } // 创建一个 Goroutine 处理连接 go handleConnection(conn) }) http.ListenAndServe(":"+port, nil) } // handleConnection 处理一个 WebSocket 连接 func handleConnection(conn *websocket.Conn) { for { msgType, msg, err := conn.ReadMessage() if err != nil { fmt.Println(err) break } if msgType == websocket.TextMessage { // 处理文本消息 fmt.Println("Received text message:", string(msg)) if err := conn.WriteMessage(msgType, msg); err != nil { fmt.Println(err) } } else { // 处理其他类型的消息 } } conn.Close() }
2. Channel
Channel 是Go 中用於通訊的並發通道。我們可以透過一個 Channel 來處理多個連接:
package main import ( "fmt" "net/http" "os" "sync" "time" "github.com/gorilla/websocket" ) var ( upgrader = websocket.Upgrader{} connections = make(chan *websocket.Conn, 100) wg sync.WaitGroup ) func main() { // WebSocket 服务器端口号 port := os.Getenv("PORT") if port == "" { port = "8080" } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 对请求进行 WebSocket 升级 conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) return } // 将连接添加到 Channel connections <- conn }) // 启动一个 Goroutine 处理 Channel 中的连接 go handleConnections() http.ListenAndServe(":"+port, nil) } // handleConnections 处理 Channel 中的 WebSocket 连接 func handleConnections() { for { conn := <-connections wg.Add(1) go func() { defer wg.Done() for { msgType, msg, err := conn.ReadMessage() if err != nil { fmt.Println(err) break } if msgType == websocket.TextMessage { // 处理文本消息 fmt.Println("Received text message:", string(msg)) // 向所有连接的客户端广播消息 for c := range connections { if c != conn { if err := c.WriteMessage(msgType, msg); err != nil { fmt.Println(err) } } } } else { // 处理其他类型的消息 } } conn.Close() }() } }
透過管道傳遞連接可以在所有 Goroutine 之間共享連接,並避免創建過多線程帶來的開銷。
3. 第三方函式庫
還有許多第三方函式庫可以簡化WebSocket 並發處理,例如:
這些函式庫提供了高層次的API 來處理並發連接,並簡化了WebSocket 的使用。
以上是Go WebSocket 如何處理並發連線?的詳細內容。更多資訊請關注PHP中文網其他相關文章!