| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package discovery
- import (
- "fmt"
- "net/http"
- "sort"
- "time"
- "ai-status-light/internal/logger"
- )
- type Scanner struct {
- Host string
- ScanRange *[2]int
- }
- func NewScanner(host string, scanRange *[2]int) *Scanner {
- return &Scanner{
- Host: host,
- ScanRange: scanRange,
- }
- }
- func (s *Scanner) Discover() []int {
- logger.Debug("开始发现 OpenCode 实例,主机: %s", s.Host)
- ports := findByCmdline()
- if len(ports) > 0 {
- logger.Debug("通过命令行参数发现端口: %v", ports)
- } else {
- logger.Debug("命令行未发现端口,尝试通过 PID 查找")
- ports = findByPID()
- if len(ports) > 0 {
- logger.Debug("通过 PID 发现端口: %v", ports)
- }
- }
- if len(ports) == 0 && s.ScanRange != nil {
- logger.Info("未通过系统命令发现实例,开始端口扫描 %d-%d", s.ScanRange[0], s.ScanRange[1])
- ports = scanPorts(s.Host, s.ScanRange[0], s.ScanRange[1])
- if len(ports) > 0 {
- logger.Info("端口扫描发现 %d 个实例: %v", len(ports), ports)
- }
- }
- result := unique(ports)
- logger.Debug("发现完成,共 %d 个实例: %v", len(result), result)
- return result
- }
- func scanPorts(host string, startPort, endPort int) []int {
- var found []int
- client := http.Client{Timeout: 1 * time.Second}
- for port := startPort; port <= endPort; port++ {
- resp, err := client.Get(fmt.Sprintf("http://%s:%d/global/health", host, port))
- if err != nil {
- continue
- }
- resp.Body.Close()
- if resp.StatusCode == 200 {
- logger.Debug("端口扫描发现实例: %d", port)
- found = append(found, port)
- }
- }
- return found
- }
- func contains(slice []int, val int) bool {
- for _, v := range slice {
- if v == val {
- return true
- }
- }
- return false
- }
- func unique(slice []int) []int {
- keys := make(map[int]bool)
- var result []int
- for _, v := range slice {
- if !keys[v] {
- keys[v] = true
- result = append(result, v)
- }
- }
- sort.Ints(result)
- return result
- }
|