package srvlib import ( "os" "strconv" "strings" "time" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/srvlib/protocol" ) var ( SessionAttributeServiceInfo = &serviceMgr{} SessionAttributeServiceFlag = &serviceMgr{} ServiceMgr = &serviceMgr{servicesPool: make(map[int32]map[int32]*protocol.ServiceInfo)} ) type ServiceRegisteListener interface { OnRegiste([]*protocol.ServiceInfo) OnUnregiste(*protocol.ServiceInfo) } type serviceMgr struct { servicesPool map[int32]map[int32]*protocol.ServiceInfo // srvType:srvId:ServiceInfo listeners []ServiceRegisteListener } func (this *serviceMgr) AddListener(l ServiceRegisteListener) ServiceRegisteListener { this.listeners = append(this.listeners, l) return l } func (this *serviceMgr) RegisteService(s *netlib.Session, services []*protocol.ServiceInfo) { if this == nil || s == nil || len(services) == 0 { return } // 根据对方提供的服务信息获取对方应该和那些其它服务建立连接,然后让其它服务连接这个刚注册的服务(service) s.SetAttribute(SessionAttributeServiceInfo, services) // 保存监听服务配置 for _, service := range services { srvid := service.GetSrvId() srvtype := service.GetSrvType() if _, has := this.servicesPool[srvtype]; !has { this.servicesPool[srvtype] = make(map[int32]*protocol.ServiceInfo) } if _, exist := this.servicesPool[srvtype][srvid]; !exist { this.servicesPool[srvtype][srvid] = service logger.Logger.Infof("服务注册:%v", service) pack := &protocol.SSServiceInfo{} pack.Service = service sessiontypes := GetCareSessionsByService(service.GetSrvType()) areaId := service.GetAreaId() for _, v1 := range sessiontypes { // 地区和服务类型 ServerSessionMgrSington.Broadcast(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_INFO), pack, int(areaId), int(v1)) logger.Logger.Infof("广播服务信息:%v ==> AreaId:%v ServerType:%v", service.GetSrvName(), areaId, v1) } //if len(this.listeners) != 0 { // for _, l := range this.listeners { // l.OnRegiste(services) // } //} } } } // UnregisteService 广播服务关闭 func (this *serviceMgr) UnregisteService(service *protocol.ServiceInfo) { if this == nil || service == nil { return } srvid := service.GetSrvId() srvtype := service.GetSrvType() if v, has := this.servicesPool[srvtype]; has { if ss, exist := v[srvid]; exist && ss == service { delete(v, srvid) logger.Logger.Infof("服务关闭:%v", service) pack := &protocol.SSServiceShut{} pack.Service = service sessiontypes := GetCareSessionsByService(service.GetSrvType()) areaId := service.GetAreaId() for _, v1 := range sessiontypes { ServerSessionMgrSington.Broadcast(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_SHUT), pack, int(areaId), int(v1)) logger.Logger.Infof("广播服务关闭:%v ==> AreaId:%v ServerType:%v", service.GetSrvName(), areaId, v1) } //if len(this.listeners) != 0 { // for _, l := range this.listeners { // l.OnUnregiste(service) // } //} } } } // OnRegiste 服务器注册 func (this *serviceMgr) OnRegiste(s *netlib.Session) { if this == nil || s == nil { return } if s.GetAttribute(SessionAttributeServiceFlag) == nil { return } // 查看已存在的服务信息列表找当前服务器需要建立连接的服务,然后建立连接 attr := s.GetAttribute(SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*protocol.SSSrvRegiste); ok && srvInfo != nil { services := GetCareServicesBySession(srvInfo.GetType()) for _, v1 := range services { if v2, has := this.servicesPool[v1]; has { for _, v3 := range v2 { func(si *protocol.ServiceInfo, sInfo *protocol.SSSrvRegiste) { pack := &protocol.SSServiceInfo{} pack.Service = si s.Send(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_INFO), pack) logger.Logger.Infof("建立连接: client(%v)==>server(%v)", srvInfo.GetName(), si.GetSrvName()) }(v3, srvInfo) } } } } } } func (this *serviceMgr) OnUnregiste(s *netlib.Session) { } func (this *serviceMgr) ClearServiceBySession(s *netlib.Session) { attr := s.GetAttribute(SessionAttributeServiceInfo) if attr != nil { if services, ok := attr.([]*protocol.ServiceInfo); ok { for _, service := range services { this.UnregisteService(service) } } s.RemoveAttribute(SessionAttributeServiceInfo) } } func (this *serviceMgr) ReportService(s *netlib.Session) { acceptors := netlib.GetAcceptors() cnt := len(acceptors) if cnt > 0 { pack := &protocol.SSServiceRegiste{ Services: make([]*protocol.ServiceInfo, 0, cnt), } for _, v := range acceptors { addr := v.Addr() if addr == nil { continue } network := addr.Network() s := addr.String() ipAndPort := strings.Split(s, ":") if len(ipAndPort) < 2 { continue } port, err := strconv.Atoi(ipAndPort[len(ipAndPort)-1]) if err != nil { continue } sc := v.GetSessionConfig() si := &protocol.ServiceInfo{ AreaId: int32(sc.AreaId), SrvId: int32(sc.Id), SrvType: int32(sc.Type), SrvPID: int32(os.Getpid()), SrvName: sc.Name, NetworkType: network, Ip: sc.Ip, Port: int32(port), WriteTimeOut: int32(sc.WriteTimeout / time.Second), ReadTimeOut: int32(sc.ReadTimeout / time.Second), IdleTimeOut: int32(sc.IdleTimeout / time.Second), MaxDone: int32(sc.MaxDone), MaxPend: int32(sc.MaxPend), MaxPacket: int32(sc.MaxPacket), RcvBuff: int32(sc.RcvBuff), SndBuff: int32(sc.SndBuff), SoLinger: int32(sc.SoLinger), KeepAlive: sc.KeepAlive, NoDelay: sc.NoDelay, IsAutoReconn: sc.IsAutoReconn, IsInnerLink: sc.IsInnerLink, SupportFragment: sc.SupportFragment, AllowMultiConn: sc.AllowMultiConn, AuthKey: sc.AuthKey, EncoderName: sc.EncoderName, DecoderName: sc.DecoderName, FilterChain: sc.FilterChain, HandlerChain: sc.HandlerChain, Protocol: sc.Protocol, Path: sc.Path, OuterIp: sc.OuterIp, } pack.Services = append(pack.Services, si) } s.Send(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_REGISTE), pack) logger.Logger.Infof("目标服务器:%v 发送服务信息:%v", s.GetSessionConfig().Name, pack) } } func (this *serviceMgr) GetServices(srvtype int32) map[int32]*protocol.ServiceInfo { if v, has := this.servicesPool[srvtype]; has { return v } return nil } func (this *serviceMgr) GetService(srvtype, srvid int32) *protocol.ServiceInfo { if v, has := this.servicesPool[srvtype]; has { if vv, has := v[srvid]; has { return vv } } return nil } func init() { // service registe netlib.RegisterFactory(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_REGISTE), netlib.PacketFactoryWrapper(func() interface{} { return &protocol.SSServiceRegiste{} })) netlib.RegisterHandler(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_REGISTE), netlib.HandlerWrapper(func(s *netlib.Session, packetid int, pack interface{}) error { if sr, ok := pack.(*protocol.SSServiceRegiste); ok { ServiceMgr.RegisteService(s, sr.GetServices()) } return nil })) // service info netlib.RegisterFactory(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_INFO), netlib.PacketFactoryWrapper(func() interface{} { return &protocol.SSServiceInfo{} })) netlib.RegisterHandler(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_INFO), netlib.HandlerWrapper(func(s *netlib.Session, packetid int, pack interface{}) error { if sr, ok := pack.(*protocol.SSServiceInfo); ok { service := sr.GetService() if service != nil { sc := &netlib.SessionConfig{ Id: int(service.GetSrvId()), Type: int(service.GetSrvType()), AreaId: int(service.GetAreaId()), Name: service.GetSrvName(), Ip: service.GetIp(), OuterIp: service.GetOuterIp(), Port: int(service.GetPort()), WriteTimeout: time.Duration(service.GetWriteTimeOut()), ReadTimeout: time.Duration(service.GetReadTimeOut()), IdleTimeout: time.Duration(service.GetIdleTimeOut()), MaxDone: int(service.GetMaxDone()), MaxPend: int(service.GetMaxPend()), MaxPacket: int(service.GetMaxPacket()), RcvBuff: int(service.GetRcvBuff()), SndBuff: int(service.GetSndBuff()), IsClient: true, IsAutoReconn: true, AuthKey: service.GetAuthKey(), SoLinger: int(service.GetSoLinger()), KeepAlive: service.GetKeepAlive(), NoDelay: service.GetNoDelay(), IsInnerLink: service.GetIsInnerLink(), SupportFragment: service.GetSupportFragment(), AllowMultiConn: service.GetAllowMultiConn(), EncoderName: service.GetEncoderName(), DecoderName: service.GetDecoderName(), FilterChain: service.GetFilterChain(), HandlerChain: service.GetHandlerChain(), Protocol: service.GetProtocol(), Path: service.GetPath(), } if !sc.AllowMultiConn && netlib.ConnectorMgr.IsConnecting(sc) { logger.Logger.Warnf("%v:%v %v:%v had connected, not allow multiple connects", sc.Id, sc.Name, sc.Ip, sc.Port) return nil } sc.Init() err := netlib.Connect(sc) if err != nil { logger.Logger.Warn("connect server failed err:", err) } } } return nil })) // service shutdown netlib.RegisterFactory(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_SHUT), netlib.PacketFactoryWrapper(func() interface{} { return &protocol.SSServiceShut{} })) netlib.RegisterHandler(int(protocol.SrvlibPacketID_PACKET_SS_SERVICE_SHUT), netlib.HandlerWrapper(func(s *netlib.Session, packetid int, pack interface{}) error { if sr, ok := pack.(*protocol.SSServiceShut); ok { service := sr.GetService() if service != nil { netlib.ShutConnector(service.GetIp(), int(service.GetPort())) } } return nil })) ServerSessionMgrSington.AddListener(ServiceMgr) }