goserver_sync/srvlib/serversessionmgr.go

238 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
// AddListener 添加一个服务器会话注册监听器
func (ssm *ServerSessionMgr) AddListener(l ServerSessionRegisteListener) ServerSessionRegisteListener {
ssm.listeners = append(ssm.listeners, l)
return l
}
// RegisteSession 注册一个新的服务器会话
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.Infof("删除旧服务器注册: %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.Infof("尝试删除服务器注册:%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.Infof("服务器注册信息已经删除")
return false
}
}
}
logger.Logger.Infof("服务器注册信息没找到:%v", srvInfo)
return false
}
// GetSession 根据区域ID、服务器类型和服务器ID获取会话
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
}
// GetSessions 获取指定区域和服务器类型的所有会话
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
}
// GetServerId 获取指定区域和服务器类型的第一个服务器ID
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
}
// GetServerIdByMaxData 根据最大数据获取指定区域和服务器类型的服务器ID
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
}
// GetServerIds 获取指定区域和服务器类型的所有服务器ID
// 参数:
// - areaId: 区域ID
// - srvType: 服务器类型
//
// 返回:
// - ids: 包含所有匹配服务器ID的切片
func (ssm *ServerSessionMgr) GetServerIds(areaId, srvType int) (ids []int) {
// 检查指定区域是否存在
if a, exist := ssm.sessions[areaId]; exist {
// 检查指定服务器类型是否存在
if b, exist := a[srvType]; exist {
// 遍历所有匹配的服务器收集它们的ID
for sid := range b {
ids = append(ids, sid)
}
}
}
return
}
// Broadcast 向指定区域和服务器类型广播消息
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)
}
}
}
}
}
}