goserver_sync/srvlib/serversessionmgr.go

215 lines
5.0 KiB
Go

package srvlib
import (
"strings"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/srvlib/protocol"
)
/*
服务器信息注册,单个服务器可能包含多个子服务端口
*/
var (
SessionAttributeServerInfo = &ServerSessionMgr{}
ServerSessionMgrSington = &ServerSessionMgr{sessions: make(map[int]map[int]map[int]*netlib.Session)}
)
type ServerSessionRegisteListener interface {
OnRegiste(*netlib.Session)
OnUnregiste(*netlib.Session)
}
type ServerSessionMgr struct {
sessions map[int]map[int]map[int]*netlib.Session //keys=>areaid:type:id
listeners []ServerSessionRegisteListener
}
func (ssm *ServerSessionMgr) AddListener(l ServerSessionRegisteListener) ServerSessionRegisteListener {
ssm.listeners = append(ssm.listeners, l)
return l
}
func (ssm *ServerSessionMgr) RegisteSession(s *netlib.Session) bool {
attr := s.GetAttribute(SessionAttributeServerInfo)
if attr == nil {
logger.Logger.Warnf("服务器注册信息为空")
return false
}
srvInfo, ok := attr.(*protocol.SSSrvRegiste)
if !ok || srvInfo == nil {
logger.Logger.Warnf("服务器注册信息错误")
return false
}
areaId := int(srvInfo.GetAreaId())
srvType := int(srvInfo.GetType())
srvId := int(srvInfo.GetId())
if _, ok := ssm.sessions[areaId]; !ok {
ssm.sessions[areaId] = make(map[int]map[int]*netlib.Session)
}
if _, ok := ssm.sessions[areaId][srvType]; !ok {
ssm.sessions[areaId][srvType] = make(map[int]*netlib.Session)
}
session, has := ssm.sessions[areaId][srvType][srvId]
if has && session != nil && session != s {
logger.Logger.Warnf("删除旧服务器注册: %v", srvInfo)
ssm.UnregisteSession(session)
}
logger.Logger.Infof("服务器注册成功:%v", srvInfo)
ssm.sessions[areaId][srvType][srvId] = s
if len(ssm.listeners) != 0 {
for _, l := range ssm.listeners {
l.OnRegiste(s)
}
}
return true
}
// UnregisteSession 服务器关闭
// 需要支持幂等性
func (ssm *ServerSessionMgr) UnregisteSession(s *netlib.Session) bool {
attr := s.GetAttribute(SessionAttributeServerInfo)
if attr == nil {
return false
}
srvInfo, ok := attr.(*protocol.SSSrvRegiste)
if !ok || srvInfo == nil {
return false
}
logger.Logger.Tracef("尝试删除服务器注册:%v", srvInfo)
areaId := int(srvInfo.GetAreaId())
srvType := int(srvInfo.GetType())
srvId := int(srvInfo.GetId())
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
if conn, exist := b[srvId]; exist && s == conn {
logger.Logger.Infof("删除服务器注册成功 %v", srvInfo)
delete(b, srvId)
if len(ssm.listeners) != 0 {
for _, l := range ssm.listeners {
l.OnUnregiste(s)
}
}
return true
} else {
logger.Logger.Tracef("服务器注册信息已经删除")
}
}
}
return false
}
func (ssm *ServerSessionMgr) GetSession(areaId, srvType, srvId int) *netlib.Session {
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
if c, exist := b[srvId]; exist {
return c
}
}
}
return nil
}
func (ssm *ServerSessionMgr) GetSessions(areaId, srvType int) (sessions []*netlib.Session) {
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
for _, s := range b {
sessions = append(sessions, s)
}
}
}
return
}
func (ssm *ServerSessionMgr) GetServerId(areaId, srvType int) int {
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
for sid, _ := range b {
return sid
}
}
}
return -1
}
func (ssm *ServerSessionMgr) GetServerIdByMaxData(areaId, srvType int) int {
var bestSid int = -1
var data string
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
for sid, s := range b {
if srvInfo, ok := s.GetAttribute(SessionAttributeServerInfo).(*protocol.SSSrvRegiste); ok && srvInfo != nil {
if strings.Compare(data, srvInfo.GetData()) <= 0 {
data = srvInfo.GetData()
bestSid = sid
}
}
}
}
}
return bestSid
}
func (ssm *ServerSessionMgr) GetServerIds(areaId, srvType int) (ids []int) {
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
for sid, _ := range b {
ids = append(ids, sid)
}
}
}
return
}
func (ssm *ServerSessionMgr) Broadcast(packetid int, pack interface{}, areaId, srvType int) {
if areaId >= 0 {
if srvType >= 0 {
if a, exist := ssm.sessions[areaId]; exist {
if b, exist := a[srvType]; exist {
for _, s := range b {
s.Send(packetid, pack)
}
}
}
} else {
if a, exist := ssm.sessions[areaId]; exist {
for _, b := range a {
for _, s := range b {
s.Send(packetid, pack)
}
}
}
}
} else {
if srvType >= 0 {
for _, a := range ssm.sessions {
if b, exist := a[srvType]; exist {
for _, s := range b {
s.Send(packetid, pack)
}
}
}
} else {
for _, a := range ssm.sessions {
for _, b := range a {
for _, s := range b {
s.Send(packetid, pack)
}
}
}
}
}
}