This commit is contained in:
ryan
2026-06-19 15:13:24 +08:00
parent 0b34792709
commit 32861c5db9
376 changed files with 3648 additions and 19957 deletions
@@ -1,6 +1,7 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
// Package websocket manages persistent WebSocket connections between the OpenFlare server and its agents.
package websocket
import (
@@ -67,7 +68,7 @@ func ServeAgent(c *gin.Context, nodeID string, onStatus AgentStatusHandler) {
nodeID: nodeID,
remoteAddr: c.Request.RemoteAddr,
conn: conn,
send: make(chan Message, 16),
send: make(chan Message, wsChannelBuf),
done: make(chan struct{}),
onStatus: onStatus,
}
@@ -202,15 +203,15 @@ func (c *agentClient) readPump() {
}
func agentWSReadTimeout() time.Duration {
timeout := 90 * time.Second
if timeout < 30*time.Second {
return 30 * time.Second
timeout := wsReadDeadline
if timeout < minAgentWSReadTimeout {
return minAgentWSReadTimeout
}
return timeout
}
func (c *agentClient) writePump() {
ticker := time.NewTicker(30 * time.Second)
ticker := time.NewTicker(wsPingInterval)
defer ticker.Stop()
for {
@@ -218,7 +219,7 @@ func (c *agentClient) writePump() {
case <-c.done:
return
case message := <-c.send:
_ = c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
_ = c.conn.SetWriteDeadline(time.Now().Add(wsWriteDeadline))
if err := c.conn.WriteJSON(message); err != nil {
slog.Debug("agent ws write failed", "node_id", c.nodeID, "error", err)
c.close()
@@ -0,0 +1,14 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package websocket
import "time"
const (
wsChannelBuf = 16
wsPingInterval = 30 * time.Second
wsReadDeadline = 90 * time.Second
wsWriteDeadline = 10 * time.Second
minAgentWSReadTimeout = 30 * time.Second
)
@@ -4,7 +4,6 @@
package websocket
import (
"encoding/json"
"log/slog"
"sync"
"time"
@@ -58,7 +57,7 @@ func ServeFlared(c *gin.Context, nodeID string) {
client := &flaredClient{
nodeID: nodeID,
conn: conn,
send: make(chan Message, 16),
send: make(chan Message, wsChannelBuf),
done: make(chan struct{}),
}
defaultFlaredHub.register(client)
@@ -136,37 +135,11 @@ func SendFlaredPong(nodeID string) bool {
}
func (c *flaredClient) readPump() {
defer c.close()
_ = c.conn.SetReadDeadline(time.Now().Add(90 * time.Second))
c.conn.SetPongHandler(func(string) error {
return c.conn.SetReadDeadline(time.Now().Add(90 * time.Second))
})
for {
_, data, err := c.conn.ReadMessage()
if err != nil {
slog.Debug("flared ws read closed", "node_id", c.nodeID, "error", err)
return
}
var message Message
if err = json.Unmarshal(data, &message); err != nil {
slog.Debug("flared ws invalid message", "node_id", c.nodeID, "error", err)
continue
}
switch message.Type {
case messageTypePing:
_ = SendFlaredPong(c.nodeID)
case flaredMessageTypePong:
default:
slog.Debug("flared ws unsupported message", "node_id", c.nodeID, "type", message.Type)
}
}
runReadPump(c.nodeID, c.conn, c.close, "flared ws", SendFlaredPong, flaredMessageTypePong)
}
func (c *flaredClient) writePump() {
ticker := time.NewTicker(30 * time.Second)
ticker := time.NewTicker(wsPingInterval)
defer ticker.Stop()
for {
@@ -174,7 +147,7 @@ func (c *flaredClient) writePump() {
case <-c.done:
return
case message := <-c.send:
_ = c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
_ = c.conn.SetWriteDeadline(time.Now().Add(wsWriteDeadline))
if err := c.conn.WriteJSON(message); err != nil {
slog.Debug("flared ws write failed", "node_id", c.nodeID, "error", err)
c.close()
@@ -0,0 +1,49 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package websocket
import (
"encoding/json"
"log/slog"
"time"
"github.com/gorilla/websocket"
)
func runReadPump(
nodeID string,
conn *websocket.Conn,
closeFn func(),
logLabel string,
sendPong func(string) bool,
clientPongType string,
) {
defer closeFn()
_ = conn.SetReadDeadline(time.Now().Add(wsReadDeadline))
conn.SetPongHandler(func(string) error {
return conn.SetReadDeadline(time.Now().Add(wsReadDeadline))
})
for {
_, data, err := conn.ReadMessage()
if err != nil {
slog.Debug(logLabel+" read closed", "node_id", nodeID, "error", err)
return
}
var message Message
if err = json.Unmarshal(data, &message); err != nil {
slog.Debug(logLabel+" invalid message", "node_id", nodeID, "error", err)
continue
}
switch message.Type {
case messageTypePing:
_ = sendPong(nodeID)
case clientPongType:
default:
slog.Debug(logLabel+" unsupported message", "node_id", nodeID, "type", message.Type)
}
}
}
+4 -31
View File
@@ -4,7 +4,6 @@
package websocket
import (
"encoding/json"
"log/slog"
"sync"
"time"
@@ -52,7 +51,7 @@ func ServeRelay(c *gin.Context, nodeID string) {
client := &relayClient{
nodeID: nodeID,
conn: conn,
send: make(chan Message, 16),
send: make(chan Message, wsChannelBuf),
done: make(chan struct{}),
}
defaultRelayHub.register(client)
@@ -117,37 +116,11 @@ func SendRelayPong(nodeID string) bool {
}
func (c *relayClient) readPump() {
defer c.close()
_ = c.conn.SetReadDeadline(time.Now().Add(90 * time.Second))
c.conn.SetPongHandler(func(string) error {
return c.conn.SetReadDeadline(time.Now().Add(90 * time.Second))
})
for {
_, data, err := c.conn.ReadMessage()
if err != nil {
slog.Debug("relay ws read closed", "node_id", c.nodeID, "error", err)
return
}
var message Message
if err = json.Unmarshal(data, &message); err != nil {
slog.Debug("relay ws invalid message", "node_id", c.nodeID, "error", err)
continue
}
switch message.Type {
case messageTypePing:
_ = SendRelayPong(c.nodeID)
case messageTypePong:
default:
slog.Debug("relay ws unsupported message", "node_id", c.nodeID, "type", message.Type)
}
}
runReadPump(c.nodeID, c.conn, c.close, "relay ws", SendRelayPong, messageTypePong)
}
func (c *relayClient) writePump() {
ticker := time.NewTicker(30 * time.Second)
ticker := time.NewTicker(wsPingInterval)
defer ticker.Stop()
for {
@@ -155,7 +128,7 @@ func (c *relayClient) writePump() {
case <-c.done:
return
case message := <-c.send:
_ = c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
_ = c.conn.SetWriteDeadline(time.Now().Add(wsWriteDeadline))
if err := c.conn.WriteJSON(message); err != nil {
slog.Debug("relay ws write failed", "node_id", c.nodeID, "error", err)
c.close()