fix: 去除无用注释
This commit is contained in:
parent
e87a10c08f
commit
86f731b76c
18
db.go
18
db.go
@ -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`
|
||||||
|
|||||||
@ -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
110
logger.go
@ -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)
|
}
|
||||||
}
|
}
|
||||||
}
|
}()
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|||||||
7
main.go
7
main.go
@ -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()
|
||||||
|
|||||||
327
tcp_server.go
327
tcp_server.go
@ -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()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user