127 lines
3.4 KiB
Go
127 lines
3.4 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sync"
|
|
|
|
"gitea.tecamino.com/paadi/statusServer/models"
|
|
|
|
json_dataModels "gitea.tecamino.com/paadi/tecamino-json_data/models"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ClientHandler manages active websocket clients.
|
|
// - Keeps a map of connected clients (thread-safe).
|
|
// - Provides helper methods to connect, lookup, and send responses.
|
|
type ClientHandler struct {
|
|
sync.RWMutex // protects access to Clients map
|
|
clients models.Clients // map[string]*Client (id → client)
|
|
}
|
|
|
|
// SendBroadcast sends a raw message to all clients in the global Broadcast list.
|
|
// Note: uses `models.Broadcast` (separate global client slice).
|
|
func SendBroadcast(data []byte) {
|
|
for _, c := range models.Broadcast {
|
|
c.SendData(data)
|
|
}
|
|
}
|
|
|
|
// NewConnectionHandler creates and initializes a new ClientHandler
|
|
// with an empty client map.
|
|
func NewConnectionHandler() *ClientHandler {
|
|
return &ClientHandler{
|
|
clients: models.NewClients(),
|
|
}
|
|
}
|
|
|
|
// ConnectNewClient registers a new websocket client by ID.
|
|
// - If client with same ID already exists, returns the existing client.
|
|
// - Otherwise, creates a new connection and stores it in the handler map.
|
|
func (cH *ClientHandler) ConnectNewClient(id string, c *gin.Context) (client *models.Client, err error) {
|
|
// Check if client already exists (reuse connection).
|
|
if _, exists := cH.clients[id]; exists {
|
|
return cH.clients[id], nil
|
|
}
|
|
|
|
// Create a new websocket client instance.
|
|
client, err = models.ConnectNewClient(id, c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Ensure cleanup: when client disconnects, remove from map.
|
|
client.OnClose = func(code int, reason string) {
|
|
delete(cH.clients, id)
|
|
}
|
|
|
|
// Add client to handler map.
|
|
cH.Lock()
|
|
cH.clients[id] = client
|
|
cH.Unlock()
|
|
|
|
return client, nil
|
|
}
|
|
|
|
// GetClient retrieves a client by ID.
|
|
// Returns nil if client does not exist.
|
|
func (c *ClientHandler) GetClient(id string) *models.Client {
|
|
if client, ok := c.clients[id]; ok {
|
|
return client
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cH *ClientHandler) RemoveClient(id string) {
|
|
delete(cH.clients, id)
|
|
}
|
|
|
|
// SendResponse sends a structured JSON response to a given client by ID.
|
|
// - If client is not found, returns error.
|
|
// - Otherwise marshals the Response and sends via websocket.
|
|
func (c *ClientHandler) SendResponse(id string, r *json_dataModels.Response) error {
|
|
client, ok := c.clients[id]
|
|
if !ok {
|
|
return fmt.Errorf("client not found for id %s", id)
|
|
}
|
|
|
|
// Encode response to JSON.
|
|
b, err := json.Marshal(*r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Send JSON payload over websocket.
|
|
client.SendData(b)
|
|
|
|
return nil
|
|
}
|
|
|
|
// --- Sending helpers (proxy to server messaging system) ---
|
|
|
|
// SendInfo sends an "info" log message to the server.
|
|
func (c *ClientHandler) SendInfo(id string, data any) error {
|
|
return c.clients[id].SendInfo(data)
|
|
}
|
|
|
|
// SendInfo sends an "info" log message to the server.
|
|
func (c *ClientHandler) SendStatus(id string, data any) error {
|
|
return c.clients[id].SendStatus(data)
|
|
}
|
|
|
|
// SendDebug sends a "debug" log message to the server.
|
|
func (c *ClientHandler) SendDebug(id string, data any) error {
|
|
return c.clients[id].SendDebug(data)
|
|
}
|
|
|
|
// SendWarning sends a "warning" log message to the server.
|
|
func (c *ClientHandler) SendWarning(id string, data any) error {
|
|
return c.clients[id].SendWarning(data)
|
|
}
|
|
|
|
// SendError sends an "error" log message to the server.
|
|
func (c *ClientHandler) SendError(id string, data any) error {
|
|
return c.clients[id].SendError(data)
|
|
}
|