strategy_leastping.go 1.4 KB

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