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 } } }