diff --git a/.github/workflows/release-go.yml b/.github/workflows/release-go.yml index 1628d87..f908df7 100644 --- a/.github/workflows/release-go.yml +++ b/.github/workflows/release-go.yml @@ -1,8 +1,8 @@ name: Go Server Only Build on: workflow_dispatch: - push: - branches: ["main"] + schedule: + - cron: '0 2 * * *' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true diff --git a/client.go b/client.go index b9e560f..dcfa6d1 100644 --- a/client.go +++ b/client.go @@ -4,6 +4,7 @@ import ( "encoding/json" "log" "net/http" + "strings" "sync" "time" @@ -79,51 +80,44 @@ func (c *Client) readPump() { // Handle normal WebSocket close events if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) { log.Printf("WebSocket closed by client: %v", c.conn.RemoteAddr()) + } else if strings.Contains(err.Error(), "connection reset by peer") { + // Suppress log for expected errors + log.Printf("Connection reset by peer for client: %v. Cleaning up.", c.conn.RemoteAddr()) } else { log.Printf("Error reading message from client: %v, err: %v", c.conn.RemoteAddr(), err) } - return // Exit on read error + return // Exit on any read error } + // Handle valid messages switch messageType { - case websocket.TextMessage: // JSON or plain text + case websocket.TextMessage: + // Process text messages var message map[string]interface{} if err := json.Unmarshal(rawMessage, &message); err != nil { log.Printf("Invalid JSON from client: %v, message: %s, err: %v", c.conn.RemoteAddr(), string(rawMessage), err) - continue // Skip invalid JSON messages + continue // Skip invalid JSON } - action, _ := message["action"].(string) - channel, _ := message["channel"].(string) - - if action == "" || channel == "" { - continue - } switch action { case "ping": if err := c.conn.WriteMessage(websocket.TextMessage, []byte(`{"action":"pong"}`)); err != nil { - log.Printf("Error sending pong to client: %v, err: %v", c.conn.RemoteAddr(), err) return } - - case "subscribe": - c.hub.register <- &Subscription{Client: c, Channel: channel} - - case "unsubscribe": - c.hub.unregister <- &Subscription{Client: c, Channel: channel} - - case "message": - payload := message["payload"] - msg := Message{ - Channel: channel, - Event: "message", - Payload: payload, - } - c.hub.broadcast <- msg - default: + log.Printf("Unhandled action: %s", action) + } + + case websocket.PingMessage: + // Reply to WebSocket ping frames + if err := c.conn.WriteMessage(websocket.PongMessage, nil); err != nil { + log.Printf("Error responding to ping from client: %v, err: %v", c.conn.RemoteAddr(), err) + return } + + default: + log.Printf("Unsupported message type from client: %v, type: %d", c.conn.RemoteAddr(), messageType) } } } diff --git a/ts-client/src/index.ts b/ts-client/src/index.ts index cec905e..e38b7c6 100644 --- a/ts-client/src/index.ts +++ b/ts-client/src/index.ts @@ -172,7 +172,7 @@ export class SocketClient { if (this.heartbeatTimer) clearInterval(this.heartbeatTimer); this.heartbeatTimer = setInterval(() => { if (this.socket && this.socket.readyState === WebSocket.OPEN) { - this.send({ action: 'ping' }); + this.send(''); } }, this.heartbeatInterval);