-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
107 lines (93 loc) · 2.54 KB
/
main.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 (
"io"
"log"
"math/rand"
"net/http"
"time"
"code.google.com/p/go.net/websocket"
"github.com/surma/httptools"
"github.com/voxelbrain/goptions"
"github.com/voxelbrain/pixelpixel/pixelutils"
)
var (
options = struct {
Listen string `goptions:"-l, --listen, description='Adress to bind webserver to'"`
NumPixelsPerRow int `goptions:"-r, --per-row, description='Number of pixels per row'"`
TemplateDir string `goptions:"-t, --templates, description='Path to the templates'"`
StaticDir string `goptions:"--static, description='Path to the static content'"`
Lxc bool `goptions:"-x, --lxc, description='Use lxc containers for pixels'"`
DeleteToken string `goptions:"--delete-token, description='Token to authorize deletion'"`
Help goptions.Help `goptions:"-h, --help, description='Show this help'"`
}{
Listen: "localhost:8080",
StaticDir: "./static",
TemplateDir: "./templates",
NumPixelsPerRow: 4,
}
)
func init() {
rand.Seed(time.Now().UnixNano())
}
func main() {
goptions.ParseAndFail(&options)
if options.Lxc {
log.Fatalf("LXC support not implemented yet")
}
pa := NewPixelApi(NewLocalContainerCreator())
r := httptools.NewRegexpSwitch(map[string]http.Handler{
"/ws": NewStreamingHandler(pa),
"/templates/.*": httptools.L{
httptools.DiscardPathElements(1),
templateRenderer{
Dir: options.TemplateDir,
Data: TemplateData(),
},
},
"/pixels(/.*)?": httptools.L{
httptools.DiscardPathElements(1),
pa,
},
"/handshake": http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "PIXELPIXEL OK")
}),
"/.*": httptools.L{
http.FileServer(http.Dir(options.StaticDir)),
},
})
log.Printf("Starting webserver on %s...", options.Listen)
err := http.ListenAndServe(options.Listen, r)
if err != nil {
log.Fatalf("Could not start webserver: %s", err)
}
}
func NewStreamingHandler(pa *PixelApi) websocket.Handler {
f := NewFanout(pa.Messages)
return websocket.Handler(func(c *websocket.Conn) {
messages := f.Output()
defer f.Close(messages)
go func() {
click := &pixelutils.Click{}
for {
err := websocket.JSON.Receive(c, &click)
if err == io.EOF {
return
}
if err != nil {
log.Printf("Received invalid click: %s", err)
continue
}
pa.ReportClick(click)
}
}()
for {
select {
case message, ok := <-messages:
if !ok {
return
}
websocket.JSON.Send(c, message)
}
}
})
}