在Go语言中实现WebSocket的双向通信通常需要使用第三方库,其中 gorilla/websocket
是一个非常流行和广泛使用的库。
1、安装
go get github.com/gorilla/websocket
2、编写WebSocket服务器代码
package main
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
// 允许所有来源的WebSocket连接
return true
},
}
func handleConnection(w http.ResponseWriter, r *http.Request) {
// 升级HTTP连接为WebSocket连接
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("升级到WebSocket连接时出错:", err)
return
}
defer conn.Close()
log.Println("客户端已连接")
// 读取客户端发来消息
for {
messageType, p, err := conn.ReadMessage()
if err != nil {
log.Println("从客户端读取时出错:", err)
return
}
// 处理消息
log.Printf("这是客户端发来的信息:%s-------------消息类型%v", string(p), messageType)
// 发送消息给客户端
err = conn.WriteMessage(messageType, []byte("你好!我是server端。。。"))
if err != nil {
fmt.Println(err)
return
}
}
}
func main() {
//创建一个HTTP服务器,当有请求过来时交给handleConnection处理
http.HandleFunc("/ws", handleConnection)
// 启动WebSocket服务器
log.Println("WebSocket服务器正在侦听:8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Println("WebSocket服务器正在侦听出错", err)
}
}
3、编写WebSocket客户端代码
package main
import (
"github.com/gorilla/websocket"
"log"
"os"
"os/signal"
"time"
)
func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt) //使用signal.Notify监听os.Interrupt信号(通常是Ctrl+C产生的中断信号)
u := "ws://localhost:8080/ws"
log.Printf("连接到服务器 %s", u)
c, _, err := websocket.DefaultDialer.Dial(u, nil) //试连接到WebSocket服务器
if err != nil {
log.Fatal("失败:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
//无限循环读取从WebSocket服务器发送的消息
for {
messageType, message, err := c.ReadMessage()
if err != nil {
log.Println("读取失败:", err)
return
}
log.Printf("这是服务器端发来的信息: %s--------------消息类型:%v", message, messageType)
}
}()
ticker := time.NewTicker(2 * time.Second) //创建一个定时器,每2秒触发一次
defer ticker.Stop()
for {
select {
case <-done:
return
case <-ticker.C: //定时候定时触发
//向WebSocket服务端发送消息
//websocket.TextMessage指定消息类型为文本消息
//t.String()将定时器的当前值转换为字符串,然后通过[]byte(t.String())转换为字节切片,作为消息的内容发送。
err := c.WriteMessage(websocket.TextMessage, []byte("你好!我是client端。。。"))
if err != nil {
log.Println("向WebSocket服务端发送消息出错:", err)
return
}
case <-interrupt:
log.Println("接收到中断信号")
// 关闭连接
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("关闭输入:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}