在 golang 中如何實現 WebSocket 的雙向通信

在 Go 語言中實現 WebSocket 的雙向通信通常需要使用第三方庫,其中 gorilla/websocket 是一個非常流行和廣泛使用的庫。

以下是實現 WebSocket 雙向通信的步驟和簡單示例代碼:

1 安裝 gorilla/websocket 庫:

go get github.com/gorilla/websocket

2 編寫 WebSocket 服務器:

package main

import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
    // 允許所有來源的WebSocket連接
    return true
},
}

func handleConnection(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
    fmt.Println(err)
    return
}
defer conn.Close()

fmt.Println("Client connected")

for {
    // 讀取客戶端消息
    messageType, p, err := conn.ReadMessage()
    if err != nil {
        fmt.Println(err)
        return
    }

    // 處理消息
    fmt.Printf("Received message: %s\n", p)

    // 發送消息給客戶端
    err = conn.WriteMessage(messageType, p)
    if err != nil {
        fmt.Println(err)
        return
    }
}
}

func main() {
http.HandleFunc("/ws", handleConnection)

// 啓動WebSocket服務器
fmt.Println("WebSocket server listening on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
    fmt.Println(err)
}
}

在上述代碼中,我們使用 gorilla/websocketUpgrader 來升級 HTTP 連接爲 WebSocket 連接。在 handleConnection 函數中,我們處理了連接的升級、讀取客戶端消息以及向客戶端發送消息。

3 編寫 WebSocket 客戶端:

package main

import (
"fmt"
"log"
"os"
"os/signal"
"time"

"github.com/gorilla/websocket"
)

func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)

u := "ws://localhost:8080/ws"
log.Printf("connecting to %s", u)

c, _, err := websocket.DefaultDialer.Dial(u, nil)
if err != nil {
    log.Fatal("dial:", err)
}
defer c.Close()

done := make(chan struct{})

go func() {
    defer close(done)
    for {
        _, message, err := c.ReadMessage()
        if err != nil {
            log.Println("read:", err)
            return
        }
        log.Printf("recv: %s", message)
    }
}()

ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for {
    select {
    case <-done:
        return
    case t := <-ticker.C:
        err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
        if err != nil {
            log.Println("write:", err)
            return
        }
    case <-interrupt:
        log.Println("interrupt")

        // 關閉連接
        err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
        if err != nil {
            log.Println("write close:", err)
            return
        }
        select {
        case <-done:
        case <-time.After(time.Second):
        }
        return
    }
}
}

在客戶端代碼中,我們使用 gorilla/websocketDefaultDialer 來建立與 WebSocket 服務器的連接。然後,我們啓動兩個 goroutine,一個用於接收服務器發來的消息,另一個用於定期向服務器發送消息。

  1. 運行程序:

通過這個簡單的示例,你可以看到 WebSocket 服務器和客戶端之間的雙向通信。你可以

根據實際需求擴展和修改這個基礎的實現。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Gk_zHKTw39tllmfwsInpaw