以下是使用 Go 编写的 WebSocket 服务端和客户端代码示例。
WebSocket 服务端代码示例:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
// 定义 WebSocket 连接升级器
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
// 允许跨域访问
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func main() {
// 注册 WebSocket 处理函数
http.HandleFunc("/ws", handleWebSocket)
// 监听 8080 端口
http.ListenAndServe(":8080", nil)
}
// 处理 WebSocket 连接
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
// 升级 HTTP 连接为 WebSocket 连接
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return
}
// 在新的协程中处理 WebSocket 消息
go handleWebSocketMessage(conn)
}
// 处理 WebSocket 消息
func handleWebSocketMessage(conn *websocket.Conn) {
for {
// 读取 WebSocket 消息
_, message, err := conn.ReadMessage()
if err != nil {
fmt.Println(err)
return
}
// 打印消息
fmt.Printf("Message received: %s\n", message)
// 回复消息
err = conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
fmt.Println(err)
return
}
}
}
WebSocket 客户端代码示例:
package main
import (
"fmt"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
func main() {
// 构造 WebSocket 连接地址
u := url.URL{Scheme: "ws", Host: "localhost:8080", Path: "/ws"}
// 连接 WebSocket 服务器
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
// 启动发送消息协程
go sendMessage(c)
// 循环读取消息
for {
// 读取 WebSocket 消息
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("Message received: %s", message)
}
}
// 发送消息
func sendMessage(c *websocket.Conn) {
for i := 0; i < 5; i++ {
message := []byte(fmt.Sprintf("Hello, %d!", i))
// 发送消息
err := c.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Println("write:", err)
return
}
// 等待 1 秒
time.Sleep(time.Second)
}
// 发送关闭消息并关闭连接
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
}
// 监听系统信号,关闭连接
func listenSignal(c *websocket.Conn) {
ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
<-ch
log.Println("interrupt signal received, closing connection")
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-time.After(1 * time.Second):
}
return
}