Example #1
0
// PauseHandler returns the handler for `flixy pause`.
func PauseHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.PauseMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy pause",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
			return
		}

		sid := data.SessionID

		log.Infof("%s pausing session %s", sockid, sid)
		s, ok := sessions[sid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "flixy pause",
				"member_sockid": sockid,
				"member_remote": sockip,
				"invalid_sid":   sid,
			}).Warn("invalid session id")

			so.Emit("flixy invalid session id", sid)
			return
		}

		s.Pause()
		log.WithFields(log.Fields{
			"verb":          "flixy pause",
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Debug("pausing")
	}
}
Example #2
0
File: main.go Project: flixy/flixy
// 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))
}