forked from gin-gonic/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rooms.go
107 lines (92 loc) · 2.03 KB
/
rooms.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"github.com/dustin/go-broadcast"
)
type Message struct {
UserId string
RoomId string
Text string
}
type Listener struct {
RoomId string
Chan chan interface{}
}
type Manager struct {
roomChannels map[string]broadcast.Broadcaster
open chan *Listener
close chan *Listener
delete chan string
messages chan *Message
}
func NewRoomManager() *Manager {
manager := &Manager{
roomChannels: make(map[string]broadcast.Broadcaster),
open: make(chan *Listener, 100),
close: make(chan *Listener, 100),
delete: make(chan string, 100),
messages: make(chan *Message, 100),
}
go manager.run()
return manager
}
func (m *Manager) run() {
for {
select {
case listener := <- m.open:
m.register(listener)
case listener := <- m.close:
m.deregister(listener)
case roomid := <- m.delete:
m.deleteBroadcast(roomid)
case message := <- m.messages:
m.room(message.RoomId).Submit(message.UserId + ": " + message.Text)
}
}
}
func (m *Manager) register(listener *Listener) {
m.room(listener.RoomId).Register(listener.Chan)
}
func (m *Manager) deregister(listener *Listener) {
m.room(listener.RoomId).Unregister(listener.Chan)
close(listener.Chan)
}
func (m *Manager) deleteBroadcast(roomid string) {
b, ok := m.roomChannels[roomid]
if ok {
b.Close()
delete(m.roomChannels, roomid)
}
}
func (m *Manager) room(roomid string) broadcast.Broadcaster {
b, ok := m.roomChannels[roomid]
if !ok {
b = broadcast.NewBroadcaster(10)
m.roomChannels[roomid] = b
}
return b
}
func (m *Manager) OpenListener(roomid string) chan interface{}{
listener := make(chan interface{})
m.open <- &Listener{
RoomId: roomid,
Chan: listener,
}
return listener
}
func (m *Manager) CloseListener(roomid string, channel chan interface{}) {
m.close <- &Listener{
RoomId: roomid,
Chan: channel,
}
}
func (m *Manager) DeleteBroadcast(roomid string) {
m.delete <- roomid
}
func (m *Manager) Submit (userid, roomid, text string) {
msg := &Message{
UserId: userid,
RoomId: roomid,
Text: text,
}
m.messages <- msg
}