entropy/ws.go

84 lines
1.7 KiB
Go

package main
import (
"io"
"log"
"net/http"
"sync"
"github.com/gorilla/websocket"
)
type WS struct {
upgrader websocket.Upgrader
pools *sync.Map
}
func NewWS() *WS {
return &WS{
upgrader: websocket.Upgrader{
ReadBufferSize: 10240,
WriteBufferSize: 10240,
CheckOrigin: func(_ *http.Request) bool { return true },
},
pools: &sync.Map{},
}
}
func (ws *WS) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := ws.serveHTTP(w, r); err != nil {
log.Println(r.URL.Path, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (ws *WS) serveHTTP(w http.ResponseWriter, r *http.Request) error {
log.Println("ws serve http", r.URL.Path)
pooli, ok := ws.pools.Load(r.URL.Path)
if !ok {
pooli = NewPool()
}
pool := pooli.(*Pool)
log.Println("ws upgrade")
conn, err := ws.upgrader.Upgrade(w, r, nil)
if err != nil {
return err
}
log.Println("ws next reader")
mt, _, err := conn.NextReader()
if err != nil {
return err
}
log.Println("funcs")
go func() {
for {
_, r, err := conn.NextReader()
if err != nil {
panic(err)
}
log.Println("copying to pool...")
if _, err := io.Copy(pool, r); err != nil {
panic(err)
}
log.Println("/copying to pool...")
}
}()
func() {
for {
w, err := conn.NextWriter(mt)
if err != nil {
panic(err)
}
log.Println("copying from pool...")
if _, err := io.Copy(w, pool); err != nil { // todo impl broadcast to channel;; sync map to all channels, goes to a forking reader-writer pipe, all listeners to broadcast read from pipe
panic(err)
}
log.Println("/copying from pool...")
if err := w.Close(); err != nil {
panic(err)
}
}
}()
return nil
}