goserver_sync/mmo/balancesrv/clientsessionhandler.go

102 lines
2.9 KiB
Go

package main
import (
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/mmo/protocol"
"mongo.games.com/goserver/srvlib"
)
var (
SessionHandlerClientBalanceName = "handler-client-balance"
SessionHandlerClientBalanceMgr = &SessionHandlerClientBalance{gates: make(map[int32]*gateService)}
)
type gateService struct {
load int
active bool
}
type SessionHandlerClientBalance struct {
netlib.BasicSessionHandler
gates map[int32]*gateService
}
func (sfcb SessionHandlerClientBalance) GetName() string {
return SessionHandlerClientBalanceName
}
func (sfcb *SessionHandlerClientBalance) GetInterestOps() uint {
return 1 << netlib.InterestOps_Opened
}
func (sfcb *SessionHandlerClientBalance) OnSessionOpened(s *netlib.Session) {
logger.Logger.Trace("SessionHandlerClientBalance.OnSessionOpened")
services := srvlib.ServiceMgr.GetServices(srvlib.ClientServiceType)
if services != nil {
/*清理掉线的gate*/
for k, _ := range sfcb.gates {
if _, has := services[k]; !has {
logger.Logger.Trace("gate leave: ", k)
delete(sfcb.gates, k)
}
}
/*补充新上线的gate*/
for k, v := range services {
if _, has := sfcb.gates[k]; !has {
sfcb.gates[k] = &gateService{active: true}
logger.Logger.Trace("new gate come in: ", k, v)
}
}
}
/*查找最小负载的gate*/
var minsrvid int32
var min = 100000
for k, v := range sfcb.gates {
if v.active && v.load < min {
minsrvid = k
min = v.load
}
}
pack := &protocol.SCGateInfo{}
if mls, has := services[minsrvid]; has {
pack.SrvType = mls.GetSrvType()
pack.SrvId = mls.GetSrvId()
pack.AuthKey = mls.GetAuthKey()
pack.Ip = mls.GetOuterIp()
pack.Port = mls.GetPort()
}
s.Send(int(protocol.MmoPacketID_PACKET_SC_GATEINFO), pack)
logger.Logger.Trace(pack)
s.Close()
}
func init() {
netlib.RegisteSessionHandlerCreator(SessionHandlerClientBalanceName, func() netlib.SessionHandler {
return SessionHandlerClientBalanceMgr
})
netlib.RegisterFactory(int(protocol.MmoPacketID_PACKET_GB_CUR_LOAD), netlib.PacketFactoryWrapper(func() interface{} {
return &protocol.ServerLoad{}
}))
netlib.RegisterHandler(int(protocol.MmoPacketID_PACKET_GB_CUR_LOAD), netlib.HandlerWrapper(func(s *netlib.Session, packetid int, pack interface{}) error {
if sr, ok := pack.(*protocol.ServerLoad); ok {
srvid := sr.GetSrvId()
if v, has := SessionHandlerClientBalanceMgr.gates[srvid]; has {
v.load = int(sr.GetCurLoad())
logger.Logger.Trace("receive gate load info 1, sid=", srvid, " load=", v.load)
} else {
services := srvlib.ServiceMgr.GetServices(srvlib.ClientServiceType)
if _, has := services[srvid]; has {
SessionHandlerClientBalanceMgr.gates[srvid] = &gateService{active: true, load: int(sr.GetCurLoad())}
logger.Logger.Trace("receive gate load info 2, sid=", srvid, " load=", sr.GetCurLoad())
}
}
}
return nil
}))
}