/
notifier.go
123 lines (98 loc) · 2.27 KB
/
notifier.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
package goatee
import (
"log"
"net/http"
"github.com/gomodule/redigo/redis"
"github.com/gorilla/websocket"
)
// type AuthFunc func(req *http.Request) bool
type sockethub struct {
// registered connections
connections map[*connection]bool
// inbound messages from connections
broadcast chan *Data
// register requests from connection
register chan *connection
// unregister request from connection
unregister chan *connection
// copy of the redis client
rclient *RedisClient
// copy of the redis connection
rconn redis.Conn
Auth func(req *http.Request) bool
}
var h = sockethub{
broadcast: make(chan *Data),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
}
func (h *sockethub) WsHandler(w http.ResponseWriter, r *http.Request) {
var authenticated bool
if h.Auth != nil {
authenticated = h.Auth(r)
}
if authenticated {
ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
if _, ok := err.(websocket.HandshakeError); ok {
http.Error(w, "Not a websocket handshake", 400)
return
} else if err != nil {
log.Printf("WsHandler error: %s", err.Error())
return
}
c := &connection{send: make(chan *Data), ws: ws}
h.register <- c
go c.writer()
go c.reader()
} else {
http.Error(w, "Invalid API key", 401)
}
}
func (h *sockethub) Run() {
for {
select {
case c := <-h.register:
h.connections[c] = true
case c := <-h.unregister:
if _, ok := h.connections[c]; ok {
delete(h.connections, c)
close(c.send)
}
case m := <-h.broadcast:
for c := range h.connections {
select {
case c.send <- m:
if DEBUG {
log.Printf("broadcasting: %s", m.Payload)
}
default:
close(c.send)
delete(h.connections, c)
}
}
}
}
}
func (h *sockethub) RegisterAuthFunc(AuthFunc func(req *http.Request) bool) {
aut := AuthFunc
h.Auth = aut
}
func (h *sockethub) StartServer() {
conf := LoadConfig("config")
client, err := NewRedisClient(conf.Redis.Host)
if err != nil {
log.Fatal(err)
}
defer client.Close()
go h.Run()
http.HandleFunc("/", h.WsHandler)
log.Println("Starting server on: ", conf.Web.Host)
err = http.ListenAndServe(conf.Web.Host, nil)
if err != nil {
log.Fatal(err)
}
}
func CreateServer() sockethub {
return h
}