2021-01-07 11:07:07 +08:00

165 lines
4.6 KiB
Go

package main
import (
"sync"
"q5"
"f5"
)
type OnlineUser struct {
accountId string
sessionId string
timer *q5.TimerList
}
type StatMgr struct {
onlineUserHash map[string]*OnlineUser
onlineNumHash map[int64]int32
onlineNumMutex sync.RWMutex
}
func (this *StatMgr) Init() *StatMgr {
this.onlineUserHash = make(map[string]*OnlineUser)
this.onlineNumHash = make(map[int64]int32)
f5.App.RegisterIMMsgHandle(IM_UPDATE_SESSION, this._IMUpdateSession)
G.HttpServer.RegisterHandle("Stat", "updateSession", this._statUpdateSession)
G.HttpServer.RegisterHandle("Stat", "getRealTimeOnline", this._statGetRealTimeOnline)
return this
}
func (this *StatMgr) UnInit() {
}
func (this *StatMgr) _IMUpdateSession(msgId int16, params* q5.XParams) {
/*if q5.Debug() {
f5.SysLog().Info("StatMgr._IMUpdateSession")
}*/
accountId := params.Sender.GetString()
sessionId := params.Param1.GetString()
remoteAddr := params.Param2.GetString()
tryCount := params.Param3.GetInt32()
if tryCount > 0 {
return
}
instanceId := this.allocInstanceId(accountId)
if instanceId == f5.App.GetInstanceId() {
userInfo, ok := this.onlineUserHash[accountId]
if !ok {
this.playerOnline(remoteAddr, accountId, sessionId)
} else {
if userInfo.sessionId != sessionId {
if !f5.IsValidSessionId(accountId, sessionId, SESSION_KEY) {
f5.SysLog().Warning("invalid sessionid1 %s %s %s",
remoteAddr,
accountId,
sessionId)
return
}
userInfo.sessionId = sessionId
}
gameId := f5.ExtractGameIdFromAccountId(accountId)
f5.Timer().ModifyTimer(
userInfo.timer,
G.MetaMgr.GetConf().GetHeartBeatTimeout(gameId))
}
}
}
func (this *StatMgr) GetRealTimeOnline(gameId int32, channel int32) int32 {
this.onlineNumMutex.Lock()
defer this.onlineNumMutex.Unlock()
if v, ok := this.onlineNumHash[q5.MkInt64(gameId, channel)]; ok {
return v
} else {
return 0
}
}
func (this *StatMgr) incGameChannelOnline(gameId int32, channel int32) {
this.onlineNumMutex.Lock()
defer this.onlineNumMutex.Unlock()
this.onlineNumHash[q5.MkInt64(gameId, channel)] += 1
this.onlineNumHash[q5.MkInt64(gameId, 0)] += 1
}
func (this *StatMgr) decGameChannelOnline(gameId int32, channel int32) {
this.onlineNumMutex.Lock()
defer this.onlineNumMutex.Unlock()
this.onlineNumHash[q5.MkInt64(gameId, channel)] -= 1
this.onlineNumHash[q5.MkInt64(gameId, 0)] -= 1
}
func (this *StatMgr) allocInstanceId(accountId string) uint32 {
return 1
//return q5.Crc32(accountId)
}
func (this *StatMgr) playerOnline(remoteAddr string, accountId string, sessionId string) {
if q5.Debug() {
f5.SysLog().Info("playerOnline %s %s %s",
remoteAddr,
accountId,
sessionId)
}
if !f5.IsValidSessionId(accountId, sessionId, SESSION_KEY) {
f5.SysLog().Warning("invalid sessionid2 %s %s %s",
remoteAddr,
accountId,
sessionId)
return
}
gameId := f5.ExtractGameIdFromAccountId(accountId)
channel := f5.ExtractChannelFromAccountId(accountId)
registerTime := f5.ExtractRegisterTimeFromSessionId(sessionId)
userInfo := new(OnlineUser)
userInfo.timer = f5.Timer().AddDeadLineTimer(
G.MetaMgr.GetConf().GetHeartBeatTimeout(gameId),
func (params *q5.XParams) {
params.Sender.SetString("")
params.Param1.SetString(accountId)
params.Param2.SetInt64(f5.App.NowUnix())
params.Param3.SetInt64(registerTime)
},
func (params *q5.XParams) {
this.playerOffline(remoteAddr, accountId, registerTime, params.Param2.GetInt64())
})
this.onlineUserHash[accountId] = userInfo
this.incGameChannelOnline(gameId, channel)
G.GameLog.PlayerOnline(remoteAddr, accountId, int64(registerTime))
}
func (this *StatMgr) playerOffline(remoteAddr string, accountId string,
registerTime int64, online_time int64) {
if q5.Debug() {
f5.SysLog().Info("playerOffline %s %s",
remoteAddr,
accountId)
}
gameId := f5.ExtractGameIdFromAccountId(accountId)
channel := f5.ExtractChannelFromAccountId(accountId)
delete(this.onlineUserHash, accountId)
this.decGameChannelOnline(gameId, channel)
G.GameLog.PlayerOffline(remoteAddr, accountId, int64(registerTime), online_time)
}
func (this *StatMgr) _statUpdateSession(c *f5.Context) {
f5.App.AddIMMsg(IM_UPDATE_SESSION, new(q5.XParams).Init(func (params *q5.XParams){
params.Sender.SetString(c.Request("account_id").GetString())
params.Param1.SetString(c.Request("session_id").GetString())
params.Param2.SetString(c.GetRemoteAddr())
params.Param3.SetString(c.Request("_try_count").GetString())
}))
c.ResponseOk();
}
func (this *StatMgr) _statGetRealTimeOnline(c *f5.Context) {
onlineNum := G.StatMgr.GetRealTimeOnline(
c.Request("game_id").GetInt32(),
c.Request("channel").GetInt32())
c.ResponseInt32Ok("num", onlineNum)
}