This commit is contained in:
aozhiwei 2020-10-27 21:10:44 +08:00
parent 58bfc5043e
commit ddc3ea0925
10 changed files with 289 additions and 28 deletions

View File

@ -1,29 +1,31 @@
package main
import "f5"
import "fmt"
import (
"f5"
)
type App_ struct {
f5.App_
}
var App *App_
var App = new (App_)
func (this *App_) Init() {
f5.App = &this.App_
f5.App.SetPkgName("analyseapi")
f5.App.SetPkgName("statserver")
this.App_.Init()
G.MetaMgr = new(MetaMgr)
G.MetaMgr.Init()
G.MetaMgr.Load()
G.GCListener = new(GCListener)
G.GCListener.Init()
fmt.Println(
G.MetaMgr.GetConf().GetGameHeartbeat()[0],
G.MetaMgr.GetServer(1))
G.MetaMgr = new(MetaMgr).Init()
G.HttpServer = new(f5.HttpServer).Init()
G.GameLog = new(GameLog).Init()
G.StatMgr = new(StatMgr).Init()
G.HttpServer.Start(G.MetaMgr.GetServer(1).GetListenPort());
}
func (this *App_) UnInit() {
G.StatMgr.UnInit()
G.GameLog.UnInit()
G.HttpServer.UnInit()
G.MetaMgr.UnInit()
this.App_.UnInit()
}

View File

@ -0,0 +1,7 @@
package main
const (
IM_UPDATE_SESSION = 100
)
const SESSION_KEY = "f3a6a9a5-217a-4079-ab99-b5d69b8212be"

View File

@ -1,8 +1,14 @@
package main
import (
"f5"
)
type GlobalVar struct {
MetaMgr *MetaMgr
GCListener *GCListener
HttpServer *f5.HttpServer
StatMgr *StatMgr
GameLog *GameLog
}
var G *GlobalVar = &GlobalVar{}

View File

@ -0,0 +1,48 @@
package main
import (
"q5"
"f5"
)
type GameLog struct {
}
func (this *GameLog) Init() *GameLog {
f5.TgLog().SetPolyLog(true)
return this
}
func (this *GameLog) UnInit() {
}
func (this *GameLog) PlayerOnline(remoteAddr string, accountId string, registerTime int64) {
gameId := f5.ExtractGameIdFromAccountId(accountId)
channel := f5.ExtractChannelFromAccountId(accountId)
prop := q5.NewMxoObject()
prop.SetXValue("channel", q5.NewXInt32(channel))
prop.SetXValue("ad_channel", q5.NewXString(""))
prop.SetXValue("account_register_date", q5.NewXString(q5.FormatUnixDateTime(registerTime)))
prop.SetXValue("gameid", q5.NewXInt32(gameId))
f5.TgLog().AddTrackLog(gameId, accountId, remoteAddr, 21, 1, prop.AsXObject())
}
func (this *GameLog) PlayerOffline(remoteAddr string, accountId string, registerTime int64, onlineTime int64) {
gameId := f5.ExtractGameIdFromAccountId(accountId)
channel := f5.ExtractChannelFromAccountId(accountId)
prop := q5.NewMxoObject()
prop.SetXValue("channel", q5.NewXInt32(channel))
prop.SetXValue("ad_channel", q5.NewXString(""))
prop.SetXValue("account_register_date", q5.NewXString(q5.FormatUnixDateTime(registerTime)))
prop.SetXValue("gameid", q5.NewXInt32(gameId))
prop.SetXValue("online_time", q5.NewXString(q5.FormatUnixDateTime(onlineTime)))
prop.SetXValue("online_duration", q5.NewXString(
q5.FormatUnixDateTime(f5.App.NowUnix() - onlineTime)))
f5.TgLog().AddTrackLog(gameId, accountId, remoteAddr, 21, 2, prop.AsXObject())
}

View File

@ -1,4 +1,4 @@
module analyseapi
module statserver
go 1.11

View File

