82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type Broker struct {
|
|
sockets map[*websocket.Conn]struct{}
|
|
sync.Mutex
|
|
}
|
|
|
|
var upgrader = websocket.Upgrader{
|
|
ReadBufferSize: 128,
|
|
WriteBufferSize: 128,
|
|
}
|
|
|
|
var broker Broker
|
|
|
|
//go:embed index.html
|
|
var static embed.FS
|
|
|
|
func actionBroker(w http.ResponseWriter, r *http.Request) {
|
|
conn, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
log.Printf("failed to fulfill client request for playPauseBroker: %v", err)
|
|
return
|
|
}
|
|
|
|
broker.Lock()
|
|
broker.sockets[conn] = struct{}{}
|
|
log.Printf("broker currently handles %d clients", len(broker.sockets))
|
|
broker.Unlock()
|
|
|
|
for {
|
|
messageType, p, err := conn.ReadMessage()
|
|
if err != nil {
|
|
log.Printf("failed to read message from client %p: %v", conn, err)
|
|
log.Printf("will attempt to close connection %p", conn)
|
|
if err := conn.Close(); err != nil {
|
|
log.Printf("failed to close connection at %p", conn)
|
|
}
|
|
delete(broker.sockets, conn)
|
|
return
|
|
}
|
|
|
|
for client := range broker.sockets {
|
|
if client == conn {
|
|
continue // prevent self echo
|
|
}
|
|
|
|
if err := client.WriteMessage(messageType, p); err != nil {
|
|
log.Printf("while sending: %s to client %p: %v", p, client, err)
|
|
}
|
|
log.Printf("successfully sent %s", p)
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
listenPort := flag.Uint("port", 8000, "port to listen on")
|
|
flag.Parse()
|
|
streamFile := flag.Arg(0)
|
|
if streamFile == "" {
|
|
log.Fatal("stream file is undefined")
|
|
}
|
|
broker.sockets = make(map[*websocket.Conn]struct{})
|
|
http.Handle("/stream/", http.StripPrefix("/stream/", http.FileServer(http.Dir(streamFile))))
|
|
http.HandleFunc("/broker", actionBroker)
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFileFS(w, r, static, "index.html")
|
|
})
|
|
|
|
panic(http.ListenAndServe(fmt.Sprintf(":%d", *listenPort), nil))
|
|
}
|