// Benchmark_Routes runs a benchmark against our custom Mux using the // default settings. func Benchmark_Routes(b *testing.B) { handler := routes.New() handler.Get("/person/:last/:first", HandlerOk) for i := 0; i < b.N; i++ { r, _ := http.NewRequest("GET", "/person/anderson/thomas?learn=kungfu", nil) w := httptest.NewRecorder() handler.ServeHTTP(w, r) } }
// main is the entry point to the flixy server. func main() { log.Info("Starting flixy!") server, err := socketio.NewServer(nil) if err != nil { log.Fatal(err) } // TODO can/should this be moved to its own function? it might make the // architecture of the various other handlers simpler, if implemented // in the right way. server.On("connection", func(so socketio.Socket) { sockid := so.Id() sockip := getRemoteIP(so) so.On("flixy get sync", SyncHandler(so)) so.On("flixy new", NewHandler(so)) so.On("flixy pause", PauseHandler(so)) so.On("flixy play", PlayHandler(so)) so.On("flixy join", JoinHandler(so)) so.On("flixy seek", SeekHandler(so)) log.WithFields(log.Fields{ "member_sockid": sockid, "member_remote": sockip, }).Info("connected") }) // TODO move this to its own handler (we're all grown up now!!!!) server.On("disconnection", func(so socketio.Socket) { sockid := so.Id() sockip := getRemoteIP(so) m, ok := members[sockid] if !ok { log.WithFields(log.Fields{ "verb": "disconnection", "member_sockid": sockid, "member_remote": sockip, }).Warn("member never in a session disconnected") // If a socket has never been a member, then it has no // sessions to be removed from, and thus we have // nothing further to do. return } log.Infof("%v disconnected", sockid) delete(members, sockid) s := m.Session // TODO this could be a lot prettier. I wish it could go in the // `RemoveMember` func itself, but I can't actually think of // how to remove a session from within its own context. numLeft := s.RemoveMember(sockid) // NOTE what happens if a user connects to the session here? if numLeft == 0 { sid := s.SessionID delete(sessions, sid) } }) // TODO this should probably go to its own handler, too. server.On("error", func(so socketio.Socket, err error) { // TODO how can this even happen? log.Error("error:", err) }) mux := http.NewServeMux() api := routes.New() // TODO remove this api.Get("/status", func(w http.ResponseWriter, r *http.Request) { // print status here // this is just for debugging for now, we need more in-depth stuff soon enc := json.NewEncoder(w) wms := make(map[string]models.WireSession) for k, v := range sessions { wms[k] = v.GetWireSession() } enc.Encode(wms) }) // `/sessions/:sid` will 302 the user to the proper Netflix URL if it's // a valid SID, setting the session ID in the URL as it does so. It // will *also* return the session as a JSON object. api.Get("/sessions/:sid", func(w http.ResponseWriter, r *http.Request) { params := r.URL.Query() session, present := sessions[params.Get(":sid")] if !present { w.WriteHeader(404) return } w.Header().Set("Location", session.GetNetflixURL()) w.WriteHeader(302) routes.ServeJson(w, session.GetWireSession()) }) mux.Handle("/socket.io/", server) mux.Handle("/", api) n := negroni.New() n.Use(negronilogrus.NewCustomMiddleware(loglevel, &log.TextFormatter{}, "web")) n.Use(negroni.NewRecovery()) middleware.Inject(n) n.UseHandler(mux) n.Run(fmt.Sprintf("%s:%d", opts.Host, opts.Port)) }