-
Notifications
You must be signed in to change notification settings - Fork 0
/
room.go
76 lines (67 loc) · 1.15 KB
/
room.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package main
import (
"log"
"sync"
"sync/atomic"
)
type Room struct {
Id int
Name string
forward chan *Message
join chan *Client
leave chan *Client
clients map[*Client]bool
}
var (
mu sync.Mutex
maxRoomId int32 = 0
rooms = make([]*Room, 0)
)
func FindRoom(id int) *Room {
for _, r := range rooms {
if r.Id == id {
return r
}
}
return nil
}
func NewRoom(name string) *Room {
atomic.AddInt32(&maxRoomId, 1)
r := &Room{
Id: int(maxRoomId),
Name: name,
forward: make(chan *Message),
join: make(chan *Client),
leave: make(chan *Client),
clients: make(map[*Client]bool),
}
mu.Lock()
defer mu.Unlock()
rooms = append(rooms, r)
go r.run()
return r
}
func (r *Room) broadcast(m *Message) {
for client := range r.clients {
select {
case client.send <- m:
default:
// failed to send
delete(r.clients, client)
client.Close()
}
}
}
func (r *Room) run() {
log.Printf("run room(id: %d)", r.Id)
for {
select {
case client := <-r.join:
r.clients[client] = true
case client := <-r.leave:
delete(r.clients, client)
case msg := <-r.forward:
r.broadcast(msg)
}
}
}