Skip to content

Commit eb8322b

Browse files
committed
Update.
1 parent 304c23a commit eb8322b

File tree

3 files changed

+312
-54
lines changed

3 files changed

+312
-54
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ server
2525
scripts/monitor_goroutines.sh
2626
FIXES_APPLIED.md
2727
debug_monitor.sh
28+
test_websocket.sh

cmd/dashboard/controller/common_page.go

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package controller
22

33
import (
44
"context"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"log"
@@ -1141,6 +1142,9 @@ func (cp *commonPage) ws(c *gin.Context) {
11411142
CheckOrigin: func(r *http.Request) bool {
11421143
return true
11431144
},
1145+
// 添加缓冲区大小配置
1146+
ReadBufferSize: 1024,
1147+
WriteBufferSize: 1024,
11441148
}
11451149
conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
11461150
if err != nil {
@@ -1151,8 +1155,19 @@ func (cp *commonPage) ws(c *gin.Context) {
11511155
// 使用正确的构造函数
11521156
safeConn := websocketx.NewConn(conn)
11531157

1158+
// 设置连接参数
1159+
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
1160+
conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
1161+
1162+
// 设置ping/pong处理
1163+
conn.SetPongHandler(func(string) error {
1164+
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
1165+
return nil
1166+
})
1167+
11541168
// 使用一个channel来通知写入goroutine退出
11551169
done := make(chan struct{})
1170+
lastActivity := time.Now()
11561171

11571172
// Read goroutine
11581173
go func() {
@@ -1161,35 +1176,76 @@ func (cp *commonPage) ws(c *gin.Context) {
11611176
safeConn.Close()
11621177
}()
11631178
for {
1164-
// 我们需要从连接中读取,以检测客户端是否已断开连接。
1165-
// 我们不需要处理任何传入的消息。
1166-
if _, _, err := safeConn.ReadMessage(); err != nil {
1179+
// 设置读取超时
1180+
conn.SetReadDeadline(time.Now().Add(60 * time.Second))
1181+
1182+
messageType, message, err := safeConn.ReadMessage()
1183+
if err != nil {
11671184
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
11681185
log.Printf("NG-ERROR: websocket read error: %v", err)
11691186
}
11701187
break // 退出循环
11711188
}
1189+
1190+
// 更新活动时间
1191+
lastActivity = time.Now()
1192+
1193+
// 处理客户端ping消息
1194+
if messageType == websocket.TextMessage {
1195+
var msg map[string]interface{}
1196+
if err := json.Unmarshal(message, &msg); err == nil {
1197+
if msgType, ok := msg["type"].(string); ok && msgType == "ping" {
1198+
// 发送pong响应
1199+
pongMsg := map[string]interface{}{"type": "pong", "timestamp": time.Now().Unix()}
1200+
if pongData, err := json.Marshal(pongMsg); err == nil {
1201+
safeConn.WriteMessage(websocket.TextMessage, pongData)
1202+
}
1203+
}
1204+
}
1205+
}
11721206
}
11731207
}()
11741208

11751209
// Write goroutine
11761210
go func() {
1177-
ticker := time.NewTicker(time.Second * 1) // 从5秒改为1秒,提高更新频率
1178-
defer ticker.Stop()
1211+
ticker := time.NewTicker(time.Second * 1) // 1秒更新间隔,提供更好的实时性
1212+
pingTicker := time.NewTicker(time.Second * 30) // 30秒心跳间隔
1213+
defer func() {
1214+
ticker.Stop()
1215+
pingTicker.Stop()
1216+
}()
1217+
11791218
for {
11801219
select {
11811220
case <-done: // 从读取goroutine接收到退出信号
11821221
return
1222+
case <-pingTicker.C:
1223+
// 发送ping消息保持连接活跃
1224+
conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
1225+
if err := safeConn.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
1226+
log.Printf("发送ping消息失败: %v", err)
1227+
return
1228+
}
1229+
1230+
// 检查连接是否长时间无活动
1231+
if time.Since(lastActivity) > 90*time.Second {
1232+
log.Printf("WebSocket连接长时间无活动,主动关闭")
1233+
return
1234+
}
1235+
11831236
case <-ticker.C:
11841237
stat, err := cp.getServerStat(c, false)
11851238
if err != nil {
11861239
log.Printf("NG-ERROR: failed to get server stat for websocket: %v", err)
11871240
// 不要退出,让 done channel 处理终止
11881241
continue
11891242
}
1243+
1244+
// 设置写入超时
1245+
conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
11901246
if err = safeConn.WriteMessage(websocket.TextMessage, stat); err != nil {
11911247
// 写入失败,可能是因为连接已关闭。
1192-
// 读取goroutine将处理清理工作。我们可以在这里退出。
1248+
log.Printf("WebSocket写入失败: %v", err)
11931249
return
11941250
}
11951251
}

0 commit comments

Comments
 (0)