Files
gocommon/wshandler/room.go

85 lines
1.5 KiB
Go

package wshandler
import (
"context"
"encoding/json"
"github.com/gorilla/websocket"
"repositories.action2quare.com/ayo/gocommon/logger"
)
type room struct {
inChan chan *wsconn
outChan chan *wsconn
messageChan chan *UpstreamMessage
name string
}
func makeRoom(name string) *room {
return &room{
inChan: make(chan *wsconn, 10),
outChan: make(chan *wsconn, 10),
messageChan: make(chan *UpstreamMessage, 100),
name: name,
}
}
func (r *room) broadcast(msg *UpstreamMessage) {
r.messageChan <- msg
}
func (r *room) in(conn *wsconn) {
r.inChan <- conn
}
func (r *room) out(conn *wsconn) {
r.outChan <- conn
}
func (r *room) start(ctx context.Context) {
go func(ctx context.Context) {
conns := make(map[string]*wsconn)
normal := false
for !normal {
normal = r.loop(ctx, &conns)
}
}(ctx)
}
func (r *room) loop(ctx context.Context, conns *map[string]*wsconn) (normalEnd bool) {
defer func() {
s := recover()
if s != nil {
logger.Error(s)
normalEnd = false
}
}()
for {
select {
case <-ctx.Done():
return true
case conn := <-r.inChan:
(*conns)[conn.sender.Accid.Hex()] = conn
case conn := <-r.outChan:
delete((*conns), conn.sender.Accid.Hex())
case msg := <-r.messageChan:
ds := DownstreamMessage{
Alias: msg.Alias,
Body: msg.Body,
Tag: append(msg.Tag, r.name),
}
bt, _ := json.Marshal(ds)
for _, conn := range *conns {
writer, _ := conn.NextWriter(websocket.TextMessage)
writer.Write(bt)
writer.Close()
}
}
}
}