Files
excel-api/websocket/handler.go
2026-06-26 14:31:24 +08:00

96 lines
2.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package websocket 提供WebSocket HTTP升级处理器
package websocket
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
)
// upgrader 用于将HTTP连接升级为WebSocket连接
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024, // 读缓冲区大小
WriteBufferSize: 1024, // 写缓冲区大小
// 允许所有来源的连接(开发环境)
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// HandleWebSocket 处理WebSocket连接升级请求Gin版本
// 客户端通过此接口建立WebSocket连接加入Hub进行消息通信
// 路径: GET /api/ws
func HandleWebSocket(hub *Hub) gin.HandlerFunc {
return func(c *gin.Context) {
handleWS(hub, c.Writer, c.Request)
}
}
// HandleWebSocketHTTP 处理WebSocket连接升级请求标准net/http版本
// 用于独立的WebSocket服务端口16703
func HandleWebSocketHTTP(hub *Hub) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
handleWS(hub, w, r)
}
}
// handleWS WebSocket连接处理的核心逻辑
func handleWS(hub *Hub, w http.ResponseWriter, r *http.Request) {
// 将HTTP连接升级为WebSocket连接
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("WebSocket升级失败: %v", err)
return
}
// 创建客户端实例并注册到Hub
client := &Client{
hub: hub,
conn: conn,
send: make(chan []byte, 256),
}
hub.register <- client
// 启动读写goroutine
go client.writePump()
go client.readPump()
}
// readPump 从WebSocket连接读取消息
// 持续监听客户端发送的消息,遇到错误或关闭时断开连接
func (c *Client) readPump() {
defer func() {
c.hub.unregister <- c
c.conn.Close()
}()
for {
// 读取消息(目前仅用于检测连接状态,后续可扩展协作协议)
_, message, err := c.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseNormalClosure) {
log.Printf("WebSocket读取错误: %v", err)
}
break
}
// 收到客户端消息后广播给其他客户端(协作基础)
c.hub.BroadcastMessage(message)
}
}
// writePump 向WebSocket连接写入消息
// 从send通道读取消息并发送给客户端
func (c *Client) writePump() {
defer c.conn.Close()
for message := range c.send {
err := c.conn.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Printf("WebSocket写入错误: %v", err)
break
}
}
}