actions.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package server
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/felamaslen/gmus-backend/pkg/logger"
  7. "github.com/go-playground/validator/v10"
  8. "github.com/go-redis/redis"
  9. )
  10. type ActionType string
  11. const (
  12. StateSet ActionType = "STATE_SET"
  13. ClientListUpdated ActionType = "CLIENT_LIST_UPDATED"
  14. )
  15. type Action struct {
  16. Type ActionType `json:"type"`
  17. FromClient *string `json:"fromClient"`
  18. Payload interface{} `json:"payload"`
  19. }
  20. func BroadcastAction(l *logger.Logger, thisPodClients *map[string]*Client, action *Action) []error {
  21. var errors []error
  22. for _, client := range *thisPodClients {
  23. l.Debug("[->Client] %s (%s)\n", action.Type, client.name)
  24. if err := client.send(action); err != nil {
  25. errors = append(errors, err)
  26. }
  27. }
  28. return errors
  29. }
  30. func validateAction(action *Action) (validatedAction *Action, err error) {
  31. switch action.Type {
  32. case StateSet:
  33. var remarshaledPayload []byte
  34. remarshaledPayload, err = json.Marshal(action.Payload)
  35. if err != nil {
  36. return
  37. }
  38. var playerState MusicPlayer
  39. err = json.Unmarshal(remarshaledPayload, &playerState)
  40. if err != nil {
  41. return
  42. }
  43. v := validator.New()
  44. err = v.Struct(playerState)
  45. if err != nil {
  46. err = errors.New(err.Error())
  47. return
  48. }
  49. validatedAction = &Action{
  50. Type: StateSet,
  51. FromClient: action.FromClient,
  52. Payload: playerState,
  53. }
  54. return
  55. default:
  56. err = errors.New(fmt.Sprintf("Invalid client action type: %s", action.Type))
  57. return
  58. }
  59. }
  60. func PublishAction(rdb redis.Cmdable, action []byte) error {
  61. if _, err := rdb.Publish(TOPIC_BROADCAST, action).Result(); err != nil {
  62. return err
  63. }
  64. return nil
  65. }
  66. func PublishActionFromClient(rdb redis.Cmdable, action *Action) error {
  67. validatedAction, validationErr := validateAction(action)
  68. if validationErr != nil {
  69. return validationErr
  70. }
  71. pubsubPayload, err := json.Marshal(validatedAction)
  72. if err != nil {
  73. return err
  74. }
  75. return PublishAction(rdb, pubsubPayload)
  76. }