73 lines
1.1 KiB
Go
73 lines
1.1 KiB
Go
|
|
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)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|