samba/util/model/userOnline.go
2025-06-04 09:51:39 +08:00

92 lines
2.1 KiB
Go

package model
import (
"context"
"encoding/json"
"fmt"
"github.com/go-redis/redis/v8"
"github.com/golang-module/carbon/v2"
"samba/pkg/log"
"samba/pkg/servername"
"samba/pkg/service"
"samba/pkg/xtime"
"samba/proto"
"samba/util/rdbkey"
"samba/util/routingKey"
"samba/util/util"
"time"
)
// UserOnlineDuration 用户在线时长记录
type UserOnlineDuration struct {
UID int64 `json:"uid"`
// 上线时间
OnlineTime time.Time `json:"online_time"`
// 下线时间
OffLineTime time.Time `json:"offline_time"`
// 在线时长(s)
Duration int64 `json:"duration"`
// 记录时间
RecordTime time.Time `json:"record_time"`
}
func (u *UserOnlineDuration) Flush(srv service.IService) error {
sql, err := util.Struct2InsertSql("user_online_duration", u)
if err != nil {
return err
}
req := proto.NtfClickHouseSql{Sql: sql}
msg := util.MakeMessage(proto.NtfClickHouseSqlId, req, u.UID, 0)
byteData, err := json.Marshal(msg)
if err != nil {
return err
}
err = srv.Publish(util.Direct(servername.ClickHouse), routingKey.ClickHouseKey(u.UID), byteData)
if err != nil {
return err
}
return err
}
var UserOnlineRepo = map[int64]carbon.Carbon{}
func RecordUserOnline(uid int64) {
UserOnlineRepo[uid] = xtime.Now()
}
func RecordUserOffline(uid int64, srv service.IService) {
onlineTime, ok := UserOnlineRepo[uid]
if !ok {
return
}
delete(UserOnlineRepo, uid)
now := xtime.Now()
dur := UserOnlineDuration{
UID: uid,
OnlineTime: onlineTime.StdTime(),
OffLineTime: now.StdTime(),
Duration: onlineTime.DiffInSeconds(now),
RecordTime: now.StdTime(),
}
err := dur.Flush(srv)
if err != nil {
log.Error(fmt.Sprintf("failed to flush user uid=%d online duration %s", dur.UID, err))
}
}
type UserOnlineOp struct {
rdb *redis.Client
}
func NewUserOnlineOp() *UserOnlineOp {
return &UserOnlineOp{rdb: rdbGameLog}
}
func (op *UserOnlineOp) Current() (int64, error) {
return op.rdb.Get(context.TODO(), rdbkey.CurrentOnlineUserKey()).Int64()
}
func (op *UserOnlineOp) SetCurrent(count int64) error {
return op.rdb.Set(context.TODO(), rdbkey.CurrentOnlineUserKey(), count, 0).Err()
}