forked from gophergala2016/spacegophers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
136 lines (105 loc) · 2.91 KB
/
server.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
package main
import (
"encoding/json"
"html/template"
"net/http"
"github.com/apex/log"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
// NewServer sets up a new server instance.
func NewServer(ctx log.Interface, address, templateFilename string) Server {
return Server{
Log: ctx.WithFields(log.Fields{
"module": "Server",
"address": address,
}),
IndexTemplate: template.Must(template.ParseFiles(templateFilename)),
Address: address,
Hub: NewGameHub(ctx),
}
}
// Server contains the entire application bundle and will start the necessary
// components to serve up resources needed to execute the game.
type Server struct {
Address string
IndexTemplate *template.Template
Log log.Interface
Hub GameHub
}
// HandleWS handles the ws server upgrading.
func (s *Server) HandleWS(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
gameID := vars["gameID"]
ctx := s.Log.WithFields(log.Fields{
"path": r.URL.Path,
"method": r.Method,
"handler": "HandleWS",
"gameID": gameID,
})
ctx.Info("request")
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
ctx.Error(err.Error())
return
}
ctx.Debug("upgraded")
user := NewUser(log.WithField("gameID", gameID), ws)
// pass off the new user to the game hub
s.Hub.register <- GameRegistrationRequest{
GameID: gameID,
User: &user,
}
ctx.Debug("registered")
}
// HandleHTTP handles the http calls at the root for anything really.
func (s *Server) HandleHTTP(w http.ResponseWriter, r *http.Request) {
ctx := s.Log.WithFields(log.Fields{
"path": r.URL.Path,
"method": r.Method,
"handler": "HandleHTTP",
})
ctx.Info("request")
if r.URL.Path == "/" {
if r.Method == "GET" {
// serve the index file here..
w.Header().Set("Content-Type", "text/html")
s.IndexTemplate.Execute(w, r.Host)
return
} else if r.Method == "POST" {
payload := map[string]string{
"id": NewGameID(),
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(payload); err != nil {
ctx.Error(err.Error())
}
return
}
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
http.Error(w, "not found", http.StatusNotFound)
return
}
// Serve sets up the components necessary to run games.
func (s *Server) Serve() {
r := mux.NewRouter()
// handle the http + ws servers
r.HandleFunc("/", s.HandleHTTP)
r.HandleFunc("/{gameID}/ws", s.HandleWS)
// handle all other static files
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
// bind the router to the default http handler
http.Handle("/", r)
s.Log.Info("listening")
// start up the hub
go s.Hub.run()
if err := http.ListenAndServe(s.Address, nil); err != nil {
s.Log.Fatalf("ListenAndServe: %s", err.Error())
}
}