123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package ws
- import (
- "errors"
- "fmt"
- "github.com/gorilla/websocket"
- "sync"
- "time"
- )
- const (
- maxMessageSize = 1024 * 1024
- basePingInterval = 30 * time.Second
- maxPingInterval = 120 * time.Second
- minPingInterval = 15 * time.Second
- )
- type ConnectionManager struct {
- Sessions sync.Map
- heartbeat *HeartbeatManager
- }
- var (
- manager = &ConnectionManager{
- heartbeat: GetHeartbeatManager(),
- }
- )
- func Manager() *ConnectionManager {
- return manager
- }
- func (manager *ConnectionManager) HandleMessage(userID int, sessionID string, message []byte) error {
- if !Allow(userID, QA_LIMITER) {
- return errors.New("request too frequent")
- }
- session, exists := manager.GetSession(sessionID)
- if !exists {
- return errors.New("session not found")
- }
-
- session.History = append(session.History, string(message))
- response := "Processed: " + string(message)
-
- session.LastActive = time.Now()
-
- return session.Conn.WriteMessage(websocket.TextMessage, []byte(response))
- }
- func (manager *ConnectionManager) StartHeartbeat() {
- ticker := time.NewTicker(basePingInterval)
- defer ticker.Stop()
- for range ticker.C {
- manager.checkSessions()
- }
- }
- func (manager *ConnectionManager) checkSessions() {
- manager.Sessions.Range(func(key, value interface{}) bool {
- session := value.(*Session)
- if time.Since(session.LastActive) > 2*basePingInterval {
- session.Conn.Close()
- manager.Sessions.Delete(key)
- } else {
- _ = session.Latency.SendPing(session.Conn)
- }
- return true
- })
- }
- func (manager *ConnectionManager) AddSession(session *Session) {
- manager.Sessions.Store(session.ID, session)
- manager.heartbeat.Register(session)
- }
- func (manager *ConnectionManager) GetSessionId(userId int, sessionId string) (sessionID string) {
- return fmt.Sprintf("%d_%s", userId, sessionId)
- }
- func (manager *ConnectionManager) RemoveSession(sessionCode string) {
- if data, ok := manager.Sessions.LoadAndDelete(sessionCode); ok {
- session := data.(*Session)
- close(session.CloseChan)
- _ = session.Conn.Close()
- }
- }
- func (manager *ConnectionManager) GetSession(sessionCode string) (session *Session, ok bool) {
- if data, ok := manager.Sessions.Load(sessionCode); ok {
- session = data.(*Session)
- }
- return
- }
|