238 lines
6.0 KiB
Go
238 lines
6.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
|
||
}
|
||
|
||
// 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)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|