session.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package session
  2. import (
  3. "sync"
  4. "sync/atomic"
  5. "time"
  6. "realtime-gateway/internal/model"
  7. )
  8. type Session struct {
  9. ID string
  10. Role model.Role
  11. Authenticated bool
  12. ChannelID string
  13. Subscriptions []model.Subscription
  14. CreatedAt time.Time
  15. }
  16. type Snapshot struct {
  17. ID string `json:"id"`
  18. Role model.Role `json:"role"`
  19. Authenticated bool `json:"authenticated"`
  20. ChannelID string `json:"channelId,omitempty"`
  21. CreatedAt time.Time `json:"createdAt"`
  22. Subscriptions []model.Subscription `json:"subscriptions"`
  23. }
  24. type Manager struct {
  25. mu sync.RWMutex
  26. sequence atomic.Uint64
  27. sessions map[string]*Session
  28. }
  29. func NewManager() *Manager {
  30. return &Manager{
  31. sessions: make(map[string]*Session),
  32. }
  33. }
  34. func (m *Manager) Create() *Session {
  35. id := m.sequence.Add(1)
  36. session := &Session{
  37. ID: formatSessionID(id),
  38. Role: model.RoleConsumer,
  39. CreatedAt: time.Now(),
  40. }
  41. m.mu.Lock()
  42. m.sessions[session.ID] = session
  43. m.mu.Unlock()
  44. return session
  45. }
  46. func (m *Manager) Delete(sessionID string) {
  47. m.mu.Lock()
  48. delete(m.sessions, sessionID)
  49. m.mu.Unlock()
  50. }
  51. func (m *Manager) Get(sessionID string) (*Session, bool) {
  52. m.mu.RLock()
  53. defer m.mu.RUnlock()
  54. session, ok := m.sessions[sessionID]
  55. return session, ok
  56. }
  57. func (m *Manager) Count() int {
  58. m.mu.RLock()
  59. defer m.mu.RUnlock()
  60. return len(m.sessions)
  61. }
  62. func (m *Manager) List() []Snapshot {
  63. m.mu.RLock()
  64. defer m.mu.RUnlock()
  65. snapshots := make([]Snapshot, 0, len(m.sessions))
  66. for _, current := range m.sessions {
  67. subscriptions := append([]model.Subscription(nil), current.Subscriptions...)
  68. snapshots = append(snapshots, Snapshot{
  69. ID: current.ID,
  70. Role: current.Role,
  71. Authenticated: current.Authenticated,
  72. ChannelID: current.ChannelID,
  73. CreatedAt: current.CreatedAt,
  74. Subscriptions: subscriptions,
  75. })
  76. }
  77. return snapshots
  78. }
  79. func formatSessionID(id uint64) string {
  80. return "sess-" + itoa(id)
  81. }
  82. func itoa(v uint64) string {
  83. if v == 0 {
  84. return "0"
  85. }
  86. var buf [20]byte
  87. i := len(buf)
  88. for v > 0 {
  89. i--
  90. buf[i] = byte('0' + v%10)
  91. v /= 10
  92. }
  93. return string(buf[i:])
  94. }