dndmusicbot/ws.go

119 lines
2.2 KiB
Go
Raw Normal View History

2022-11-18 12:29:39 +00:00
package main
import (
"context"
"encoding/json"
"log"
"net/http"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/grafov/bcast"
"github.com/kataras/go-events"
)
func init() {
log.Println("ws.go loading..")
go ws_clients.Broadcast(0)
ws_msg = make(chan interface{})
go func() {
for {
select {
case msg := <-ws_msg:
ws_clients.Send(msg)
}
}
}()
// Since httprouter seems to not like doing websocket stuff, we run a seperate server for it.. for now..
go func() {
app.mux.HandleFunc("/ws", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("WS connection from %v\n", r.RemoteAddr)
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
err = handleWS(conn)
if err != nil {
log.Printf("WS connection closed, %v\n", r.RemoteAddr)
}
}))
}()
log.Println("ws.go done.")
}
type WSmsg struct {
Event string
Payload json.RawMessage
}
var ws_clients = bcast.NewGroup()
var ws_msg chan interface{}
var WSMutex = &sync.Mutex{}
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func handleWS(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 := app.songInfoEvent("song_info")
c.SetWriteDeadline(time.Now().Add(10 * time.Second))
c.WriteJSON(msg)
if app.ambiance.IsPlaying() {
msg := make(map[string]interface{})
out := make(map[string]interface{})
msg["event"] = "ambiance_play"
out["type"] = app.curamb
msg["payload"] = out
c.WriteJSON(msg)
} else {
msg := make(map[string]interface{})
msg["event"] = "ambiance_stop"
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)
}
}