package www import ( "github.com/gorilla/websocket" ) type Socket struct { wsc *websocket.Conn send chan []byte bundle *Bundle closed bool } func makeSocket(c *websocket.Conn, b *Bundle) *Socket { s := &Socket { wsc: c, send: make(chan []byte, 1024), bundle: b, closed: false, } s.bundle.add <- s return s } func (s *Socket) close() { if !s.closed { pln("socket - close") close(s.send) s.wsc.Close() s.bundle.remove <- s s.closed = true } } type Bundle struct { socks map[*Socket]bool broadcast chan []byte add chan *Socket remove chan *Socket } func makeBundle() *Bundle { return &Bundle { socks: make(map[*Socket]bool), broadcast: make(chan []byte, 1024), add: make(chan *Socket), remove: make(chan *Socket), } } func (b *Bundle) process() { for { select { case sock := <-b.add: b.socks[sock] = true case sock := <-b.remove: if b.socks[sock] { delete(b.socks, sock) } case data := <-b.broadcast: for s := range b.socks { select { case s.send <- data: default: pln("bundle -- socket close") s.close() delete(b.socks, s) } } } } }