func (s *server) findNode(msg *proto.ToIslbFindNodeMsg) (interface{}, error) {
	service := msg.Service
	nodes := s.getNodes()

	if msg.SID != "" && msg.UID != "" && msg.MID != "" {
		mkey := proto.MediaInfo{
			DC:  s.dc,
			SID: msg.SID,
			UID: msg.UID,
			MID: msg.MID,
		}.BuildKey()
		log.Infof("find mids by mkey: %s", mkey)
		for _, key := range s.redis.Keys(mkey + "*") {
			log.Infof("got: key => %s", key)
			minfo, err := proto.ParseMediaInfo(key)
			if err != nil {
				log.Warnf("parse media info error: %v", key)
				continue
			}
			for _, node := range nodes {
				if service == node.Service && minfo.NID == node.NID {
					log.Infof("found node by sid=%s & uid=%s & mid=%s : %v", msg.SID, msg.UID, msg.MID, node)
					return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
				}
			}
		}
	}

	// MID/SID Doesn't exist in Redis
	// Find least packed node to return
	nodeID := ""
	minStreamCount := math.MaxInt32
	for _, node := range nodes {
		if service == node.Service {
			// get stream count
			nkey := proto.MediaInfo{
				DC:  s.dc,
				NID: node.NID,
			}.BuildKey()
			streamCount := len(s.redis.Keys(nkey))

			log.Infof("looking up node stream count: [%s] = %v", nkey, streamCount)
			if streamCount <= minStreamCount {
				nodeID = node.NID
				minStreamCount = streamCount
			}
		}
	}
	log.Infof("selecting node: [%s] = %v", nodeID, minStreamCount)
	if node, ok := nodes[nodeID]; ok {
		log.Infof("found best node: %v", node)
		return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
	}

	// TODO: Add a load balancing algorithm.
	for _, node := range nodes {
		if service == node.Service {
			log.Infof("found node: %v", node)
			return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
		}
	}

	return nil, errors.New("service node not found")
}
// Find service nodes by name, such as sfu|avp|sip-gateway|rtmp-gateway
Find service nodes by name, such as sfu|avp|sip-gateway|rtmp-gateway
// Find service nodes by name such as sfu|avp|sip - gateway|rtmp - gateway
func (s *server) findNode(msg *proto.ToIslbFindNodeMsg) (interface{}, error) {
	service := msg.Service
	nodes := s.getNodes()
	if msg.SID != "" && msg.UID != "" && msg.MID != "" {
		mkey := proto.MediaInfo{
			DC:  s.dc,
			SID: msg.SID,
			UID: msg.UID,
			MID: msg.MID,
		}.BuildKey()
		log.Infof("find mids by mkey: %s", mkey)
		for _, key := range s.redis.Keys(mkey + "*") {
			log.Infof("got: key => %s", key)
			minfo, err := proto.ParseMediaInfo(key)
			if err != nil {
				log.Warnf("parse media info error: %v", key)
				continue
			}
			for _, node := range nodes {
				if service == node.Service && minfo.NID == node.NID {
					log.Infof("found node by sid=%s & uid=%s & mid=%s : %v", msg.SID, msg.UID, msg.MID, node)
					return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
				}
			}
		}
	}
	nodeID := ""
	minStreamCount := math.MaxInt32
	for _, node := range nodes {
		if service == node.Service {
			nkey := proto.MediaInfo{
				DC:  s.dc,
				NID: node.NID,
			}.BuildKey()
			streamCount := len(s.redis.Keys(nkey))
			log.Infof("looking up node stream count: [%s] = %v", nkey, streamCount)
			if streamCount <= minStreamCount {
				nodeID = node.NID
				minStreamCount = streamCount
			}
		}
	}
	log.Infof("selecting node: [%s] = %v", nodeID, minStreamCount)
	if node, ok := nodes[nodeID]; ok {
		log.Infof("found best node: %v", node)
		return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
	}
	for _, node := range nodes {
		if service == node.Service {
			log.Infof("found node: %v", node)
			return proto.FromIslbFindNodeMsg{ID: node.NID}, nil
		}
	}
	return nil, errors.New("service node not found")
}
func ( s * server ) findNode ( msg * proto . ToIslbFindNodeMsg ) ( interface { } , error ) { service := msg . Service nodes := s . getNodes ( ) if msg . SID != " " && msg . UID != " " && msg . MID != " " { mkey := proto . MediaInfo { DC : s . dc , SID : msg . SID , UID : msg . UID , MID : msg . MID , } . BuildKey ( ) log . Infof ( " " , mkey ) for _ , key := range s . redis . Keys ( mkey + " " ) { log . Infof ( " " , key ) minfo , err := proto . ParseMediaInfo ( key ) if err != nil { log . Warnf ( " " , key ) continue } for _ , node := range nodes { if service == node . Service && minfo . NID == node . NID { log . Infof ( " " , msg . SID , msg . UID , msg . MID , node ) return proto . FromIslbFindNodeMsg { ID : node . NID } , nil } } } } nodeID := " " minStreamCount := math . MaxInt32 for _ , node := range nodes { if service == node . Service { nkey := proto . MediaInfo { DC : s . dc , NID : node . NID , } . BuildKey ( ) streamCount := len ( s . redis . Keys ( nkey ) ) log . Infof ( " " , nkey , streamCount ) if streamCount <= minStreamCount { nodeID = node . NID minStreamCount = streamCount } } } log . Infof ( " " , nodeID , minStreamCount ) if node , ok := nodes [ nodeID ] ; ok { log . Infof ( " " , node ) return proto . FromIslbFindNodeMsg { ID : node . NID } , nil } for _ , node := range nodes { if service == node . Service { log . Infof ( " " , node ) return proto . FromIslbFindNodeMsg { ID : node . NID } , nil } } return nil , errors . New ( " " ) }
Find service nodes by name, such as sfu|avp|sip-gateway|rtmp-gateway
Find service nodes by name such as sfu|avp|sip - gateway|rtmp - gateway
// MID/SID Doesn't exist in Redis // Find least packed node to return // get stream count // TODO: Add a load balancing algorithm.