fix(websocket): errors in saving client info during ping ping
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
||||
"lst.net/utils/db"
|
||||
logging "lst.net/utils/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -30,7 +32,8 @@ type Client struct {
|
||||
ConnectedAt time.Time `json:"connected_at"`
|
||||
done chan struct{} // For graceful shutdown
|
||||
isAlive atomic.Bool
|
||||
//mu sync.Mutex // Protects isAlive if not using atomic
|
||||
lastActive time.Time // Tracks last activity
|
||||
|
||||
}
|
||||
|
||||
func (c *Client) SaveToDB() {
|
||||
@@ -59,7 +62,10 @@ func (c *Client) SaveToDB() {
|
||||
}
|
||||
|
||||
func (c *Client) MarkDisconnected() {
|
||||
log.Printf("Client %v just lefts us", c.ClientID)
|
||||
logger := logging.New()
|
||||
clientData := fmt.Sprintf("Client %v just lefts us", c.ClientID)
|
||||
logger.Info(clientData, "websocket", map[string]interface{}{})
|
||||
|
||||
now := time.Now()
|
||||
res := db.DB.Model(&db.ClientRecord{}).
|
||||
Where("client_id = ?", c.ClientID).
|
||||
@@ -68,10 +74,17 @@ func (c *Client) MarkDisconnected() {
|
||||
})
|
||||
|
||||
if res.RowsAffected == 0 {
|
||||
log.Println("⚠️ No rows updated for client_id:", c.ClientID)
|
||||
|
||||
logger.Info("⚠️ No rows updated for client_id", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
})
|
||||
}
|
||||
if res.Error != nil {
|
||||
log.Println("❌ Error updating disconnected_at:", res.Error)
|
||||
|
||||
logger.Error("❌ Error updating disconnected_at", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
"error": res.Error,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +136,8 @@ const (
|
||||
)
|
||||
|
||||
func (c *Client) StartHeartbeat() {
|
||||
logger := logging.New()
|
||||
log.Println("Started hearbeat")
|
||||
ticker := time.NewTicker(pingPeriod)
|
||||
defer ticker.Stop()
|
||||
|
||||
@@ -140,6 +155,27 @@ func (c *Client) StartHeartbeat() {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
res := db.DB.Model(&db.ClientRecord{}).
|
||||
Where("client_id = ?", c.ClientID).
|
||||
Updates(map[string]interface{}{
|
||||
"last_heartbeat": &now,
|
||||
})
|
||||
|
||||
if res.RowsAffected == 0 {
|
||||
|
||||
logger.Info("⚠️ No rows updated for client_id", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
})
|
||||
}
|
||||
if res.Error != nil {
|
||||
|
||||
logger.Error("❌ Error updating disconnected_at", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
"error": res.Error,
|
||||
})
|
||||
}
|
||||
|
||||
case <-c.done:
|
||||
return
|
||||
}
|
||||
@@ -155,6 +191,75 @@ func (c *Client) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) startServerPings() {
|
||||
ticker := time.NewTicker(60 * time.Second) // Ping every 30s
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
c.Conn.SetWriteDeadline(time.Now().Add(10 * time.Second))
|
||||
if err := c.Conn.WriteMessage(websocket.PingMessage, nil); err != nil {
|
||||
c.Close() // Disconnect if ping fails
|
||||
return
|
||||
}
|
||||
case <-c.done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) markActive() {
|
||||
c.lastActive = time.Now() // No mutex needed if single-writer
|
||||
}
|
||||
|
||||
func (c *Client) IsActive() bool {
|
||||
return time.Since(c.lastActive) < 45*time.Second // 1.5x ping interval
|
||||
}
|
||||
|
||||
func (c *Client) updateHeartbeat() {
|
||||
//fmt.Println("Updating heatbeat")
|
||||
now := time.Now()
|
||||
logger := logging.New()
|
||||
|
||||
//fmt.Printf("Updating heartbeat for client: %s at %v\n", c.ClientID, now)
|
||||
|
||||
//db.DB = db.DB.Debug()
|
||||
res := db.DB.Model(&db.ClientRecord{}).
|
||||
Where("client_id = ?", c.ClientID).
|
||||
Updates(map[string]interface{}{
|
||||
"last_heartbeat": &now, // Explicit format
|
||||
})
|
||||
//fmt.Printf("Executed SQL: %v\n", db.DB.Statement.SQL.String())
|
||||
if res.RowsAffected == 0 {
|
||||
|
||||
logger.Info("⚠️ No rows updated for client_id", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
})
|
||||
}
|
||||
if res.Error != nil {
|
||||
|
||||
logger.Error("❌ Error updating disconnected_at", "websocket", map[string]interface{}{
|
||||
"clientID": c.ClientID,
|
||||
"error": res.Error,
|
||||
})
|
||||
}
|
||||
// 2. Verify DB connection
|
||||
if db.DB == nil {
|
||||
logger.Error("DB connection is nil", "websocket", map[string]interface{}{})
|
||||
return
|
||||
}
|
||||
|
||||
// 3. Test raw SQL execution first
|
||||
testRes := db.DB.Exec("SELECT 1")
|
||||
if testRes.Error != nil {
|
||||
logger.Error("DB ping failed", "websocket", map[string]interface{}{
|
||||
"error": testRes.Error,
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// work on this stats later
|
||||
// Add to your admin endpoint
|
||||
// type ConnectionStats struct {
|
||||
|
||||
Reference in New Issue
Block a user