84 lines
1.7 KiB
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
|
|
}
|