深圳幻海软件技术有限公司 欢迎您!

两个 Go 程序之间的 WebSocket 通信

2023-02-28

 实现两个Go服务之间做WebSocket通信要怎么做?本文做了介绍。使用WebSockets时,一个程序必须充当服务器。但是可以有许多其他程序作为客户端。在本文中,我们将创建一个服务器和一个客户端WebSocketServer服务器的代码非常简单。因为我们不想重新发明轮子,所以我们将使用

 

实现两个 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)  
            }  
        }()  
    }))  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

服务器除了等待连接之外什么都不做,打印接收到的数据并最后发送一条消息(随机整数)

如果客户端断开连接(或有人停止程序),它将打印有关此断开连接的信息

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")  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

这个客户端除了连接、发送消息(随机整数)并打印发回的任何内容之外没有什么特别的

测试

左侧,服务器结果 右侧,客户端结果

客户端每 5 秒向服务器发送一个随机数。服务器用另一个随机数回复

如果您停止服务器,您将在客户端看到服务器已断开连接。如果您再次启动服务器,客户端将再次连接。

您可以以另一种方式期待相同的行为。如果停止客户端,服务器将打印一条消息,表明客户端已断开连接。如果您再次运行客户端......好吧,它再次连接

因为 Go 经常用于服务和/或微服务,所以在这些服务之间进行通信是有意义的 。