broadcast.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package broadcast
  2. import (
  3. "encoding/json"
  4. "goseg/structs"
  5. "log/slog"
  6. "os"
  7. "reflect"
  8. "sync"
  9. "fmt"
  10. "github.com/gorilla/websocket"
  11. )
  12. var (
  13. logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
  14. clients = make(map[*websocket.Conn]bool)
  15. broadcastState structs.AuthBroadcast
  16. mu sync.RWMutex // synchronize access to broadcastState
  17. )
  18. func init(){
  19. // initialize broadcastState global var
  20. return
  21. }
  22. // adds ws client
  23. func RegisterClient(conn *websocket.Conn) {
  24. clients[conn] = true
  25. }
  26. // remove ws client
  27. func UnregisterClient(conn *websocket.Conn) {
  28. delete(clients, conn)
  29. }
  30. // update broadcastState with a map of items
  31. func UpdateStateWithMap(values map[string]interface{}) error {
  32. mu.Lock()
  33. defer mu.Unlock()
  34. v := reflect.ValueOf(&broadcastState).Elem()
  35. for key, value := range values {
  36. // we are matching the map key with the broadcastState item
  37. field := v.FieldByName(key)
  38. if !field.IsValid() || !field.CanSet() {
  39. return fmt.Errorf("field %s does not exist or is not settable", key)
  40. }
  41. val := reflect.ValueOf(value)
  42. if field.Type() != val.Type() {
  43. return fmt.Errorf("type mismatch for field %s: expected %s, got %s", key, field.Type(), val.Type())
  44. }
  45. field.Set(val)
  46. }
  47. BroadcastToClients()
  48. return nil
  49. }
  50. // return broadcast state
  51. func GetState() structs.AuthBroadcast {
  52. mu.Lock()
  53. defer mu.Unlock()
  54. return broadcastState
  55. }
  56. // broadcast the global state to all clients
  57. func BroadcastToClients() error {
  58. broadcastJson, err := json.Marshal(broadcastState)
  59. if err != nil {
  60. logger.Error("Error marshalling response:", err)
  61. return err
  62. }
  63. for client := range clients {
  64. if err := client.WriteMessage(websocket.TextMessage, broadcastJson); err != nil {
  65. logger.Error("Error writing response:", err)
  66. return err
  67. }
  68. }
  69. return nil
  70. }