fix: 去除无用注释

This commit is contained in:
fengyarnom 2025-05-15 13:34:47 +08:00
parent e87a10c08f
commit 86f731b76c
6 changed files with 249 additions and 325 deletions

18
db.go
View File

@ -13,7 +13,6 @@ const SCALING_FACTOR = 1000 // 浮点数到整数的转换因子
// 初始化数据库连接 // 初始化数据库连接
func InitDB() error { func InitDB() error {
// 调整这些参数以匹配你的MySQL配置
username := "root" username := "root"
password := "root" // 请替换为你的实际密码 password := "root" // 请替换为你的实际密码
host := "localhost" host := "localhost"
@ -29,13 +28,11 @@ func InitDB() error {
return err return err
} }
// 测试连接
err = db.Ping() err = db.Ping()
if err != nil { if err != nil {
return err return err
} }
// 设置连接池参数
db.SetMaxOpenConns(10) db.SetMaxOpenConns(10)
db.SetMaxIdleConns(5) db.SetMaxIdleConns(5)
db.SetConnMaxLifetime(time.Minute * 5) db.SetConnMaxLifetime(time.Minute * 5)
@ -52,7 +49,6 @@ func CloseDB() {
// 保存传感器数据 - 将浮点值转换为整数存储 // 保存传感器数据 - 将浮点值转换为整数存储
func SaveSensorData(sensorID int, x, y, z float64) error { func SaveSensorData(sensorID int, x, y, z float64) error {
// 转换为整数乘以1000并四舍五入
xInt := int(x * SCALING_FACTOR) xInt := int(x * SCALING_FACTOR)
yInt := int(y * SCALING_FACTOR) yInt := int(y * SCALING_FACTOR)
zInt := int(z * SCALING_FACTOR) zInt := int(z * SCALING_FACTOR)
@ -62,20 +58,16 @@ func SaveSensorData(sensorID int, x, y, z float64) error {
return err return err
} }
// 获取传感器数据 - 从整数转换回浮点数
// 获取传感器数据 - 添加时间范围 // 获取传感器数据 - 添加时间范围
func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) { func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) {
// 基本查询
query := `SELECT id, sensor_id, x_value, y_value, z_value, query := `SELECT id, sensor_id, x_value, y_value, z_value,
timestamp as timestamp timestamp as timestamp
FROM sensor_data FROM sensor_data
WHERE sensor_id = ?` WHERE sensor_id = ?`
// 添加查询条件
var args []interface{} var args []interface{}
args = append(args, sensorID) args = append(args, sensorID)
// 添加日期范围
if !startDate.IsZero() { if !startDate.IsZero() {
query += " AND timestamp >= ?" query += " AND timestamp >= ?"
args = append(args, startDate) args = append(args, startDate)
@ -86,11 +78,9 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti
args = append(args, endDate) args = append(args, endDate)
} }
// 添加排序和限制
query += " ORDER BY timestamp DESC LIMIT ?" query += " ORDER BY timestamp DESC LIMIT ?"
args = append(args, limit) args = append(args, limit)
// 执行查询
rows, err := db.Query(query, args...) rows, err := db.Query(query, args...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -108,7 +98,6 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti
return nil, err return nil, err
} }
// 从整数转换回浮点数
data.X = float64(xInt) / SCALING_FACTOR data.X = float64(xInt) / SCALING_FACTOR
data.Y = float64(yInt) / SCALING_FACTOR data.Y = float64(yInt) / SCALING_FACTOR
data.Z = float64(zInt) / SCALING_FACTOR data.Z = float64(zInt) / SCALING_FACTOR
@ -121,16 +110,13 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti
// 获取所有传感器数据 // 获取所有传感器数据
func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) { func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) {
// 基本查询
query := `SELECT id, sensor_id, x_value, y_value, z_value, query := `SELECT id, sensor_id, x_value, y_value, z_value,
timestamp as timestamp timestamp as timestamp
FROM sensor_data FROM sensor_data
WHERE 1=1` WHERE 1=1`
// 添加查询条件
var args []interface{} var args []interface{}
// 添加日期范围
if !startDate.IsZero() { if !startDate.IsZero() {
query += " AND timestamp >= ?" query += " AND timestamp >= ?"
args = append(args, startDate) args = append(args, startDate)
@ -141,11 +127,9 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens
args = append(args, endDate) args = append(args, endDate)
} }
// 添加排序和限制
query += " ORDER BY timestamp DESC LIMIT ?" query += " ORDER BY timestamp DESC LIMIT ?"
args = append(args, limit) args = append(args, limit)
// 执行查询
rows, err := db.Query(query, args...) rows, err := db.Query(query, args...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -163,7 +147,6 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens
return nil, err return nil, err
} }
// 从整数转换回浮点数
data.X = float64(xInt) / SCALING_FACTOR data.X = float64(xInt) / SCALING_FACTOR
data.Y = float64(yInt) / SCALING_FACTOR data.Y = float64(yInt) / SCALING_FACTOR
data.Z = float64(zInt) / SCALING_FACTOR data.Z = float64(zInt) / SCALING_FACTOR
@ -173,6 +156,7 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens
return result, nil return result, nil
} }
// 获取所有传感器ID // 获取所有传感器ID
func GetAllSensorIDs() ([]int, error) { func GetAllSensorIDs() ([]int, error) {
query := `SELECT DISTINCT sensor_id FROM sensor_data ORDER BY sensor_id` query := `SELECT DISTINCT sensor_id FROM sensor_data ORDER BY sensor_id`

View File

@ -14,10 +14,8 @@ import (
// 启动HTTP服务器 // 启动HTTP服务器
func StartHTTPServer(address string) error { func StartHTTPServer(address string) error {
// 主页
http.HandleFunc("/", handleIndex) http.HandleFunc("/", handleIndex)
// API路由
http.HandleFunc("/api/data", handleGetData) http.HandleFunc("/api/data", handleGetData)
http.HandleFunc("/api/sensors", handleGetSensors) http.HandleFunc("/api/sensors", handleGetSensors)
http.HandleFunc("/api/clients", handleGetClients) http.HandleFunc("/api/clients", handleGetClients)
@ -29,7 +27,6 @@ func StartHTTPServer(address string) error {
func handleIndex(w http.ResponseWriter, r *http.Request) { func handleIndex(w http.ResponseWriter, r *http.Request) {
log.Printf("接收到主页请求: %s", r.URL.Path) log.Printf("接收到主页请求: %s", r.URL.Path)
// 确保templates目录存在
templatePath := "templates/index.html" templatePath := "templates/index.html"
absPath, _ := filepath.Abs(templatePath) absPath, _ := filepath.Abs(templatePath)
@ -62,16 +59,13 @@ func handleGetData(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
// 获取查询参数
sensorIDStr := r.URL.Query().Get("sensor_id") sensorIDStr := r.URL.Query().Get("sensor_id")
limitStr := r.URL.Query().Get("limit") limitStr := r.URL.Query().Get("limit")
startDateStr := r.URL.Query().Get("start_date") startDateStr := r.URL.Query().Get("start_date")
endDateStr := r.URL.Query().Get("end_date") endDateStr := r.URL.Query().Get("end_date")
// 默认值
limit := 500 limit := 500
// 处理传感器ID
var sensorID int var sensorID int
var err error var err error
if sensorIDStr != "" && sensorIDStr != "all" { if sensorIDStr != "" && sensorIDStr != "all" {
@ -83,7 +77,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) {
} }
} }
// 处理限制条数
if limitStr != "" { if limitStr != "" {
limit, err = strconv.Atoi(limitStr) limit, err = strconv.Atoi(limitStr)
if err != nil || limit <= 0 { if err != nil || limit <= 0 {
@ -93,7 +86,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) {
} }
} }
// 处理日期范围
var startDate, endDate time.Time var startDate, endDate time.Time
if startDateStr != "" { if startDateStr != "" {
startDate, err = time.Parse("2006-01-02T15:04", startDateStr) startDate, err = time.Parse("2006-01-02T15:04", startDateStr)
@ -113,7 +105,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) {
} }
} }
// 获取数据
var data []SensorData var data []SensorData
if sensorIDStr == "all" || sensorIDStr == "" { if sensorIDStr == "all" || sensorIDStr == "" {
data, err = GetAllSensorData(limit, startDate, endDate) data, err = GetAllSensorData(limit, startDate, endDate)
@ -129,7 +120,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) {
log.Printf("成功获取到 %d 条数据记录", len(data)) log.Printf("成功获取到 %d 条数据记录", len(data))
// 返回JSON
if err := json.NewEncoder(w).Encode(data); err != nil { if err := json.NewEncoder(w).Encode(data); err != nil {
log.Printf("错误: 编码JSON失败: %v", err) log.Printf("错误: 编码JSON失败: %v", err)
http.Error(w, "编码JSON失败"+err.Error(), http.StatusInternalServerError) http.Error(w, "编码JSON失败"+err.Error(), http.StatusInternalServerError)
@ -141,7 +131,6 @@ func handleGetSensors(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
// 获取所有传感器ID
sensorIDs, err := GetAllSensorIDs() sensorIDs, err := GetAllSensorIDs()
if err != nil { if err != nil {
log.Printf("错误: 获取传感器ID失败: %v", err) log.Printf("错误: 获取传感器ID失败: %v", err)
@ -151,7 +140,6 @@ func handleGetSensors(w http.ResponseWriter, r *http.Request) {
log.Printf("成功获取到 %d 个传感器ID", len(sensorIDs)) log.Printf("成功获取到 %d 个传感器ID", len(sensorIDs))
// 返回JSON
if err := json.NewEncoder(w).Encode(sensorIDs); err != nil { if err := json.NewEncoder(w).Encode(sensorIDs); err != nil {
log.Printf("错误: 编码JSON失败: %v", err) log.Printf("错误: 编码JSON失败: %v", err)
http.Error(w, "编码JSON失败"+err.Error(), http.StatusInternalServerError) http.Error(w, "编码JSON失败"+err.Error(), http.StatusInternalServerError)

110
logger.go
View File

@ -1,89 +1,79 @@
// logger.go
package main package main
import ( import (
"fmt" "fmt"
"io" "io"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
) )
// 日志文件
var ( var (
logFile *os.File logFile *os.File
Logger *log.Logger // 导出Logger供其他包使用 Logger *log.Logger // 导出Logger供其他包使用
TCPDataLogger *log.Logger // 专门用于记录TCP数据的日志 TCPDataLogger *log.Logger // 专门用于记录TCP数据的日志
) )
// 初始化日志系统 // 初始化日志系统
func InitLogger() error { func InitLogger() error {
// 创建logs目录 logsDir := "logs"
logsDir := "logs" if err := os.MkdirAll(logsDir, 0755); err != nil {
if err := os.MkdirAll(logsDir, 0755); err != nil { return fmt.Errorf("创建日志目录失败: %v", err)
return fmt.Errorf("创建日志目录失败: %v", err) }
}
// 创建当天的日志文件 today := time.Now().Format("2006-01-02")
today := time.Now().Format("2006-01-02") logFilePath := filepath.Join(logsDir, fmt.Sprintf("server_%s.log", today))
logFilePath := filepath.Join(logsDir, fmt.Sprintf("server_%s.log", today))
file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
return fmt.Errorf("打开日志文件失败: %v", err) return fmt.Errorf("打开日志文件失败: %v", err)
} }
logFile = file logFile = file
// 创建一个多输出的logger同时写入文件和控制台 multiWriter := io.MultiWriter(os.Stdout, file)
multiWriter := io.MultiWriter(os.Stdout, file) Logger = log.New(multiWriter, "", log.Ldate|log.Ltime|log.Lshortfile)
Logger = log.New(multiWriter, "", log.Ldate|log.Ltime|log.Lshortfile)
// 创建TCP数据日志文件 tcpDataFilePath := filepath.Join(logsDir, fmt.Sprintf("tcp_data_%s.log", today))
tcpDataFilePath := filepath.Join(logsDir, fmt.Sprintf("tcp_data_%s.log", today)) tcpDataFile, err := os.OpenFile(tcpDataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
tcpDataFile, err := os.OpenFile(tcpDataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil {
if err != nil { return fmt.Errorf("打开TCP数据日志文件失败: %v", err)
return fmt.Errorf("打开TCP数据日志文件失败: %v", err) }
}
// TCP数据日志同时写入文件和控制台 tcpDataMultiWriter := io.MultiWriter(os.Stdout, tcpDataFile)
tcpDataMultiWriter := io.MultiWriter(os.Stdout, tcpDataFile) TCPDataLogger = log.New(tcpDataMultiWriter, "TCP_DATA: ", log.Ldate|log.Ltime)
TCPDataLogger = log.New(tcpDataMultiWriter, "TCP_DATA: ", log.Ldate|log.Ltime)
// 替换标准日志 log.SetOutput(multiWriter)
log.SetOutput(multiWriter) log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
Logger.Println("日志系统初始化完成") Logger.Println("日志系统初始化完成")
return nil return nil
} }
// 关闭日志文件 // 关闭日志文件
func CloseLogger() { func CloseLogger() {
if logFile != nil { if logFile != nil {
logFile.Close() logFile.Close()
} }
} }
// 日志轮转,每天创建新的日志文件 // 日志轮转,每天创建新的日志文件
func StartLogRotation() { func StartLogRotation() {
go func() { go func() {
for { for {
// 等待到明天0点 now := time.Now()
now := time.Now() next := now.Add(24 * time.Hour)
next := now.Add(24 * time.Hour) next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location())
next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()) duration := next.Sub(now)
duration := next.Sub(now)
time.Sleep(duration) time.Sleep(duration)
// 重新初始化日志 Logger.Println("开始日志轮转...")
Logger.Println("开始日志轮转...") CloseLogger()
CloseLogger() if err := InitLogger(); err != nil {
if err := InitLogger(); err != nil { log.Printf("日志轮转失败: %v", err)
log.Printf("日志轮转失败: %v", err) }
} }
} }()
}()
} }

View File

@ -8,33 +8,27 @@ import (
) )
func main() { func main() {
// 命令行参数解析
serverType := flag.String("server", "tcp", "服务器类型: tcp 或 udp") serverType := flag.String("server", "tcp", "服务器类型: tcp 或 udp")
tcpPort := flag.String("tcpport", "10002", "TCP服务器端口") tcpPort := flag.String("tcpport", "10002", "TCP服务器端口")
udpPort := flag.String("udpport", "10002", "UDP服务器端口") udpPort := flag.String("udpport", "10002", "UDP服务器端口")
httpPort := flag.String("httpport", "10001", "HTTP服务器端口") httpPort := flag.String("httpport", "10001", "HTTP服务器端口")
flag.Parse() flag.Parse()
// 初始化日志
if err := InitLogger(); err != nil { if err := InitLogger(); err != nil {
log.Fatalf("初始化日志系统失败: %v", err) log.Fatalf("初始化日志系统失败: %v", err)
} }
defer CloseLogger() defer CloseLogger()
// 启动日志轮转
StartLogRotation() StartLogRotation()
// 初始化数据库
err := InitDB() err := InitDB()
if err != nil { if err != nil {
log.Fatalf("初始化数据库失败: %v", err) log.Fatalf("初始化数据库失败: %v", err)
} }
defer CloseDB() defer CloseDB()
fmt.Println("iProbe 斜侧仪监控系统启动中...")
var wg sync.WaitGroup var wg sync.WaitGroup
// 根据选择启动TCP或UDP服务器
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
@ -53,7 +47,6 @@ func main() {
} }
}() }()
// 启动HTTP服务器
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()

View File

@ -1,255 +1,236 @@
// tcp_server.go
package main package main
import ( import (
"fmt" "fmt"
"io" "io"
"net" "net"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
) )
// 客户端信息结构 // 客户端信息结构
type ClientInfo struct { type ClientInfo struct {
IP string // IP地址 IP string // IP地址
Port string // 端口 Port string // 端口
LastSeen time.Time // 最后活跃时间 LastSeen time.Time // 最后活跃时间
} }
// 客户端列表(使用互斥锁保护的映射) // 客户端列表(使用互斥锁保护的映射)
var ( var (
clientsMutex sync.Mutex clientsMutex sync.Mutex
clients = make(map[string]*ClientInfo) clients = make(map[string]*ClientInfo)
) )
// StartTCPServer 启动TCP服务器 // StartTCPServer 启动TCP服务器
func StartTCPServer(address string) error { func StartTCPServer(address string) error {
listener, err := net.Listen("tcp", address) listener, err := net.Listen("tcp", address)
if err != nil { if err != nil {
return err return err
} }
// 启动客户端清理 startClientCleanup()
startClientCleanup()
Logger.Printf("TCP服务器已启动正在监听 %s\n", address) Logger.Printf("TCP服务器已启动正在监听 %s\n", address)
for { for {
conn, err := listener.Accept() conn, err := listener.Accept()
if err != nil { if err != nil {
Logger.Printf("接受连接失败: %v", err) Logger.Printf("接受连接失败: %v", err)
continue continue
} }
go handleConnection(conn) go handleConnection(conn)
} }
} }
// handleConnection 处理客户端连接 // handleConnection 处理客户端连接
func handleConnection(conn net.Conn) { func handleConnection(conn net.Conn) {
defer conn.Close() defer conn.Close()
// 获取客户端信息 remoteAddr := conn.RemoteAddr().String()
remoteAddr := conn.RemoteAddr().String() Logger.Printf("新的客户端连接: %s", remoteAddr)
Logger.Printf("新的客户端连接: %s", remoteAddr)
// 添加到在线客户端列表 addClient(remoteAddr)
addClient(remoteAddr)
buffer := make([]byte, 1024) buffer := make([]byte, 1024)
for { for {
// 读取数据 n, err := conn.Read(buffer)
n, err := conn.Read(buffer) if err != nil {
if err != nil { if err != io.EOF {
if err != io.EOF { Logger.Printf("从客户端读取失败 %s: %v", remoteAddr, err)
Logger.Printf("从客户端读取失败 %s: %v", remoteAddr, err) } else {
} else { Logger.Printf("客户端断开连接 %s", remoteAddr)
Logger.Printf("客户端断开连接 %s", remoteAddr) }
} removeClient(remoteAddr)
removeClient(remoteAddr) break
break }
}
// 将字节数据转换为字符串,并记录原始数据 rawData := string(buffer[:n])
rawData := string(buffer[:n]) TCPDataLogger.Printf("从客户端 %s 接收到原始数据: %s", remoteAddr, rawData)
TCPDataLogger.Printf("从客户端 %s 接收到原始数据: %s", remoteAddr, rawData)
// 尝试解析数据 sensorID, x, y, z, err := parseData(rawData)
sensorID, x, y, z, err := parseData(rawData)
if err == nil { if err == nil {
TCPDataLogger.Printf("解析成功 - 客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f", TCPDataLogger.Printf("解析成功 - 客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f",
remoteAddr, sensorID, x, y, z) remoteAddr, sensorID, x, y, z)
// 保存数据到数据库 if err := SaveSensorData(sensorID, x, y, z); err != nil {
if err := SaveSensorData(sensorID, x, y, z); err != nil { Logger.Printf("保存传感器数据失败: %v", err)
Logger.Printf("保存传感器数据失败: %v", err) }
} } else {
} else { TCPDataLogger.Printf("无法解析从客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err)
TCPDataLogger.Printf("无法解析从客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) }
}
// 发送响应 resp := "OK\n"
resp := "OK\n" if _, err := conn.Write([]byte(resp)); err != nil {
if _, err := conn.Write([]byte(resp)); err != nil { Logger.Printf("发送响应到客户端 %s 失败: %v", remoteAddr, err)
Logger.Printf("发送响应到客户端 %s 失败: %v", remoteAddr, err) removeClient(remoteAddr)
removeClient(remoteAddr) break
break }
}
// 更新客户端最后活跃时间 updateClientLastSeen(remoteAddr)
updateClientLastSeen(remoteAddr) }
}
} }
// parseData 使用正则表达式解析传感器数据 // parseData 使用正则表达式解析传感器数据
func parseData(data string) (int, float64, float64, float64, error) { func parseData(data string) (int, float64, float64, float64, error) {
// 使用正则表达式匹配数据格式 pattern := regexp.MustCompile(`(\d+):([-]?\d+\.\d+),\s*([-]?\d+\.\d+),\s*([-]?\d+\.\d+)`)
pattern := regexp.MustCompile(`(\d+):([-]?\d+\.\d+),\s*([-]?\d+\.\d+),\s*([-]?\d+\.\d+)`) matches := pattern.FindStringSubmatch(data)
matches := pattern.FindStringSubmatch(data)
if len(matches) != 5 { if len(matches) != 5 {
return 0, 0, 0, 0, fmt.Errorf("数据格式不正确: %s", data) return 0, 0, 0, 0, fmt.Errorf("数据格式不正确: %s", data)
} }
// 解析传感器ID和三个浮点数值 sensorID, err := strconv.Atoi(matches[1])
sensorID, err := strconv.Atoi(matches[1]) if err != nil {
if err != nil { return 0, 0, 0, 0, fmt.Errorf("解析传感器ID失败: %v", err)
return 0, 0, 0, 0, fmt.Errorf("解析传感器ID失败: %v", err) }
}
x, err := strconv.ParseFloat(strings.TrimSpace(matches[2]), 64) x, err := strconv.ParseFloat(strings.TrimSpace(matches[2]), 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, fmt.Errorf("解析X值失败: %v", err) return 0, 0, 0, 0, fmt.Errorf("解析X值失败: %v", err)
} }
y, err := strconv.ParseFloat(strings.TrimSpace(matches[3]), 64) y, err := strconv.ParseFloat(strings.TrimSpace(matches[3]), 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, fmt.Errorf("解析Y值失败: %v", err) return 0, 0, 0, 0, fmt.Errorf("解析Y值失败: %v", err)
} }
z, err := strconv.ParseFloat(strings.TrimSpace(matches[4]), 64) z, err := strconv.ParseFloat(strings.TrimSpace(matches[4]), 64)
if err != nil { if err != nil {
return 0, 0, 0, 0, fmt.Errorf("解析Z值失败: %v", err) return 0, 0, 0, 0, fmt.Errorf("解析Z值失败: %v", err)
} }
return sensorID, x, y, z, nil return sensorID, x, y, z, nil
} }
// addClient 添加客户端 // addClient 添加客户端
func addClient(addr string) { func addClient(addr string) {
clientsMutex.Lock() clientsMutex.Lock()
defer clientsMutex.Unlock() defer clientsMutex.Unlock()
// 解析地址 host, port, err := net.SplitHostPort(addr)
host, port, err := net.SplitHostPort(addr) if err != nil {
if err != nil { Logger.Printf("解析客户端地址失败 %s: %v", addr, err)
Logger.Printf("解析客户端地址失败 %s: %v", addr, err) host = addr
host = addr port = "unknown"
port = "unknown" }
}
// 添加或更新客户端 clients[addr] = &ClientInfo{
clients[addr] = &ClientInfo{ IP: host,
IP: host, Port: port,
Port: port, LastSeen: time.Now(),
LastSeen: time.Now(), }
}
Logger.Printf("添加新客户端: %s", addr) Logger.Printf("添加新客户端: %s", addr)
} }
// updateClientLastSeen 更新客户端最后活跃时间 // updateClientLastSeen 更新客户端最后活跃时间
func updateClientLastSeen(addr string) { func updateClientLastSeen(addr string) {
clientsMutex.Lock() clientsMutex.Lock()
defer clientsMutex.Unlock() defer clientsMutex.Unlock()
if client, exists := clients[addr]; exists { if client, exists := clients[addr]; exists {
client.LastSeen = time.Now() client.LastSeen = time.Now()
} }
} }
// removeClient 移除客户端 // removeClient 移除客户端
func removeClient(addr string) { func removeClient(addr string) {
clientsMutex.Lock() clientsMutex.Lock()
defer clientsMutex.Unlock() defer clientsMutex.Unlock()
// 我们只更新最后活跃时间而不实际删除, if client, exists := clients[addr]; exists {
// 这样前端可以知道客户端已断开连接 client.LastSeen = time.Now()
if client, exists := clients[addr]; exists { Logger.Printf("客户端标记为断开连接: %s", addr)
client.LastSeen = time.Now() }
Logger.Printf("客户端标记为断开连接: %s", addr)
}
} }
// getAllClients 获取所有客户端信息 // getAllClients 获取所有客户端信息
func getAllClients() []map[string]interface{} { func getAllClients() []map[string]interface{} {
clientsMutex.Lock() clientsMutex.Lock()
defer clientsMutex.Unlock() defer clientsMutex.Unlock()
now := time.Now() now := time.Now()
result := make([]map[string]interface{}, 0, len(clients)) result := make([]map[string]interface{}, 0, len(clients))
for addr, client := range clients { for addr, client := range clients {
// 计算最后活跃时间 lastSeenDuration := now.Sub(client.LastSeen)
lastSeenDuration := now.Sub(client.LastSeen)
// 如果超过1天未活跃则删除 if lastSeenDuration > 24*time.Hour {
if lastSeenDuration > 24*time.Hour { delete(clients, addr)
delete(clients, addr) continue
continue }
}
// 在线状态 - 10分钟内有活动 isOnline := lastSeenDuration < 10*time.Minute
isOnline := lastSeenDuration < 10*time.Minute
result = append(result, map[string]interface{}{ result = append(result, map[string]interface{}{
"address": addr, "address": addr,
"ip": client.IP, "ip": client.IP,
"port": client.Port, "port": client.Port,
"lastSeen": client.LastSeen, "lastSeen": client.LastSeen,
"isOnline": isOnline, "isOnline": isOnline,
"lastSeenFormatted": formatDuration(lastSeenDuration), "lastSeenFormatted": formatDuration(lastSeenDuration),
}) })
} }
return result return result
} }
// formatDuration 格式化持续时间为友好的字符串 // formatDuration 格式化持续时间为友好的字符串
func formatDuration(d time.Duration) string { func formatDuration(d time.Duration) string {
if d < time.Minute { if d < time.Minute {
return "刚刚" return "刚刚"
} else if d < time.Hour { } else if d < time.Hour {
return fmt.Sprintf("%d分钟前", int(d.Minutes())) return fmt.Sprintf("%d分钟前", int(d.Minutes()))
} else if d < 24*time.Hour { } else if d < 24*time.Hour {
return fmt.Sprintf("%d小时前", int(d.Hours())) return fmt.Sprintf("%d小时前", int(d.Hours()))
} else { } else {
return fmt.Sprintf("%d天前", int(d.Hours()/24)) return fmt.Sprintf("%d天前", int(d.Hours()/24))
} }
} }
// startClientCleanup 启动清理过期客户端的goroutine // startClientCleanup 启动清理过期客户端的goroutine
func startClientCleanup() { func startClientCleanup() {
go func() { go func() {
for { for {
time.Sleep(1 * time.Hour) // 每小时检查一次 time.Sleep(1 * time.Hour) // 每小时检查一次
clientsMutex.Lock() clientsMutex.Lock()
now := time.Now() now := time.Now()
for addr, client := range clients { for addr, client := range clients {
if now.Sub(client.LastSeen) > 24*time.Hour { if now.Sub(client.LastSeen) > 24*time.Hour {
delete(clients, addr) delete(clients, addr)
Logger.Printf("移除过期客户端: %s", addr) Logger.Printf("移除过期客户端: %s", addr)
} }
} }
clientsMutex.Unlock() clientsMutex.Unlock()
} }
}() }()
} }

View File

@ -1,4 +1,3 @@
// udp_server.go
package main package main
import ( import (
@ -8,20 +7,17 @@ import (
// StartUDPServer 启动UDP服务器 // StartUDPServer 启动UDP服务器
func StartUDPServer(address string) error { func StartUDPServer(address string) error {
// 解析UDP地址
addr, err := net.ResolveUDPAddr("udp", address) addr, err := net.ResolveUDPAddr("udp", address)
if err != nil { if err != nil {
return fmt.Errorf("解析UDP地址失败: %v", err) return fmt.Errorf("解析UDP地址失败: %v", err)
} }
// 创建UDP连接
conn, err := net.ListenUDP("udp", addr) conn, err := net.ListenUDP("udp", addr)
if err != nil { if err != nil {
return fmt.Errorf("监听UDP地址失败: %v", err) return fmt.Errorf("监听UDP地址失败: %v", err)
} }
defer conn.Close() defer conn.Close()
// 启动客户端清理
startClientCleanup() startClientCleanup()
Logger.Printf("UDP服务器已启动正在监听 %s\n", address) Logger.Printf("UDP服务器已启动正在监听 %s\n", address)
@ -35,31 +31,25 @@ func StartUDPServer(address string) error {
continue continue
} }
// 处理数据包
go handleUDPPacket(conn, remoteAddr, buffer[:n]) go handleUDPPacket(conn, remoteAddr, buffer[:n])
} }
} }
// handleUDPPacket 处理UDP数据包 // handleUDPPacket 处理UDP数据包
func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) { func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) {
// 获取客户端信息
remoteAddr := addr.String() remoteAddr := addr.String()
// 添加到在线客户端列表
addClient(remoteAddr) addClient(remoteAddr)
// 将字节数据转换为字符串,并记录原始数据
rawData := string(data) rawData := string(data)
TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData) TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData)
// 尝试解析数据
sensorID, x, y, z, err := parseData(rawData) sensorID, x, y, z, err := parseData(rawData)
if err == nil { if err == nil {
TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f", TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f",
remoteAddr, sensorID, x, y, z) remoteAddr, sensorID, x, y, z)
// 保存数据到数据库
if err := SaveSensorData(sensorID, x, y, z); err != nil { if err := SaveSensorData(sensorID, x, y, z); err != nil {
Logger.Printf("保存传感器数据失败: %v", err) Logger.Printf("保存传感器数据失败: %v", err)
} }
@ -67,12 +57,10 @@ func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) {
TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err)
} }
// 发送响应
resp := "OK\n" resp := "OK\n"
if _, err := conn.WriteToUDP([]byte(resp), addr); err != nil { if _, err := conn.WriteToUDP([]byte(resp), addr); err != nil {
Logger.Printf("发送响应到UDP客户端 %s 失败: %v", remoteAddr, err) Logger.Printf("发送响应到UDP客户端 %s 失败: %v", remoteAddr, err)
} }
// 更新客户端最后活跃时间
updateClientLastSeen(remoteAddr) updateClientLastSeen(remoteAddr)
} }