init: 第一次提交
- 以实现登录获取个人信息和课程 - 实现了获取视频记录 - 实现了学习接口
This commit is contained in:
117
internal/ckwk/session_manager.go
Normal file
117
internal/ckwk/session_manager.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package ckwk
|
||||
|
||||
import (
|
||||
"ckwk/pkg/log"
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type SessionManager struct {
|
||||
mu sync.RWMutex
|
||||
sessions map[string]SessionItem
|
||||
userToSession map[string]string
|
||||
}
|
||||
|
||||
type SessionItem struct {
|
||||
Instance *WK
|
||||
LastValue time.Time
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewSessionManager() *SessionManager {
|
||||
return &SessionManager{
|
||||
sessions: make(map[string]SessionItem),
|
||||
userToSession: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// Store: 保存 session 并返回 session id
|
||||
func (m *SessionManager) Store(wk *WK) string {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
userKey := wk.Host + ":" + wk.Username
|
||||
if oldID, exists := m.userToSession[userKey]; exists {
|
||||
item := m.sessions[oldID]
|
||||
item.LastValue = time.Now()
|
||||
item.Instance = wk
|
||||
m.sessions[oldID] = item
|
||||
|
||||
log.Info("用户已存在,复用旧 Session",
|
||||
zap.String("id", oldID),
|
||||
zap.String("user", userKey),
|
||||
)
|
||||
|
||||
return oldID
|
||||
}
|
||||
|
||||
sessionID := uuid.New().String()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
m.userToSession[userKey] = sessionID
|
||||
m.sessions[sessionID] = SessionItem{
|
||||
Instance: wk,
|
||||
LastValue: time.Now(),
|
||||
cancel: cancel,
|
||||
}
|
||||
|
||||
log.Info("创建新 Session", zap.String("id", sessionID))
|
||||
|
||||
go m.KeepAlive(ctx, sessionID, wk)
|
||||
|
||||
return sessionID
|
||||
}
|
||||
|
||||
// Get: 获取指定 session id 的 wk
|
||||
func (m *SessionManager) Get(sessionID string) (*WK, bool) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
item, ok := m.sessions[sessionID]
|
||||
if ok {
|
||||
return item.Instance, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (m *SessionManager) Del(sessionID string) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if item, ok := m.sessions[sessionID]; ok {
|
||||
userKey := item.Instance.Host + ":" + item.Instance.Username
|
||||
|
||||
if item.cancel != nil {
|
||||
item.cancel()
|
||||
}
|
||||
|
||||
delete(m.userToSession, userKey)
|
||||
delete(m.sessions, sessionID)
|
||||
|
||||
log.Info("删除 Session", zap.String("id", sessionID))
|
||||
}
|
||||
}
|
||||
|
||||
func (m *SessionManager) KeepAlive(ctx context.Context, id string, wk *WK) {
|
||||
ticker := time.NewTicker(2 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
log.Info("启动 KeepAlive", zap.String("id", id))
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Info("KeepAlive 已停止", zap.String("id", id))
|
||||
return
|
||||
case <-ticker.C:
|
||||
_, err := wk.Online()
|
||||
if err != nil {
|
||||
log.Error("自动保活请求失败", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user