兩個 Go 程序之間的 WebSocket 通信

使用 WebSockets 時,一個程序必須充當服務器。

但是可以有許多其他程序作爲客戶端。在本文中,我們將創建一個服務器和一個客戶端

WebSocket Server

服務器的代碼非常簡單。因爲我們不想重新發明輪子,所以我們將使用gobwas模塊

下面是運行在端口 8080 上的 WebSocket 服務器的代碼

package main

import (
    "fmt"
    "github.com/gobwas/ws"
    "github.com/gobwas/ws/wsutil"
    "math/rand"
    "net/http"
    "strconv"
)

func main() {
    fmt.Println("Server started, waiting for connection from client")
    http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Println("Client connected")
        conn, _, _, err := ws.UpgradeHTTP(r, w)
        if err != nil {
            fmt.Println("Error starting socket server: " + err.Error())
        }
        go func() {
            defer conn.Close()
            for {
                msg, op, err := wsutil.ReadClientData(conn)
                if err != nil {
                    fmt.Println("Error receiving data: " + err.Error())
                    fmt.Println("Client disconnected")
                    return
                }
                fmt.Println("Client message received with random number: " + string(msg))
                randomNumber := strconv.Itoa(rand.Intn(100))
                err = wsutil.WriteServerMessage(conn, op, []byte(randomNumber))
                if err != nil {
                    fmt.Println("Error sending data: " + err.Error())
                    fmt.Println("Client disconnected")
                    return
                }
                fmt.Println("Server message send with random number " + randomNumber)
            }
        }()
    }))
}

服務器除了等待連接之外什麼都不做,打印接收到的數據並最後發送一條消息(隨機整數)

如果客戶端斷開連接(或有人停止程序),它將打印有關此斷開連接的信息

WebSocket Client

客戶端的代碼類似。同樣,我們將使用gobwas模塊

客戶端正在通過端口 8080 連接到 localhost

package main

import (
    "context"
    "fmt"
    "github.com/gobwas/ws"
    "github.com/gobwas/ws/wsutil"
    "math/rand"
    "os"
    "strconv"
    "time"
)

func main() {
    fmt.Println("Client started")
    for {
        conn, _, _, err := ws.DefaultDialer.Dial(context.Background()"ws://127.0.0.1:8080/")
        if err != nil {
            fmt.Println("Cannot connect: " + err.Error())
            time.Sleep(time.Duration(5) * time.Second)
            continue
        }
        fmt.Println("Connected to server")
        for i := 0; i < 10; i++ {
            randomNumber := strconv.Itoa(rand.Intn(100))
            msg := []byte(randomNumber)
            err = wsutil.WriteClientMessage(conn, ws.OpText, msg)
            if err != nil {
                fmt.Println("Cannot send: " + err.Error())
                continue
            }
            fmt.Println("Client message send with random number " + randomNumber)
            msg, _, err := wsutil.ReadServerData(conn)
            if err != nil {
                fmt.Println("Cannot receive data: " + err.Error())
                continue
            }
            fmt.Println("Server message received with random number: " + string(msg))
            time.Sleep(time.Duration(5) * time.Second)
        }
        err = conn.Close()
        if err != nil {
            fmt.Println("Cannot close the connection: " + err.Error())
            os.Exit(1)
        }
        fmt.Println("Disconnected from server")
    }
}

這個客戶端除了連接、發送消息(隨機整數)並打印發回的任何內容之外沒有什麼特別的

測試

左側,服務器結果 右側,客戶端結果

客戶端每 5 秒向服務器發送一個隨機數。服務器用另一個隨機數回覆

如果您停止服務器,您將在客戶端看到服務器已斷開連接。如果您再次啓動服務器,客戶端將再次連接。

您可以以另一種方式期待相同的行爲。如果停止客戶端,服務器將打印一條消息,表明客戶端已斷開連接。如果您再次運行客戶端...... 好吧,它再次連接

因爲 Go 經常用於服務和 / 或微服務,所以在這些服務之間進行通信是有意義的

轉自:

elephdev.com/index.php/golang/285.html?ref=addtabs&lang=zh-cn

Go 開發大全

參與維護一個非常全面的 Go 開源技術資源庫。日常分享 Go, 雲原生、k8s、Docker 和微服務方面的技術文章和行業動態。

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