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