Skip to content

Commit 66d7196

Browse files
mapleafgoclaude
andcommitted
feat(api): 测速 API 重构,直接调用 urltest.URLTest 支持自定义超时
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 304e34b commit 66d7196

5 files changed

Lines changed: 48 additions & 8 deletions

File tree

cmd/lib/exports.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ func CoreSelectProxy(group, tag *C.char) *C.char {
8282
}
8383

8484
//export CoreTestDelay
85-
func CoreTestDelay(name *C.char) *C.char {
86-
return resultJSON(api.TestDelay(goString(name)))
85+
func CoreTestDelay(name *C.char, timeoutMs C.int) *C.char {
86+
delay := api.TestDelay(goString(name), int32(timeoutMs))
87+
data, _ := json.Marshal(map[string]int32{"delay": delay})
88+
return cString(string(data))
8789
}
8890

8991
//export CoreSetMode

core/handler.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,19 @@ func (h *ClientHandler) GetCachedConnectionsJSON() string {
130130
return string(data)
131131
}
132132

133+
// UpdateDelay updates the cached delay for a specific proxy tag.
134+
func (h *ClientHandler) UpdateDelay(tag string, delay int32) {
135+
h.mu.Lock()
136+
defer h.mu.Unlock()
137+
for i := range h.cachedGroups {
138+
for j := range h.cachedGroups[i].Items {
139+
if h.cachedGroups[i].Items[j].Tag == tag {
140+
h.cachedGroups[i].Items[j].Delay = delay
141+
}
142+
}
143+
}
144+
}
145+
133146
// Connected is called when the command client connects to the server.
134147
func (h *ClientHandler) Connected() {
135148
h.emit(EventConnected, map[string]bool{"connected": true})

core/service.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package core
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"log/slog"
@@ -12,6 +13,7 @@ import (
1213
"sync"
1314
"time"
1415

16+
"github.com/sagernet/sing-box/common/urltest"
1517
"github.com/sagernet/sing-box/experimental/libbox"
1618
_ "github.com/sagernet/sing-box/include" // register all protocols
1719

@@ -548,9 +550,29 @@ func (s *Service) SelectOutbound(groupTag, outboundTag string) error {
548550
})
549551
}
550552

551-
// URLTest runs a URL test for the given outbound tag.
552-
func (s *Service) URLTest(outboundTag string) error {
553-
return s.withClient(func(c *libbox.CommandClient) error { return c.URLTest(outboundTag) })
553+
// URLTest tests outbound latency via urltest.URLTest.
554+
// Returns delay in milliseconds, -1 on error or timeout.
555+
func (s *Service) URLTest(outboundTag string, timeoutMs int32) int32 {
556+
inst := s.commandServer.Instance()
557+
if inst == nil {
558+
return -1
559+
}
560+
outbound, ok := inst.Box().Outbound().Outbound(outboundTag)
561+
if !ok {
562+
return -1
563+
}
564+
ctx, cancel := context.WithTimeout(context.Background(),
565+
time.Duration(timeoutMs)*time.Millisecond)
566+
defer cancel()
567+
568+
delay, err := urltest.URLTest(ctx, "", outbound)
569+
if err != nil {
570+
return -1
571+
}
572+
if s.handler != nil {
573+
s.handler.UpdateDelay(outboundTag, int32(delay))
574+
}
575+
return int32(delay)
554576
}
555577

556578
// SetClashMode sets the clash routing mode.

docs/api-reference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ Exported as C-compatible symbols via `c-shared` build mode. All functions return
5959
| Function | Signature | Description |
6060
|----------|-----------|-------------|
6161
| `CoreSelectProxy` | `char* CoreSelectProxy(const char* group, const char* tag)` | Select node in proxy group |
62-
| `CoreTestDelay` | `char* CoreTestDelay(const char* name)` | Run URL test for outbound |
62+
| `CoreTestDelay` | `char* CoreTestDelay(const char* name, int timeoutMs)` | URL test, returns `{"delay":ms}` or `{"delay":-1}` |
6363
| `CoreSetMode` | `char* CoreSetMode(const char* mode)` | Set routing mode: `rule` / `global` / `direct` |
6464
| `CoreSetGroupExpand` | `char* CoreSetGroupExpand(const char* group, int expand)` | Persist UI expand state |
6565

@@ -166,7 +166,7 @@ Built with `gomobile bind`, generates AAR (Android) and xcframework (iOS). Metho
166166
| Method | Description |
167167
|--------|-------------|
168168
| `SelectProxy(group, tag string) error` | Select proxy node |
169-
| `TestDelay(name string) error` | URL test delay |
169+
| `TestDelay(name string, timeoutMs int32) int32` | URL test delay (ms), -1 on error/timeout |
170170
| `SetMode(mode string) error` | Set routing mode |
171171
| `SetGroupExpand(group string, expand bool) error` | UI expand state |
172172

ffi/api.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,10 @@ func (s *Singcast) SelectProxy(group, tag string) error {
145145
}
146146

147147
// TestDelay runs a URL test for the given outbound tag.
148-
func (s *Singcast) TestDelay(name string) error { return s.svc.URLTest(name) }
148+
// Returns delay in milliseconds, -1 on error or timeout.
149+
func (s *Singcast) TestDelay(name string, timeoutMs int32) int32 {
150+
return s.svc.URLTest(name, timeoutMs)
151+
}
149152

150153
// SetMode sets the clash routing mode (rule, global, or direct).
151154
func (s *Singcast) SetMode(mode string) error { return s.svc.SetClashMode(mode) }

0 commit comments

Comments
 (0)