This commit is contained in:
2025-11-21 18:41:31 +08:00
parent 1402473d20
commit f6a686967c
2 changed files with 49 additions and 41 deletions

View File

@@ -104,33 +104,42 @@ func (t *PingTask) executePing() map[string]interface{} {
func parsePingOutput(output string) map[string]interface{} { func parsePingOutput(output string) map[string]interface{} {
result := map[string]interface{}{ result := map[string]interface{}{
"latency": 0.0, "latency": float64(0),
"success": true, "success": true,
"packet_loss": false, "packet_loss": false,
} }
lines := strings.Split(output, "\n") lines := strings.Split(output, "\n")
for _, line := range lines { for _, line := range lines {
line = strings.TrimSpace(line)
// 解析丢包率4 packets transmitted, 4 received, 0% packet loss
if strings.Contains(line, "packets transmitted") { if strings.Contains(line, "packets transmitted") {
// 解析丢包率
parts := strings.Fields(line) parts := strings.Fields(line)
for i, part := range parts { for i, part := range parts {
if part == "packet" && i+2 < len(parts) { if part == "packet" && i+2 < len(parts) {
if loss, err := strconv.ParseFloat(strings.Trim(parts[i+1], "%"), 64); err == nil { // 查找百分比
lossStr := strings.Trim(parts[i+1], "%")
if loss, err := strconv.ParseFloat(lossStr, 64); err == nil {
result["packet_loss"] = loss > 0 result["packet_loss"] = loss > 0
if loss > 0 {
result["success"] = false
} }
} }
} }
} }
if strings.Contains(line, "min/avg/max") { }
// 解析平均延迟
// 解析延迟rtt min/avg/max/mdev = 10.123/12.456/15.789/2.345 ms
if strings.Contains(line, "min/avg/max") || strings.Contains(line, "rtt") {
parts := strings.Fields(line) parts := strings.Fields(line)
for _, part := range parts { for _, part := range parts {
if strings.Contains(part, "/") { if strings.Contains(part, "/") && !strings.Contains(part, "=") {
times := strings.Split(part, "/") times := strings.Split(part, "/")
if len(times) >= 2 { if len(times) >= 2 {
if avg, err := strconv.ParseFloat(times[1], 64); err == nil { if avg, err := strconv.ParseFloat(times[1], 64); err == nil {
result["latency"] = avg result["latency"] = avg
break
} }
} }
} }

View File

@@ -5,6 +5,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@@ -186,69 +187,67 @@ func HandleContinuousStatus(c *gin.Context) {
} }
func pushResultToBackend(taskID string, result map[string]interface{}) { func pushResultToBackend(taskID string, result map[string]interface{}) {
// 确保result包含必要的字段
if result["timestamp"] == nil {
result["timestamp"] = time.Now().Unix()
}
if result["latency"] == nil {
result["latency"] = 0.0
}
if result["success"] == nil {
result["success"] = true
}
if result["packet_loss"] == nil {
result["packet_loss"] = false
}
// 推送结果到后端 // 推送结果到后端
url := fmt.Sprintf("%s/api/public/node/continuous/result", backendURL) url := fmt.Sprintf("%s/api/public/node/continuous/result", backendURL)
// 获取本机IP // 不发送node_ip让后端从请求中获取客户端IP外网IP
nodeIP := getLocalIP()
data := map[string]interface{}{ data := map[string]interface{}{
"task_id": taskID, "task_id": taskID,
"node_ip": nodeIP,
"result": result, "result": result,
} }
jsonData, err := json.Marshal(data) jsonData, err := json.Marshal(data)
if err != nil { if err != nil {
logger.Error("序列化结果失败", zap.Error(err)) logger.Error("序列化结果失败", zap.Error(err), zap.String("task_id", taskID))
return return
} }
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil { if err != nil {
logger.Error("创建请求失败", zap.Error(err)) logger.Error("创建请求失败", zap.Error(err), zap.String("task_id", taskID))
return return
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 5 * time.Second} client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
logger.Warn("推送结果失败", zap.Error(err)) logger.Warn("推送结果失败,继续运行",
// 如果推送失败,停止任务 zap.Error(err),
taskMutex.Lock() zap.String("task_id", taskID),
if task, exists := continuousTasks[taskID]; exists { zap.String("url", url))
task.IsRunning = false // 推送失败不停止任务,继续运行
if task.pingTask != nil {
task.pingTask.Stop()
}
if task.tcpingTask != nil {
task.tcpingTask.Stop()
}
delete(continuousTasks, taskID)
}
taskMutex.Unlock()
return return
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
logger.Warn("推送结果失败", zap.Int("status", resp.StatusCode)) body, _ := io.ReadAll(resp.Body)
// 如果推送失败,停止任务 logger.Warn("推送结果失败,继续运行",
taskMutex.Lock() zap.Int("status", resp.StatusCode),
if task, exists := continuousTasks[taskID]; exists { zap.String("task_id", taskID),
task.IsRunning = false zap.String("url", url),
if task.pingTask != nil { zap.String("response", string(body)))
task.pingTask.Stop() // 推送失败不停止任务,继续运行
} return
if task.tcpingTask != nil {
task.tcpingTask.Stop()
}
delete(continuousTasks, taskID)
}
taskMutex.Unlock()
} }
logger.Debug("推送结果成功", zap.String("task_id", taskID))
} }
func getLocalIP() string { func getLocalIP() string {