182 lines
5.4 KiB
Go
182 lines
5.4 KiB
Go
package share
|
||
|
||
import (
|
||
"blazing/cool"
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/gogf/gf/v2/errors/gerror"
|
||
"github.com/gogf/gf/v2/os/gcache"
|
||
"github.com/gogf/gf/v2/os/gctx"
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
)
|
||
var ShareManager=newSessionManager()
|
||
var (
|
||
// ErrCacheMiss 表示缓存未命中
|
||
ErrCacheMiss = gerror.New("缓存未找到")
|
||
// ErrTypeConvert 表示类型转换失败
|
||
ErrTypeConvert = gerror.New("缓存值类型转换失败")
|
||
)
|
||
|
||
// cacheStore 泛型缓存存储
|
||
type cacheStore[T any] struct {
|
||
manager *gcache.Cache // 缓存管理器
|
||
prefix string // 缓存键前缀
|
||
}
|
||
|
||
// newSessionStore 创建会话缓存实例
|
||
func newSessionStore() *cacheStore[uint32] {
|
||
return &cacheStore[uint32]{
|
||
manager: cool.CacheManager,
|
||
prefix: "blazing:session:",
|
||
}
|
||
}
|
||
|
||
// newUserOnlineStore 创建用户在线状态缓存实例
|
||
func newUserOnlineStore() *cacheStore[uint16] {
|
||
return &cacheStore[uint16]{
|
||
manager: cool.CacheManager,
|
||
prefix: "blazing:useronline:",
|
||
}
|
||
}
|
||
|
||
// 生成带前缀的缓存键
|
||
func (s *cacheStore[T]) formatKey(key string) string {
|
||
return s.prefix + strings.TrimSpace(key)
|
||
}
|
||
|
||
// Get 通过键获取缓存值
|
||
func (s *cacheStore[T]) Get(ctx context.Context, key string) (T, error) {
|
||
var zero T
|
||
result, err := s.manager.Get(ctx, s.formatKey(key))
|
||
if err != nil {
|
||
return zero, gerror.Wrapf(err, "获取缓存失败,键: %s", key)
|
||
}
|
||
if result.IsEmpty() {
|
||
return zero, ErrCacheMiss
|
||
}
|
||
|
||
// 使用 ConvertWithRefer 进行类型转换
|
||
value := gconv.ConvertWithRefer(result.Val(), zero)
|
||
|
||
// 类型断言检查转换结果
|
||
converted, ok := value.(T)
|
||
if !ok {
|
||
return zero, gerror.Wrapf(
|
||
ErrTypeConvert,
|
||
"键: %s,缓存值实际类型: %T,期望类型: %T",
|
||
key, result.Val(), zero,
|
||
)
|
||
}
|
||
|
||
return converted, nil
|
||
}
|
||
|
||
// Set 设置缓存值并带有效期
|
||
func (s *cacheStore[T]) Set(ctx context.Context, key string, value T, duration time.Duration) error {
|
||
err := s.manager.Set(ctx, s.formatKey(key), value, duration)
|
||
if err != nil {
|
||
return gerror.Wrapf(err, "设置缓存失败,键: %s,值: %v", key, value)
|
||
}
|
||
fmt.Printf("[INFO] 缓存操作 [%s] 键: %s 值: %v 有效期: %v\n",
|
||
s.prefix, key, value, duration)
|
||
return nil
|
||
}
|
||
|
||
// Del 删除缓存
|
||
func (s *cacheStore[T]) Del(ctx context.Context, key string) error {
|
||
_, err := s.manager.Remove(ctx, s.formatKey(key))
|
||
if err != nil {
|
||
return gerror.Wrapf(err, "删除缓存失败,键: %s", key)
|
||
}
|
||
fmt.Printf("[INFO] 删除缓存 [%s] 键: %s 成功\n", s.prefix, key)
|
||
return nil
|
||
}
|
||
|
||
// Contains 检查缓存是否存在
|
||
func (s *cacheStore[T]) Contains(ctx context.Context, key string) (bool, error) {
|
||
exists, err := s.manager.Contains(ctx, s.formatKey(key))
|
||
if err != nil {
|
||
return false, gerror.Wrapf(err, "检查缓存是否存在失败,键: %s", key)
|
||
}
|
||
return exists, nil
|
||
}
|
||
|
||
// GetOrSet 获取缓存值,如果不存在则设置默认值
|
||
func (s *cacheStore[T]) GetOrSet(ctx context.Context, key string, defaultValue T, duration time.Duration) (T, error) {
|
||
var zero T
|
||
result, err := s.manager.GetOrSet(ctx, s.formatKey(key), defaultValue, duration)
|
||
if err != nil {
|
||
return zero, gerror.Wrapf(err, "获取或设置缓存失败,键: %s", key)
|
||
}
|
||
|
||
// 类型转换
|
||
value := gconv.ConvertWithRefer(result.Val(), zero)
|
||
converted, ok := value.(T)
|
||
if !ok {
|
||
return zero, gerror.Wrapf(
|
||
ErrTypeConvert,
|
||
"键: %s,缓存值实际类型: %T,期望类型: %T",
|
||
key, result.Val(), zero,
|
||
)
|
||
}
|
||
|
||
return converted, nil
|
||
}
|
||
|
||
// sessionManager 会话管理器
|
||
type sessionManager struct {
|
||
sessionStore *cacheStore[uint32] // 会话缓存
|
||
userOnlineStore *cacheStore[uint16] // 用户在线状态缓存
|
||
}
|
||
|
||
// newSessionManager 创建会话管理器
|
||
func newSessionManager() *sessionManager {
|
||
return &sessionManager{
|
||
sessionStore: newSessionStore(),
|
||
userOnlineStore: newUserOnlineStore(),
|
||
}
|
||
}
|
||
|
||
// GetSession 通过会话ID获取用户ID
|
||
func (m *sessionManager) GetSession(sessionID string) (uint32, error) {
|
||
return m.sessionStore.Get(context.Background(), sessionID)
|
||
}
|
||
|
||
// SaveSession 保存会话信息
|
||
func (m *sessionManager) SaveSession(sessionID string, userID uint32) error {
|
||
return m.sessionStore.Set(gctx.New(), sessionID, userID, time.Hour*24)
|
||
}
|
||
|
||
// DeleteSession 删除会话
|
||
func (m *sessionManager) DeleteSession(sessionID string) error {
|
||
return m.sessionStore.Del(gctx.New(), sessionID)
|
||
}
|
||
|
||
// SessionExists 检查会话是否存在
|
||
func (m *sessionManager) SessionExists(sessionID string) (bool, error) {
|
||
return m.sessionStore.Contains(context.Background(), sessionID)
|
||
}
|
||
|
||
// SetUserOnline 设置用户在线状态
|
||
func (m *sessionManager) SetUserOnline(userID uint32, serverID uint16) error {
|
||
return m.userOnlineStore.Set(gctx.New(), gconv.String(userID), serverID, 0)
|
||
}
|
||
|
||
// GetUserOnline 获取用户在线状态
|
||
func (m *sessionManager) GetUserOnline(userID uint32) (uint16, error) {
|
||
return m.userOnlineStore.Get(context.Background(), gconv.String(userID))
|
||
}
|
||
|
||
// DeleteUserOnline 删除用户在线状态
|
||
func (m *sessionManager) DeleteUserOnline(userID uint32) error {
|
||
return m.userOnlineStore.Del(gctx.New(), gconv.String(userID))
|
||
}
|
||
|
||
// UserOnlineExists 检查用户在线状态是否存在
|
||
func (m *sessionManager) UserOnlineExists(userID uint32) (bool, error) {
|
||
return m.userOnlineStore.Contains(context.Background(), gconv.String(userID))
|
||
}
|