90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
package pddapi
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
// 定义一个客户端结构体,保存每个客户端的信息
|
|
type Client struct {
|
|
conn net.Conn
|
|
lastActive time.Time // 记录最后活跃时间,用于心跳检测
|
|
}
|
|
|
|
// 处理客户端消息的函数
|
|
func (c *Client) handleConnection() {
|
|
defer c.conn.Close()
|
|
|
|
reader := bufio.NewReader(c.conn)
|
|
for {
|
|
// 检查是否超时
|
|
if time.Since(c.lastActive) > 30*time.Second {
|
|
fmt.Printf("Client %s timed out\n", c.conn.RemoteAddr())
|
|
return
|
|
}
|
|
|
|
message, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
fmt.Printf("Error reading from %s: %v\n", c.conn.RemoteAddr(), err)
|
|
return
|
|
}
|
|
fmt.Printf("Received from %s: %s", c.conn.RemoteAddr(), message)
|
|
|
|
// 更新最后活跃时间
|
|
c.lastActive = time.Now()
|
|
|
|
// 发送响应给客户端
|
|
c.conn.Write([]byte("Message received\n"))
|
|
}
|
|
}
|
|
|
|
// 心跳检测函数
|
|
func (c *Client) heartbeat() {
|
|
ticker := time.NewTicker(10 * time.Second)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
// 发送心跳包
|
|
_, err := c.conn.Write([]byte("heartbeat\n"))
|
|
if err != nil {
|
|
fmt.Printf("Error sending heartbeat to %s: %v\n", c.conn.RemoteAddr(), err)
|
|
return
|
|
}
|
|
// 更新最后活跃时间
|
|
c.lastActive = time.Now()
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
listener, err := net.Listen("tcp", ":8080")
|
|
if err != nil {
|
|
fmt.Println("Error starting server:", err)
|
|
return
|
|
}
|
|
defer listener.Close()
|
|
fmt.Println("Server listening on :8080")
|
|
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
fmt.Println("Error accepting connection:", err)
|
|
continue
|
|
}
|
|
|
|
client := &Client{
|
|
conn: conn,
|
|
lastActive: time.Now(),
|
|
}
|
|
|
|
// 启动一个新的goroutine处理每个连接
|
|
go client.handleConnection()
|
|
|
|
// 启动心跳检测goroutine
|
|
go client.heartbeat()
|
|
}
|
|
}
|