dndmusicbot/ws.go

111 lines
1.8 KiB
Go

package main
import (
"context"
"encoding/json"
"log"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/grafov/bcast"
"github.com/kataras/go-events"
)
type Websocket struct {
sync.Mutex
clients *bcast.Group
}
var ws *Websocket
func init() {
log.Println("ws.go loading..")
ws = new(Websocket)
ws.clients = bcast.NewGroup()
go ws.clients.Broadcast(0)
log.Println("ws.go done.")
}
type WSmsg struct {
Event string
Payload json.RawMessage
}
type Event struct {
Event string `json:"event"`
Payload any `json:"payload,omitempty"`
}
func (ws *Websocket) SendEvent(e Event) {
ws.Lock()
ws.clients.Send(e)
ws.Unlock()
}
func (ws *Websocket) join(c *websocket.Conn) error {
memb := ws.clients.Join()
defer memb.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
ticker := time.NewTicker(30 * time.Second)
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
c.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(10*time.Second))
case msg := <-memb.Read:
c.SetWriteDeadline(time.Now().Add(10 * time.Second))
c.WriteJSON(msg)
}
}
}()
c.SetPongHandler(func(d string) error {
return nil
})
msg, err := app.songInfoEvent("song_info")
if err != nil {
return err
}
vol := Event{"volume", map[string]float64{
"playlist": pl_volume.Volume,
"ambiance": amb_volume.Volume,
}}
c.SetWriteDeadline(time.Now().Add(10 * time.Second))
c.WriteJSON(msg)
c.WriteJSON(vol)
if app.ambiance.Len() > 0 {
msg := Event{"ambiance_play", map[string]string{
"id": app.curamb.Id,
}}
c.WriteJSON(msg)
} else {
msg := Event{"ambiance_stop", nil}
c.WriteJSON(msg)
}
for {
var msg WSmsg
err := c.ReadJSON(&msg)
if err != nil {
return err
}
app.events.Emit(events.EventName(msg.Event), msg.Payload, memb)
}
}