-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathBroadcastAdapter.go
108 lines (94 loc) · 2.51 KB
/
BroadcastAdapter.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
108
package socketio
import "sync"
// BroadcastAdaptor is the adaptor to handle broadcast.
type BroadcastAdaptor interface {
// Join lets socket join the t room.
Join(room string, socket Socket) error
// Leave let socket leave the room.
Leave(room string, socket Socket) error
// Send will send the message with args to room. If ignore is not nil, it won't send to the socket ignore.
Send(ignore Socket, room, message string, args ...interface{}) error
}
var newBroadcast = newBroadcastDefault
// Broadcast is a set of "room" each with a set of Socket
type broadcast struct {
roomSet map[string]map[string]Socket
broadcastLock sync.RWMutex
}
func newBroadcastDefault() BroadcastAdaptor {
return &broadcast{
roomSet: make(map[string]map[string]Socket),
}
}
// Join into a room
func (b *broadcast) Join(room string, socket Socket) error {
b.broadcastLock.Lock()
sockets, ok := b.roomSet[room]
if !ok {
sockets = make(map[string]Socket)
}
sockets[socket.Id()] = socket
b.roomSet[room] = sockets
b.broadcastLock.Unlock()
return nil
}
// Disconnect from a room
func (b *broadcast) Leave(room string, socket Socket) error {
b.broadcastLock.Lock()
sockets, ok := b.roomSet[room]
if !ok {
return nil
}
delete(sockets, socket.Id())
if len(sockets) == 0 {
delete(b.roomSet, room)
} else {
b.roomSet[room] = sockets
}
b.broadcastLock.Unlock()
return nil
}
// Perform a brodcast send to all the sockets in a "room" except the ignored socket.
// Brodcast send to all with ignore == nil.
func (b *broadcast) Send(ignore Socket, room, message string, args ...interface{}) error {
b.broadcastLock.RLock()
defer b.broadcastLock.RUnlock()
sockets := b.roomSet[room]
for id, s := range sockets {
if ignore != nil && ignore.Id() == id {
continue
}
s.Emit(message, args...)
}
return nil
}
// return the number of connections in a specified room
func (b *broadcast) NumberInRoom(room string) (rv int, err error) {
b.broadcastLock.RLock()
defer b.broadcastLock.RUnlock()
sockets := b.roomSet[room]
rv = 0
for _, _ = range sockets {
rv++
}
return
}
// return the number of rooms
func (b *broadcast) NumberOfRooms(room string) (rv int, err error) {
b.broadcastLock.RLock()
defer b.broadcastLock.RUnlock()
rv = 0
for _, _ = range b.roomSet {
rv++
}
return
}
// return the names of the rooms as a slice of strings
func (b *broadcast) ListOfRooms(room string) (rv []string, err error) {
b.broadcastLock.RLock()
defer b.broadcastLock.RUnlock()
for room := range b.roomSet {
rv = append(rv, room)
}
return
}