107 lines
3.4 KiB
Go
107 lines
3.4 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"net"
|
||
"regexp"
|
||
)
|
||
|
||
// StartUDPServer 启动UDP服务器
|
||
func StartUDPServer(address string) error {
|
||
addr, err := net.ResolveUDPAddr("udp", address)
|
||
if err != nil {
|
||
return fmt.Errorf("解析UDP地址失败: %v", err)
|
||
}
|
||
|
||
conn, err := net.ListenUDP("udp", addr)
|
||
if err != nil {
|
||
return fmt.Errorf("监听UDP地址失败: %v", err)
|
||
}
|
||
defer conn.Close()
|
||
|
||
// 已移除客户端在线追踪;改由 DB 的 last_seen 统计在线
|
||
|
||
Logger.Printf("UDP服务器已启动,正在监听 %s\n", address)
|
||
|
||
buffer := make([]byte, 1024)
|
||
|
||
for {
|
||
n, remoteAddr, err := conn.ReadFromUDP(buffer)
|
||
if err != nil {
|
||
Logger.Printf("从UDP客户端读取失败: %v", err)
|
||
continue
|
||
}
|
||
|
||
go handleUDPPacket(conn, remoteAddr, buffer[:n])
|
||
}
|
||
}
|
||
|
||
// handleUDPPacket 处理UDP数据包
|
||
func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) {
|
||
remoteAddr := addr.String()
|
||
|
||
// 已移除客户端在线追踪
|
||
|
||
rawData := string(data)
|
||
TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData)
|
||
|
||
// 尝试解析批量数据
|
||
readings, err := parseBatchData(rawData)
|
||
if err == nil && len(readings) > 0 {
|
||
// 批量数据解析成功
|
||
TCPDataLogger.Printf("批量解析成功 - UDP客户端: %s, 传感器数量: %d", remoteAddr, len(readings))
|
||
|
||
// 保存所有传感器数据
|
||
if err := SaveBatchSensorData(readings); err != nil {
|
||
Logger.Printf("保存批量传感器数据失败: %v", err)
|
||
}
|
||
|
||
// 尝试提取设备ID并透传原始数据
|
||
if deviceID := ExtractDeviceIDFromBatchRaw(rawData); deviceID != "" {
|
||
Logger.Printf("准备转发 deviceID=%s 原始长度=%d", deviceID, len(rawData))
|
||
go func(id string, payload string) {
|
||
if fErr := ForwardRawData(id, payload); fErr != nil {
|
||
Logger.Printf("转发设备 %s 数据失败: %v", id, fErr)
|
||
}
|
||
}(deviceID, rawData)
|
||
}
|
||
|
||
// 记录第一个传感器的数据(用于兼容现有日志格式)
|
||
firstSensor := readings[0]
|
||
TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C",
|
||
remoteAddr, firstSensor.SensorID, firstSensor.X, firstSensor.Y, firstSensor.Z, firstSensor.Temperature)
|
||
} else {
|
||
// 尝试传统解析方法
|
||
sensorID, x, y, z, temperature, parseErr := parseData(rawData)
|
||
|
||
if parseErr == nil {
|
||
TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C",
|
||
remoteAddr, sensorID, x, y, z, temperature)
|
||
|
||
if err := SaveSensorData(sensorID, x, y, z, temperature, ""); err != nil {
|
||
Logger.Printf("保存传感器数据失败: %v", err)
|
||
}
|
||
|
||
// 从原始字符串尝试提取设备ID并透传
|
||
if m := regexp.MustCompile(`([A-Za-z0-9]+)-\d+`).FindStringSubmatch(rawData); len(m) == 2 {
|
||
id := m[1]
|
||
Logger.Printf("准备转发 deviceID=%s 原始长度=%d", id, len(rawData))
|
||
go func(id string, payload string) {
|
||
if fErr := ForwardRawData(id, payload); fErr != nil {
|
||
Logger.Printf("转发设备 %s 数据失败: %v", id, fErr)
|
||
}
|
||
}(id, rawData)
|
||
}
|
||
} else {
|
||
TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, parseErr)
|
||
}
|
||
}
|
||
|
||
resp := "OK\n"
|
||
if _, err := conn.WriteToUDP([]byte(resp), addr); err != nil {
|
||
Logger.Printf("发送响应到UDP客户端 %s 失败: %v", remoteAddr, err)
|
||
}
|
||
|
||
// 已移除客户端在线追踪
|
||
}
|