diff --git a/Makefile b/Makefile index 495ab0a1..d896d174 100644 --- a/Makefile +++ b/Makefile @@ -83,26 +83,3 @@ dev.run-docker: docker rm cloud-game-local # Overlord and worker should be run separately. docker run --privileged -v $PWD/games:/cloud-game/games -d --name cloud-game-local -p 8000:8000 -p 9000:9000 cloud-game-local bash -c "overlord --v=5 & overworker --overlordhost ws://localhost:8000/wso" - -#build: -# go build -o build/cloudretro ./cmd -# -#run: build -# # Run coordinator first -# ./build/cloudretro -overlordhost overlord & -# # Wait till overlord finish initialized -# # Run a worker connecting to overload -# ./build/cloudretro -overlordhost ws://localhost:8000/wso - -#run-docker: -# docker build . -t cloud-game-local -# docker stop cloud-game-local || true -# docker rm cloud-game-local || true -# # Overlord and worker should be run separately. Local is for demo purpose -# docker run --privileged -v $(PWD)/games:/cloud-game/games -d --name cloud-game-local -p 8000:8000 -p 9000:9000 cloud-game-local bash -c "cmd -overlordhost ws://localhost:8000/wso & cmd -overlordhost overlord" -# - -#run-fast: build-vendor -# ./build/cloudretro -overlordhost overlord & -# ./build/cloudretro -overlordhost ws://localhost:8000/wso -# diff --git a/go.mod b/go.mod index 150aad77..57d709fc 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,8 @@ require ( github.com/gofrs/uuid v3.2.0+incompatible github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/gorilla/websocket v1.4.0 + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.1 // indirect github.com/pion/webrtc/v2 v2.1.2 github.com/prometheus/client_golang v1.1.0 github.com/spf13/pflag v1.0.3 diff --git a/pkg/config/config.go b/pkg/config/config.go index 74529045..48cffa07 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,9 +10,7 @@ const DefaultSTUNTURN = `[{"urls":"stun:stun-turn.webgame2d.com:3478"},{"urls":" const CODEC_VP8 = "VP8" const CODEC_H264 = "H264" -var IsDebug = flag.Bool("debug", false, "Is game running in debug mode?") var Port = flag.String("port", "8000", "Port of the game") -var IsMonitor = flag.Bool("monitor", false, "Turn on monitor") var FrontendSTUNTURN = flag.String("stunturn", DefaultSTUNTURN, "Frontend STUN TURN servers") var Mode = flag.String("mode", "dev", "Environment") var StunTurnTemplate = `[{"urls":"stun:stun.l.google.com:19302"},{"urls":"stun:%s:3478"},{"urls":"turn:%s:3478","username":"root","credential":"root"}]` diff --git a/pkg/emulator/libretro/nanoarch/nanoarch.go b/pkg/emulator/libretro/nanoarch/nanoarch.go index d559370e..8541bd36 100644 --- a/pkg/emulator/libretro/nanoarch/nanoarch.go +++ b/pkg/emulator/libretro/nanoarch/nanoarch.go @@ -294,7 +294,7 @@ func coreEnvironment(cmd C.unsigned, data unsafe.Pointer) C.bool { return videoSetPixelFormat(*format) case C.RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY: path := (**C.char)(data) - *path = C.CString("./libretro/system") + *path = C.CString("./pkg/emulator/libretro/system") return true case C.RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY: path := (**C.char)(data) diff --git a/pkg/overlord/config.go b/pkg/overlord/config.go index 33961704..e501ffa7 100644 --- a/pkg/overlord/config.go +++ b/pkg/overlord/config.go @@ -8,6 +8,7 @@ import ( type Config struct { Port int URLPrefix string + DebugHost string MonitoringConfig monitoring.ServerMonitoringConfig } @@ -31,6 +32,7 @@ func (c *Config) AddFlags(fs *pflag.FlagSet) *Config { fs.BoolVarP(&c.MonitoringConfig.ProfilingEnabled, "monitoring.pprof", "p", c.MonitoringConfig.ProfilingEnabled, "Enable golang pprof for server") fs.IntVarP(&c.MonitoringConfig.Port, "monitoring.port", "", c.MonitoringConfig.Port, "Monitoring server port") fs.StringVarP(&c.MonitoringConfig.URLPrefix, "monitoring.prefix", "", c.MonitoringConfig.URLPrefix, "Monitoring server url prefix") + fs.StringVarP(&c.DebugHost, "debughost", "d", "", "Specify the server want to connect directly to debug") return c } diff --git a/pkg/overlord/handlers.go b/pkg/overlord/handlers.go index ce91c5c0..d83905f5 100644 --- a/pkg/overlord/handlers.go +++ b/pkg/overlord/handlers.go @@ -24,6 +24,7 @@ const ( ) type Server struct { + cfg Config // roomToServer map roomID to workerID roomToServer map[string]string // workerClients are the map serverID to worker Client @@ -33,8 +34,9 @@ type Server struct { var upgrader = websocket.Upgrader{} var errNotFound = errors.New("Not found") -func NewServer() *Server { +func NewServer(cfg Config) *Server { return &Server{ + cfg: cfg, // Mapping serverID to client workerClients: map[string]*WorkerClient{}, // Mapping roomID to server @@ -127,30 +129,21 @@ func (o *Server) WS(w http.ResponseWriter, r *http.Request) { client := NewBrowserClient(c) go client.Listen() - // Set up server - - workerClients := o.getAvailableWorkers() - // SessionID will be the unique per frontend connection - sessionID := uuid.Must(uuid.NewV4()).String() - var serverID string - if config.MatchWorkerRandom { - serverID, err = findBestServerRandom(workerClients) - } else { - serverID, err = findBestServerFromBrowser(workerClients, client) - } - + // Get best server for frontend to connect to + workerClient, err := o.getBestWorkerClient(client) if err != nil { - log.Println(err) return } + // SessionID will be the unique per frontend connection + sessionID := uuid.Must(uuid.NewV4()).String() // Setup session wssession := &Session{ ID: sessionID, handler: o, BrowserClient: client, - WorkerClient: o.workerClients[serverID], - ServerID: serverID, + WorkerClient: workerClient, + ServerID: workerClient.ServerID, } // TODO:? // defer wssession.Close() @@ -161,7 +154,7 @@ func (o *Server) WS(w http.ResponseWriter, r *http.Request) { wssession.BrowserClient.Send(cws.WSPacket{ ID: "init", - Data: createInitPackage(o.workerClients[serverID].StunTurnServer), + Data: createInitPackage(workerClient.StunTurnServer), }, nil) // If peerconnection is done (client.Done is signalled), we close peerconnection @@ -178,6 +171,35 @@ func (o *Server) WS(w http.ResponseWriter, r *http.Request) { wssession.WorkerClient.IsAvailable = true } +func (o *Server) getBestWorkerClient(client *BrowserClient) (*WorkerClient, error) { + if o.cfg.DebugHost != "" { + log.Println("Connecting to debug host instead prod servers", o.cfg.DebugHost) + wc := o.getWorkerFromAddress(o.cfg.DebugHost) + if wc != nil { + return wc, nil + } + // if there is not debugHost, continue usual flow + log.Println("Not found, connecting to all available servers") + } + + workerClients := o.getAvailableWorkers() + + var serverID string + var err error + if config.MatchWorkerRandom { + serverID, err = findBestServerRandom(workerClients) + } else { + serverID, err = findBestServerFromBrowser(workerClients, client) + } + + if err != nil { + log.Println(err) + return nil, err + } + + return o.workerClients[serverID], nil +} + // getAvailableWorkers returns the list of available worker func (o *Server) getAvailableWorkers() map[string]*WorkerClient { workerClients := map[string]*WorkerClient{} @@ -190,6 +212,17 @@ func (o *Server) getAvailableWorkers() map[string]*WorkerClient { return workerClients } +// getWorkerFromAddress returns the worker has given address +func (o *Server) getWorkerFromAddress(address string) *WorkerClient { + for _, w := range o.workerClients { + if w.IsAvailable && w.Address == address { + return w + } + } + + return nil +} + // findBestServer returns the best server for a session func findBestServerRandom(workerClients map[string]*WorkerClient) (string, error) { // TODO: Find best Server by latency, currently return by ping diff --git a/pkg/overlord/overlord.go b/pkg/overlord/overlord.go index 45285e66..7b2b704e 100644 --- a/pkg/overlord/overlord.go +++ b/pkg/overlord/overlord.go @@ -47,7 +47,7 @@ func (o *Overlord) Shutdown() { // initializeOverlord setup an overlord server func (o *Overlord) initializeOverlord() { - overlord := NewServer() + overlord := NewServer(o.cfg) http.HandleFunc("/", overlord.GetWeb) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./web")))) diff --git a/pkg/webrtc/webrtc.go b/pkg/webrtc/webrtc.go index 8cc5aad8..ee7b5002 100644 --- a/pkg/webrtc/webrtc.go +++ b/pkg/webrtc/webrtc.go @@ -271,9 +271,6 @@ func (w *WebRTC) startStreaming(vp8Track *webrtc.Track, opusTrack *webrtc.Track) }() for data := range w.ImageChannel { - if *config.IsMonitor { - log.Println("Encoding FPS : ", w.calculateFPS()) - } err := vp8Track.WriteSample(media.Sample{Data: data, Samples: 1}) if err != nil { log.Println("Warn: Err write sample: ", err) diff --git a/pkg/worker/overlord.go b/pkg/worker/overlord.go index 1103829a..fb3bb370 100644 --- a/pkg/worker/overlord.go +++ b/pkg/worker/overlord.go @@ -2,7 +2,6 @@ package worker import ( "encoding/json" - "fmt" "log" "github.com/giongto35/cloud-game/pkg/cws" @@ -57,12 +56,10 @@ func (h *Handler) RouteOverlord() { SDP string `json:"sdp"` IsMobile bool `json:"is_mobile"` } - fmt.Println("HIHIHIHI!!!!", resp.Data) err := json.Unmarshal([]byte(resp.Data), &initPacket) if err != nil { panic(err) } - fmt.Println("HIHIHIHI!!!!", initPacket) localSession, err := peerconnection.StartClient(initPacket.SDP, initPacket.IsMobile, iceCandidates[resp.SessionID]) // h.peerconnections[resp.SessionID] = peerconnection