-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsockets.go
159 lines (138 loc) · 3.8 KB
/
sockets.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package main
import (
"log"
"sync"
"github.com/beatrichartz/martini-sockets"
"github.com/go-martini/martini"
"github.com/lab-D8/lol-at-pitt/draft"
"github.com/lab-D8/lol-at-pitt/site"
"github.com/martini-contrib/render"
)
// Message is a single message sent between clients
type Message struct {
Type string `json:"type"`
From string `json:"from"`
Text string `json:"text"`
}
// DraftRoom used for socket communication DraftRoom
type DraftRoom struct {
sync.Mutex
clients []*Client
}
// Client is a single connection to be used for websockets
type Client struct {
ID string
in <-chan *Message
out chan<- *Message
done <-chan bool
err <-chan error
disconnect chan<- int
}
// Add a client to a room
func (r *DraftRoom) appendClient(client *Client) {
r.Lock()
r.clients = append(r.clients, client)
for _, c := range r.clients {
if c != client {
c.out <- &Message{"status", client.ID, "Joined this chat"}
}
}
r.Unlock()
}
// Remove a client from a room
func (r *DraftRoom) removeClient(client *Client) {
r.Lock()
defer r.Unlock()
for index, c := range r.clients {
if c == client {
r.clients = append(r.clients[:index], r.clients[(index+1):]...)
} else {
c.out <- &Message{"status", client.ID, "Left this chat"}
}
}
}
// Message all the other clients in the same room
func (r *DraftRoom) messageOtherClients(client *Client, msg *Message) {
r.Lock()
msg.From = client.ID
for _, c := range r.clients {
if c != client {
c.out <- msg
}
}
defer r.Unlock()
}
func (r *DraftRoom) broadcast(msg *Message) {
r.Lock()
for _, c := range r.clients {
c.out <- msg
}
defer r.Unlock()
}
func (r *DraftRoom) messageWithID(id string, msg *Message) {
for _, c := range r.clients {
if c.ID == id {
r.message(c, msg)
}
}
}
func (r *DraftRoom) message(client *Client, msg *Message) {
client.out <- msg
}
func newDraftRoom() *DraftRoom {
return &DraftRoom{sync.Mutex{}, make([]*Client, 0)}
}
var room *DraftRoom
// SocketRouter is used to setup main martini function
func SocketRouter(m *martini.ClassicMartini) {
room = newDraftRoom()
Init()
m.Get("/draft", PlayerRequired, func(r render.Render, user site.User) {
r.HTML(200, "draft", user.FacebookId)
})
m.Get("/admin/start", func() {
draft.Paused = false
allowTicks = false
Handle(Message{Type: "event", Text: "The round has started, LET THE BIDDING BEGIN"})
})
m.Get("/admin/reset", func() {
draft.GetCurrentPlayer().HighestBid = 0
draft.GetCurrentPlayer().Team = ""
Handle(Message{Type: "event", Text: "Admin reset current round, starting when they press the button.."})
allowTicks = false
draft.Paused = true
})
m.Get("/admin/skip", func() {
Handle(Message{Type: "event", Text: "Admin skipped current player, waiting on him to start.."})
draft.Next()
Handle(Message{Type: "update"})
})
m.Get("/player/refresh", func() {
Handle(Message{Type: "refresh"})
})
m.Get("/admin/previous", func() {
Handle(Message{Type: "event", Text: "Admin undid previous round, waiting on him to start.."})
draft.Previous()
Handle(Message{Type: "update"})
})
// This is the sockets connection for the room, it is a json mapping to sockets.
m.Get("/draft/:clientname", sockets.JSON(Message{}), func(params martini.Params, receiver <-chan *Message, sender chan<- *Message, done <-chan bool, disconnect chan<- int, err <-chan error) (int, string) {
client := &Client{params["clientname"], receiver, sender, done, err, disconnect}
room.appendClient(client)
Handle(Message{Type: "login"})
// A single select can be used to do all the messaging
for {
select {
case <-client.err:
// Its gone jim
case msg := <-client.in:
// Most of code will be handled here
log.Println(*msg)
Handle(*msg)
case <-client.done:
room.removeClient(client)
return 200, "OK"
}
}
})
}