github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/router/strategy_leastping.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package router 5 6 import ( 7 "context" 8 9 core "github.com/v2fly/v2ray-core/v5" 10 "github.com/v2fly/v2ray-core/v5/app/observatory" 11 "github.com/v2fly/v2ray-core/v5/common" 12 "github.com/v2fly/v2ray-core/v5/features" 13 "github.com/v2fly/v2ray-core/v5/features/extension" 14 ) 15 16 type LeastPingStrategy struct { 17 ctx context.Context 18 observatory extension.Observatory 19 20 config *StrategyLeastPingConfig 21 } 22 23 func (l *LeastPingStrategy) GetPrincipleTarget(strings []string) []string { 24 return []string{l.PickOutbound(strings)} 25 } 26 27 func (l *LeastPingStrategy) InjectContext(ctx context.Context) { 28 l.ctx = ctx 29 } 30 31 func (l *LeastPingStrategy) PickOutbound(strings []string) string { 32 if l.observatory == nil { 33 common.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error { 34 if l.config.ObserverTag != "" { 35 l.observatory = common.Must2(observatory.(features.TaggedFeatures).GetFeaturesByTag(l.config.ObserverTag)).(extension.Observatory) 36 } else { 37 l.observatory = observatory 38 } 39 return nil 40 })) 41 } 42 43 observeReport, err := l.observatory.GetObservation(l.ctx) 44 if err != nil { 45 newError("cannot get observe report").Base(err).WriteToLog() 46 return "" 47 } 48 outboundsList := outboundList(strings) 49 if result, ok := observeReport.(*observatory.ObservationResult); ok { 50 status := result.Status 51 leastPing := int64(99999999) 52 selectedOutboundName := "" 53 for _, v := range status { 54 if outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing { 55 selectedOutboundName = v.OutboundTag 56 leastPing = v.Delay 57 } 58 } 59 return selectedOutboundName 60 } 61 62 // No way to understand observeReport 63 return "" 64 } 65 66 type outboundList []string 67 68 func (o outboundList) contains(name string) bool { 69 for _, v := range o { 70 if v == name { 71 return true 72 } 73 } 74 return false 75 } 76 77 func init() { 78 common.Must(common.RegisterConfig((*StrategyLeastPingConfig)(nil), nil)) 79 }