92 lines
2.1 KiB
Go
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()
|
|
}
|