165 lines
4.6 KiB
Go
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)
|
|
}
|