github.com/xraypb/xray-core@v1.6.6/app/router/strategy_leastping.go (about)

     1  package router
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/xraypb/xray-core/app/observatory"
     7  	"github.com/xraypb/xray-core/common"
     8  	"github.com/xraypb/xray-core/core"
     9  	"github.com/xraypb/xray-core/features/extension"
    10  )
    11  
    12  type LeastPingStrategy struct {
    13  	ctx         context.Context
    14  	observatory extension.Observatory
    15  }
    16  
    17  func (l *LeastPingStrategy) InjectContext(ctx context.Context) {
    18  	l.ctx = ctx
    19  }
    20  
    21  func (l *LeastPingStrategy) PickOutbound(strings []string) string {
    22  	if l.observatory == nil {
    23  		common.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error {
    24  			l.observatory = observatory
    25  			return nil
    26  		}))
    27  	}
    28  
    29  	observeReport, err := l.observatory.GetObservation(l.ctx)
    30  	if err != nil {
    31  		newError("cannot get observe report").Base(err).WriteToLog()
    32  		return ""
    33  	}
    34  	outboundsList := outboundList(strings)
    35  	if result, ok := observeReport.(*observatory.ObservationResult); ok {
    36  		status := result.Status
    37  		leastPing := int64(99999999)
    38  		selectedOutboundName := ""
    39  		for _, v := range status {
    40  			if outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing {
    41  				selectedOutboundName = v.OutboundTag
    42  				leastPing = v.Delay
    43  			}
    44  		}
    45  		return selectedOutboundName
    46  	}
    47  
    48  	// No way to understand observeReport
    49  	return ""
    50  }
    51  
    52  type outboundList []string
    53  
    54  func (o outboundList) contains(name string) bool {
    55  	for _, v := range o {
    56  		if v == name {
    57  			return true
    58  		}
    59  	}
    60  	return false
    61  }