github.com/xraypb/Xray-core@v1.8.1/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 }