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
|
|
|
|
}
|
2025-05-28 14:54:19 +08:00
|
|
|
// 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
|
|
|
}
|