-
Notifications
You must be signed in to change notification settings - Fork 0
/
socket.go
77 lines (75 loc) · 2.19 KB
/
socket.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
package allsoc
import (
"io"
)
// sockets stores a map of slices of *io.ReadWriter
var sockets map[string][]*io.ReadWriter
// SetupAllsoc sets up this library if not already setup.
func SetupAllsoc () {
if sockets == nil { sockets = make(map[string][]*io.ReadWriter) }
}
// Socket allows socket operations.
type Socket struct {
rw *io.ReadWriter
rooms map[string]int
}
// NewSocket creates a new Socket and returns a ptr to it.
func NewSocket(rw *io.ReadWriter) *Socket {
return &Socket{rw : rw, rooms : make(map[string]int)}
}
// Join starts listening on a room
func (soc *Socket) Join(room string) {
if _, ok := soc.rooms[room]; !ok {
index := -1
for i:= 0; i < len(sockets[room]); i++ {
if sockets[room][i] == nil {
sockets[room][i] = soc.rw
index = i
break
}
}
if index == -1 {
index = len(sockets[room])
sockets[room] = append(sockets[room], soc.rw)
}
soc.rooms[room] = index
}
}
// Leave stops listening on a room
func (soc *Socket) Leave(room string) {
if index, ok := soc.rooms[room]; ok {
soc.leave(room, index)
}
}
// leave stops listening on a room. Called internally. Make sure to not call this on a room that was not joined
func (soc *Socket) leave(room string, index int) {
sockets[room][index] = nil
if sockets[room][len(sockets[room])-1] == nil {
sockets[room] = sockets[room][:len(sockets[room])-1]
}
}
// Read reads bytes from the socket
func (soc *Socket) Read(b []byte) (n int, err error) {
n, err = (*soc.rw).Read(b)
if err != nil {
for room, index := range soc.rooms {
soc.leave(room, index)
}
}
return
}
// Emit send bytes to the client
func (soc *Socket) Write(b []byte) (n int, err error) {
n, err = (*soc.rw).Write(b)
return
}
// Broadcast sends bytes to listeners of the room
func (soc *Socket) Broadcast(room string, b []byte) (n int, err error) {
index := soc.rooms[room]
for i:= 0; i < len(sockets[room]); i++ {
if sockets[room][i] != nil && i != index {
n, err = (*sockets[room][i]).Write(b)
}
}
return
}