64 lines
1.2 KiB
Go
64 lines
1.2 KiB
Go
package rtcomm
|
|
|
|
import (
|
|
"github.com/google/uuid"
|
|
"sync"
|
|
)
|
|
|
|
// TODO associate lock with individual clients to prevent global locking
|
|
type Clients struct {
|
|
sync.RWMutex
|
|
clients map[uuid.UUID][]chan StateUpdate
|
|
}
|
|
|
|
func NewClients() *Clients {
|
|
return &Clients{
|
|
clients: make(map[uuid.UUID][]chan StateUpdate),
|
|
}
|
|
}
|
|
|
|
func (c *Clients) AddClient(id uuid.UUID, client chan StateUpdate) {
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
c.clients[id] = append(c.clients[id], client)
|
|
}
|
|
|
|
//TODO remove debug
|
|
func (c *Clients) Count() (sessions, clients uint) {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
for _, s := range c.clients {
|
|
sessions++
|
|
clients += uint(len(s))
|
|
}
|
|
return
|
|
}
|
|
|
|
// TODO optimize
|
|
func (c *Clients) RemoveClient(id uuid.UUID, client chan StateUpdate) {
|
|
c.Lock()
|
|
defer c.Unlock()
|
|
var newClients = make([]chan StateUpdate, 0, len(c.clients[id]) - 1)
|
|
for i := 0; i < len(c.clients[id]); i++ {
|
|
if c.clients[id][i] != client {
|
|
newClients = append(newClients, c.clients[id][i])
|
|
}
|
|
}
|
|
c.clients[id] = newClients
|
|
}
|
|
|
|
func (c *Clients) SendToAll(id uuid.UUID, su StateUpdate) (sent, dropped uint) {
|
|
c.RLock()
|
|
defer c.RUnlock()
|
|
for i := 0; i < len(c.clients[id]); i++ {
|
|
select {
|
|
case c.clients[id][i] <- su:
|
|
sent++
|
|
default:
|
|
dropped++
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|