@ -1,11 +1,6 @@
package main
import (
//"f5"
)
func main() {
App = &App_{}
App.Init()
App.Run()
App.UnInit()

View File

@ -1,11 +1,20 @@
compile:
@. /etc/profile
protoc --proto_path=../tools/protobuild --go_out=./mt ../tools/protobuild/mt.proto
@export GOPROXY=https://goproxy.io
@go build -gcflags=all="-N -l" -o ../bin/analyseapi
@go build -gcflags=all="-N -l" -o ../bin/statserver
@echo "compile done"
debug:
@. /etc/profile
protoc --proto_path=../tools/protobuild --go_out=./mt ../tools/protobuild/mt.proto
@export GOPROXY=https://goproxy.io
@go build -gcflags=all="-N -l" -ldflags "-X q5.optDebug=1" -o ../bin/statserver
@echo "compile done"
clean:
@rm -f ../bin/analyseapi
@rm -f ../bin/statserver
@echo "clean done"

View File

@ -2,29 +2,39 @@ package main
import "f5"
import "mt"
//import "fmt"
//import "reflect"
const (
MT_SERVER_INFO = 0
MT_MAX
MT_CONF = iota
MT_MAX = iota
)
type MetaMgr struct {
f5.MetaMgr
}
func (this *MetaMgr) Init() {
func (this *MetaMgr) Init() *MetaMgr {
this.MetaMgr.Init()
configDir := "../config/"
if !f5.IsOnlineEnv() {
configDir = "/var/data/conf_test/statserver/"
}
metaClasses := &[]f5.MetaClass{
f5.MetaClass{
PrimKey: "InstanceId",
FileName: "/var/data/conf_test/mail/mail.cluster.json",
FileName: configDir + "statserver.cluster.json",
Idx: MT_SERVER_INFO,
RawMeta: (*mt.ServerInfoMetas)(nil),
WrapMeta: (*MtwServerInfo)(nil)},
f5.MetaClass{
FileName: configDir + "statserver.json",
Idx: MT_CONF,
RawMeta: (*mt.ConfMetas)(nil),
WrapMeta: (*MtwConf)(nil)},
}
this.MetaMgr.RegisterMetaClasses(metaClasses)
this.Load()
return this
}
func (this *MetaMgr) UnInit() {
@ -40,8 +50,8 @@ func (this *MetaMgr) GetServer(instance_id int32) *MtwServerInfo {
}
}
func (this *MetaMgr) GetServerList() []*MtwServerInfo {
v, ok := this.MetaMgr.GetMetaList(MT_SERVER_INFO).([]*MtwServerInfo)
func (this *MetaMgr) GetConf() *MtwConf {
v, ok := this.MetaMgr.GetMetaById(MT_CONF, 1).(*MtwConf)
if ok {
return v
} else {

View File

@ -5,3 +5,23 @@ import "mt"
type MtwServerInfo struct {
*mt.ServerInfo
}
type MtwConf struct {
*mt.Conf
hearbeatHash map[int32]int32
}
func (this *MtwConf) Init() {
this.hearbeatHash = make(map[int32]int32)
for _, v := range this.GetGameHeartbeat() {
this.hearbeatHash[v.GetGameid()] = v.GetHeartbeat()
}
}
func (this *MtwConf) GetHeartBeatTimeout(gameid int32) int32 {
if time, ok := this.hearbeatHash[gameid]; ok {
return (time + this.GetNetDelay()) * 1000
} else {
return (60 * 5 + this.GetNetDelay()) * 1000
}
}

View File

@ -0,0 +1,164 @@
package main
import (
"net/http"
"sync"
"fmt"
"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.Param3.SetInt32(registerTime)
},
func (params *q5.XParams) {
this.playerOffline(remoteAddr, accountId, registerTime)
})
this.onlineUserHash[accountId] = userInfo
this.incGameChannelOnline(gameId, channel)
G.GameLog.PlayerOnline(remoteAddr, accountId, int64(registerTime))
}
func (this *StatMgr) playerOffline(remoteAddr string, accountId string, registerTime int32) {
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), 0)
}
func (this *StatMgr) __statUpdateSession(w http.ResponseWriter,r *http.Request) {
f5.App.AddIMMsg(IM_UPDATE_SESSION, new(q5.XParams).Init(func (params *q5.XParams){
params.Sender.SetString(q5.Request(r, "account_id").GetString())
params.Param1.SetString(q5.Request(r, "session_id").GetString())
params.Param2.SetString(q5.GetRequestRemoteAddr(r))
params.Param3.SetString(q5.Request(r, "_try_count").GetString())
}))
w.Write([]byte(`{"errcode":0, "errmsg":""}`))
}
func (this *StatMgr) __statGetRealTimeOnline(w http.ResponseWriter,r *http.Request) {
onlineNum := G.StatMgr.GetRealTimeOnline(
q5.Request(r, "game_id").GetInt32(),
q5.Request(r, "channel").GetInt32())
w.Write([]byte(fmt.Sprintf(`{"errcode":0, "errmsg":"", "num":%d}`, onlineNum)))
}