websocket first version

main
nilo 2025-05-21 11:32:09 -03:00
parent f4647668c0
commit 84de38de26
4 changed files with 140 additions and 0 deletions

View File

@ -0,0 +1,119 @@
package controllers
import (
"encoding/json"
"log"
"sync"
"github.com/gofiber/websocket/v2"
)
// WebSocketManager handles all active WebSocket connections
type WebSocketManager struct {
connections map[*websocket.Conn]bool
mutex sync.RWMutex
}
// WebSocketMessage represents the structure of messages
type WebSocketMessage struct {
Command string `json:"command"`
Channel string `json:"channel"`
Text string `json:"text"`
}
// Global instance of WebSocketManager
var WSManager = &WebSocketManager{
connections: make(map[*websocket.Conn]bool),
}
// BroadcastMessage sends a message to all connected clients
func (m *WebSocketManager) BroadcastMessage(command, channel, text string) {
message := WebSocketMessage{
Command: command,
Channel: channel,
Text: text,
}
jsonMessage, err := json.Marshal(message)
if err != nil {
log.Printf("Error marshaling message: %v", err)
return
}
m.mutex.RLock()
defer m.mutex.RUnlock()
for conn := range m.connections {
if err := conn.WriteMessage(websocket.TextMessage, jsonMessage); err != nil {
log.Printf("Error broadcasting message: %v", err)
// Remove failed connection
m.mutex.RUnlock()
m.removeConnection(conn)
m.mutex.RLock()
}
}
}
// SendMessageToClient sends a message to a specific client
func (m *WebSocketManager) SendMessageToClient(conn *websocket.Conn, command, channel, text string) error {
message := WebSocketMessage{
Command: command,
Channel: channel,
Text: text,
}
jsonMessage, err := json.Marshal(message)
if err != nil {
return err
}
m.mutex.RLock()
defer m.mutex.RUnlock()
if _, exists := m.connections[conn]; exists {
return conn.WriteMessage(websocket.TextMessage, jsonMessage)
}
return nil
}
func (m *WebSocketManager) addConnection(conn *websocket.Conn) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.connections[conn] = true
}
func (m *WebSocketManager) removeConnection(conn *websocket.Conn) {
m.mutex.Lock()
defer m.mutex.Unlock()
delete(m.connections, conn)
conn.Close()
}
// WebsocketHandler handles WebSocket connections
func WebsocketHandler(c *websocket.Conn) {
// Add the connection to our manager
WSManager.addConnection(c)
defer WSManager.removeConnection(c)
// Handle incoming messages
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("Error reading message:", err)
break
}
// Try to parse the incoming message as JSON
var wsMessage WebSocketMessage
if err := json.Unmarshal(message, &wsMessage); err != nil {
log.Printf("Error parsing message: %v", err)
continue
}
// Echo the message back to the client
if err := WSManager.SendMessageToClient(c, wsMessage.Command, wsMessage.Channel, wsMessage.Text); err != nil {
log.Println("Error writing message:", err)
break
}
}
}

3
go.mod
View File

@ -4,6 +4,7 @@ go 1.22
require (
github.com/gofiber/fiber/v2 v2.50.0
github.com/gofiber/websocket/v2 v2.2.1
github.com/shirou/gopsutil/v3 v3.23.10
github.com/spf13/viper v1.17.0
golang.org/x/crypto v0.15.0
@ -14,6 +15,7 @@ require (
require (
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/fasthttp/websocket v1.5.3 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/google/uuid v1.4.0 // indirect
@ -36,6 +38,7 @@ require (
github.com/rivo/uniseg v0.4.4 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect

6
go.sum
View File

@ -58,6 +58,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek=
github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
@ -70,6 +72,8 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/gofiber/fiber/v2 v2.50.0 h1:ia0JaB+uw3GpNSCR5nvC5dsaxXjRU5OEu36aytx+zGw=
github.com/gofiber/fiber/v2 v2.50.0/go.mod h1:21eytvay9Is7S6z+OgPi7c7n4++tnClWmhpimVHMimw=
github.com/gofiber/websocket/v2 v2.2.1 h1:C9cjxvloojayOp9AovmpQrk8VqvVnT8Oao3+IUygH7w=
github.com/gofiber/websocket/v2 v2.2.1/go.mod h1:Ao/+nyNnX5u/hIFPuHl28a+NIkrqK7PRimyKaj4JxVU=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -196,6 +200,8 @@ github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9c
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
github.com/shirou/gopsutil/v3 v3.23.10 h1:/N42opWlYzegYaVkWejXWJpbzKv2JDy3mrgGzKsh9hM=
github.com/shirou/gopsutil/v3 v3.23.10/go.mod h1:JIE26kpucQi+innVlAUnIEOSBhBUkirr5b44yr55+WE=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=

View File

@ -4,6 +4,7 @@ import (
"api/controllers"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/websocket/v2"
)
// Setup sets up the routes
@ -28,4 +29,15 @@ func Setup(app *fiber.App) {
app.Post("/on_pub_start", controllers.OnPubStart)
app.Post("/on_pub_stop", controllers.OnPubStop)
// app.Post("/on_sub_start", controllers.OnSubStart)
// WebSocket route
app.Use("/ws", func(c *fiber.Ctx) error {
if websocket.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})
app.Get("/ws", websocket.New(controllers.WebsocketHandler))
}