fox/ws/wsServer.go

117 lines
2.9 KiB
Go
Raw Normal View History

2025-05-25 20:02:15 +08:00
package ws
import (
"github.com/fox/fox/ksync"
"github.com/fox/fox/log"
"github.com/gorilla/websocket"
"net/http"
2025-06-01 10:33:41 +08:00
"runtime"
2025-05-25 20:02:15 +08:00
"time"
)
const (
// 允许等待的写入时间
2025-06-02 16:51:07 +08:00
//writeWait = 10 * time.Second
2025-05-25 20:02:15 +08:00
// pong间隔时间
pongWait = 60 * time.Second
// ping间隔时间
pingPeriod = (pongWait * 9) / 10
2025-06-01 10:35:06 +08:00
// 最大消息长度 1MB
maxMessageSize = 1024 * 1024
2025-05-25 20:02:15 +08:00
)
var upGrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // 允许所有跨域请求(生产环境应限制)
// 跨域限制
// allowedOrigins := map[string]bool{
// "https://yourdomain.com": true,
// "https://api.yourdomain.com": true,
// }
// return allowedOrigins[r.Header.Get("Origin")]
},
HandshakeTimeout: 10 * time.Second, // 握手超时
ReadBufferSize: 4096, // 读缓冲区
WriteBufferSize: 4096, // 写缓冲区
// MaxMessageSize: 1024 * 1024 * 2, // 最大消息2MB
}
type WsServer struct {
addr string // 0.0.0.0:8888
onMessage func(IConn, []byte)
onDisconnect func(IConn)
2025-06-17 18:24:33 +08:00
connMgr *connManager
userMgr *userManager
2025-05-25 20:02:15 +08:00
}
func NewWsServer(addr string, onMessage func(IConn, []byte), onDisconnect func(IConn)) *WsServer {
2025-06-17 18:24:33 +08:00
wss := &WsServer{
addr: addr,
onMessage: onMessage,
onDisconnect: onDisconnect,
connMgr: newConnManager(nil),
userMgr: newUserManager(nil),
}
wss.connMgr.userMgr = wss.userMgr
wss.userMgr.connMgr = wss.connMgr
return wss
2025-05-25 20:02:15 +08:00
}
func (s *WsServer) wsHandle(w http.ResponseWriter, r *http.Request) {
conn, err := upGrader.Upgrade(w, r, nil)
if err != nil {
log.ErrorF("升级到WebSocket失败:%v", err)
return
}
// defer func() { _ = conn.close() }()
2025-05-25 20:02:15 +08:00
nextConnId++
2025-06-17 18:24:33 +08:00
wsConn := newWsConnect(conn, s.onDisconnect, s.connMgr)
s.connMgr.Add(wsConn)
log.DebugF("当前连接数:%v", s.connMgr.Count())
2025-06-01 10:33:41 +08:00
log.DebugF("新连接id:%v %v", wsConn.Id(), wsConn.Name())
2025-05-25 20:02:15 +08:00
ksync.GoSafe(func() { wsConn.handle(s.onMessage) }, nil)
ksync.GoSafe(wsConn.readWsLoop, nil)
ksync.GoSafe(wsConn.writeWsLoop, nil)
}
2025-06-01 10:33:41 +08:00
func (s *WsServer) debugGoroutineNum() {
2025-06-02 16:51:07 +08:00
ch := time.Tick(2 * time.Minute)
2025-06-01 10:33:41 +08:00
go func() {
for {
select {
case <-ch:
log.DebugF("当前协程数量:%v", runtime.NumGoroutine())
}
}
}()
}
2025-05-25 20:02:15 +08:00
func (s *WsServer) Run() {
2025-06-01 09:33:27 +08:00
router := http.NewServeMux()
router.HandleFunc("/", s.wsHandle)
2025-05-25 20:02:15 +08:00
log.DebugF("websocket server listening on :%v", s.addr)
ksync.GoSafe(func() {
2025-06-01 09:33:27 +08:00
err := http.ListenAndServe(s.addr, router)
2025-05-25 20:02:15 +08:00
if err != nil {
log.Error(err.Error())
}
}, nil)
2025-06-01 10:33:41 +08:00
s.debugGoroutineNum()
2025-05-25 20:02:15 +08:00
}
func (s *WsServer) SetUserId(connId uint32, userId int64) {
2025-06-17 18:24:33 +08:00
s.connMgr.SetUserId(connId, userId)
2025-05-25 20:02:15 +08:00
}
func (s *WsServer) FindConnByUserId(userId int64) (IConn, bool) {
2025-06-17 18:24:33 +08:00
return s.connMgr.FindByUserId(userId)
2025-05-25 20:02:15 +08:00
}
2025-05-28 19:43:56 +08:00
func (s *WsServer) FindConnByConnId(connId uint32) (IConn, bool) {
2025-06-17 18:24:33 +08:00
return s.connMgr.Get(connId)
2025-05-28 19:43:56 +08:00
}
2025-05-28 20:07:20 +08:00
func (s *WsServer) Rang(cb func(conn IConn) bool) {
2025-06-17 18:24:33 +08:00
s.connMgr.Rang(cb)
2025-05-28 20:07:20 +08:00
}