两个 Go 程序之间的 WebSocket 通信

开发 后端
实现两个 Go 服务之间做 WebSocket 通信要怎么做?本文做了介绍。

 [[440851]]

实现两个 Go 服务之间做 WebSocket 通信要怎么做?本文做了介绍。

使用 WebSockets 时,一个程序必须充当服务器。

但是可以有许多其他程序作为客户端。在本文中,我们将创建一个服务器和一个客户端

WebSocket Server

服务器的代码非常简单。因为我们不想重新发明轮子,所以我们将使用gobwas模块

下面是运行在端口 8080 上的 WebSocket 服务器的代码 

  1. package main  
  2. import (  
  3.     "fmt"  
  4.     "github.com/gobwas/ws"  
  5.     "github.com/gobwas/ws/wsutil"  
  6.     "math/rand"  
  7.     "net/http"  
  8.     "strconv" 
  9.  
  10. func main() {  
  11.     fmt.Println("Server started, waiting for connection from client")  
  12.     http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {  
  13.         fmt.Println("Client connected")  
  14.         conn, _, _, err :ws.UpgradeHTTP(r, w)  
  15.         if err != nil {  
  16.             fmt.Println("Error starting socket server: " + err.Error())  
  17.         }  
  18.         go func() {  
  19.             defer conn.Close()  
  20.             for {  
  21.                 msg, op, err :wsutil.ReadClientData(conn)  
  22.                 if err != nil {  
  23.                     fmt.Println("Error receiving data: " + err.Error())  
  24.                     fmt.Println("Client disconnected")  
  25.                     return  
  26.                 }  
  27.                 fmt.Println("Client message received with random number: " + string(msg))  
  28.                 randomNumber :strconv.Itoa(rand.Intn(100))  
  29.                 err = wsutil.WriteServerMessage(conn, op, []byte(randomNumber))  
  30.                 if err != nil {  
  31.                     fmt.Println("Error sending data: " + err.Error())  
  32.                     fmt.Println("Client disconnected")  
  33.                     return  
  34.                 }  
  35.                 fmt.Println("Server message send with random number " + randomNumber)  
  36.             }  
  37.         }()  
  38.     }))  

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

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

WebSocket Client

客户端的代码类似。同样,我们将使用gobwas模块

客户端正在通过端口 8080 连接到 localhost 

  1. package main  
  2. import (  
  3.     "context"  
  4.     "fmt"  
  5.     "github.com/gobwas/ws"  
  6.     "github.com/gobwas/ws/wsutil"  
  7.     "math/rand"  
  8.     "os"  
  9.     "strconv"  
  10.     "time"  
  11.  
  12. func main() {  
  13.     fmt.Println("Client started")  
  14.     for {  
  15.         conn, _, _, err :ws.DefaultDialer.Dial(context.Background(), "ws://127.0.0.1:8080/")  
  16.         if err != nil {  
  17.             fmt.Println("Cannot connect: " + err.Error())  
  18.             time.Sleep(time.Duration(5) * time.Second)  
  19.             continue  
  20.         }  
  21.         fmt.Println("Connected to server")  
  22.         for i :0; i < 10; i++ {  
  23.             randomNumber :strconv.Itoa(rand.Intn(100))  
  24.             msg := []byte(randomNumber)  
  25.             err = wsutil.WriteClientMessage(conn, ws.OpText, msg)  
  26.             if err != nil {  
  27.                 fmt.Println("Cannot send: " + err.Error())  
  28.                 continue  
  29.             }  
  30.             fmt.Println("Client message send with random number " + randomNumber)  
  31.             msg, _, err :wsutil.ReadServerData(conn)  
  32.             if err != nil {  
  33.                 fmt.Println("Cannot receive data: " + err.Error())  
  34.                 continue  
  35.             }  
  36.             fmt.Println("Server message received with random number: " + string(msg))  
  37.             time.Sleep(time.Duration(5) * time.Second)  
  38.         }  
  39.         err = conn.Close()  
  40.         if err != nil {  
  41.             fmt.Println("Cannot close the connection: " + err.Error())  
  42.             os.Exit(1)  
  43.         }  
  44.         fmt.Println("Disconnected from server")  
  45.     }  

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

测试

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

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

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

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

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

 

责任编辑:庞桂玉 来源: 马哥Linux运维
相关推荐

2011-04-15 09:47:38

IntentActivityAndroid

2020-08-14 08:13:49

列表差异编程

2021-11-30 06:56:58

编译Go程序

2015-02-05 09:54:13

程序员

2013-07-05 10:52:07

程序员结对编程

2010-07-25 14:31:54

Telnet程序

2023-10-04 20:03:46

GOkeyvalue

2020-03-26 15:12:35

程序线程协程

2013-12-18 10:34:42

OpenMP线程

2012-12-21 09:19:29

Google GO

2021-03-19 11:05:50

Linux目录命令

2013-05-10 09:31:06

程序员

2010-07-02 12:26:51

LEACH协议

2022-06-17 09:46:51

Chrome 102Chrome浏览器

2009-07-15 18:29:22

Jython应用

2017-04-10 14:35:35

SambaRsyncSysVol

2021-10-13 06:49:13

Integer 阿里巴巴包装类

2020-03-02 11:47:27

区块链存储应用程序

2024-09-29 10:39:48

RSocketWebSocket通信

2020-11-13 07:16:09

线程互斥锁死循环
点赞
收藏

51CTO技术栈公众号