63 lines
1.2 KiB
Go
Executable File
63 lines
1.2 KiB
Go
Executable File
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"sync"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type WS struct {
|
|
upgrader websocket.Upgrader
|
|
pools *sync.Map
|
|
}
|
|
|
|
func NewWS() *WS {
|
|
return &WS{
|
|
upgrader: websocket.Upgrader{
|
|
ReadBufferSize: 16384,
|
|
WriteBufferSize: 16384,
|
|
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 {
|
|
id := getCookie(r, "id")
|
|
if len(id) == 0 {
|
|
id = uuid.New().String()
|
|
}
|
|
log.Println("found id", id)
|
|
log.Println("ws serve http", r.URL.Path)
|
|
pooli, ok := ws.pools.Load(r.URL.Path)
|
|
if !ok {
|
|
pooli = NewPool()
|
|
ws.pools.Store(r.URL.Path, pooli.(*Pool))
|
|
}
|
|
pool := pooli.(*Pool)
|
|
conn, err := ws.upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pool.Push(id, conn) // conns.Store(id, conn)
|
|
for {
|
|
mt, reader, err := conn.NextReader()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := pool.Broadcast(mt, reader); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|