From 515259772f08b810a5d2a3274755272016283ed5 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sun, 19 May 2019 05:24:58 +0800 Subject: [PATCH] Clean code --- ' | 195 ------------------ cmd/main.go | 4 +- overlord/browser.go | 37 +--- overlord/handlers.go | 15 +- overlord/worker.go | 46 ++--- {handler => worker}/cloud-storage/storage.go | 0 .../cloud-storage/storage_test.go | 0 {handler => worker}/handlers.go | 46 +---- {handler => worker}/overlord.go | 4 +- {handler => worker}/room/media.go | 0 {handler => worker}/room/room.go | 2 +- {handler => worker}/session.go | 13 +- 12 files changed, 45 insertions(+), 317 deletions(-) delete mode 100644 ' rename {handler => worker}/cloud-storage/storage.go (100%) rename {handler => worker}/cloud-storage/storage_test.go (100%) rename {handler => worker}/handlers.go (72%) rename {handler => worker}/overlord.go (98%) rename {handler => worker}/room/media.go (100%) rename {handler => worker}/room/room.go (98%) rename {handler => worker}/session.go (67%) diff --git a/' b/' deleted file mode 100644 index 5f8bf0e0..00000000 --- a/' +++ /dev/null @@ -1,195 +0,0 @@ -package handler - -import ( - "log" - - "github.com/giongto35/cloud-game/config" - "github.com/giongto35/cloud-game/cws" - "github.com/giongto35/cloud-game/webrtc" - "github.com/gorilla/websocket" -) - -// OverlordClient maintans connection to overlord -// We expect only one OverlordClient for each server -type OverlordClient struct { - *cws.Client - peerconnections map[string]*webrtc.WebRTC -} - -// NewOverlordClient returns a client connecting to overlord for coordiation between different server -func NewOverlordClient(oc *websocket.Conn) *OverlordClient { - if oc == nil { - return nil - } - - oclient := &OverlordClient{ - Client: cws.NewClient(oc), - peerconnections: map[string]*webrtc.WebRTC{}, - } - return oclient -} - -// RouteOverlord are all routes server received from overlord -func (s *Session) RouteOverlord() { - iceCandidates := [][]byte{} - oclient := s.OverlordClient - - // Received from overlord the serverID - oclient.Receive( - "serverID", - func(response cws.WSPacket) (request cws.WSPacket) { - // Stick session with serverID got from overlord - log.Println("Received serverID ", response.Data) - s.ServerID = response.Data - - return cws.EmptyPacket - }, - ) - - oclient.Receive( - "initwebrtc", - func(resp cws.WSPacket) (req cws.WSPacket) { - log.Println("Received user SDP") - localSession, err := s.peerconnection.StartClient(resp.Data, iceCandidates, config.Width, config.Height) - if err != nil { - if err != nil { - log.Println("Error: Cannot create new webrtc session", err) - return cws.EmptyPacket - } - } - - return cws.WSPacket{ - ID: "sdp", - Data: localSession, - SessionID: s.ID, - } - }, - ) - - // Received start from overlord. This happens when bridging - // TODO: refactor - //oclient.Receive( - //"start", - //func(resp cws.WSPacket) (req cws.WSPacket) { - //log.Println("Received a start request from overlord") - //log.Println("Add the connection to current room on the host ", resp.SessionID) - - //peerconnection := oclient.peerconnections[resp.SessionID] - //log.Println("start session") - - ////room := s.handler.createNewRoom(s.GameName, s.RoomID, s.PlayerIndex) - //// Request room from Server if roomID is existed on the server - //room := s.handler.getRoom(s.RoomID) - //if room == nil { - //log.Println("Room not found ", s.RoomID) - //return cws.EmptyPacket - //} - //s.handler.detachPeerConn(s.peerconnection) - //room.AddConnectionToRoom(peerconnection, s.PlayerIndex) - ////roomID, isNewRoom := startSession(peerconnection, resp.Data, resp.RoomID, resp.PlayerIndex) - //log.Println("Done, sending back") - - //req.ID = "start" - //req.RoomID = room.ID - //return req - //}, - //) - oclient.Receive( - "start", - func(resp cws.WSPacket) (req cws.WSPacket) { - log.Println("Received a start request from overlord") - log.Println("Add the connection to current room on the host ", resp.SessionID) - s.startGameHandler(resp.Data, resp.RoomID, resp.PlayerIndex) - }, - ) - // heartbeat to keep pinging overlord. We not ping from server to browser, so we don't call heartbeat in browserClient -} - -func getServerIDOfRoom(oc *OverlordClient, roomID string) string { - log.Println("Request overlord roomID ", roomID) - packet := oc.SyncSend( - cws.WSPacket{ - ID: "getRoom", - Data: roomID, - }, - ) - log.Println("Received roomID from overlord ", packet.Data) - - return packet.Data -} - -func (s *Session) startGameHandler(gameName, roomID string, playerIndex int) cws.WSPacket { - s.GameName = gameName - s.RoomID = roomID - s.PlayerIndex = playerIndex - - log.Println("Starting game") - // If we are connecting to overlord, request corresponding serverID based on roomID - // TODO: check if roomID is in the current server - room := s.handler.getRoom(s.RoomID) - log.Println("Got Room from local ", room, " ID: ", s.RoomID) - // If room is not running - if room == nil { - // Create new room - room = s.handler.createNewRoom(s.GameName, s.RoomID, s.PlayerIndex) - // Wait for done signal from room - go func() { - <-room.Done - s.handler.detachRoom(room.ID) - }() - } - - // Attach peerconnection to room. If PC is already in room, don't detach - log.Println("Is PC in room", room.IsPCInRoom(s.peerconnection)) - if !room.IsPCInRoom(s.peerconnection) { - s.handler.detachPeerConn(s.peerconnection) - room.AddConnectionToRoom(s.peerconnection, s.PlayerIndex) - } - s.RoomID = room.ID - - // Register room to overlord if we are connecting to overlord - if room != nil && s.OverlordClient != nil { - s.OverlordClient.Send(cws.WSPacket{ - ID: "registerRoom", - Data: s.RoomID, - }, nil) - } - req.ID = "start" - req.RoomID = s.RoomID - req.SessionID = s.ID - - return req -} - -//func (s *Session) bridgeConnection(serverID string, gameName string, roomID string, playerIndex int) { -//log.Println("Bridging connection to other Host ", serverID) -//client := s.BrowserClient -//// Ask client to init - -//log.Println("Requesting offer to browser", serverID) -//resp := client.SyncSend(cws.WSPacket{ -//ID: "requestOffer", -//Data: "", -//}) - -//// Ask overlord to relay SDP packet to serverID -//resp.TargetHostID = serverID -//log.Println("Sending offer to overlord to relay message to target host", resp.TargetHostID, "with payload") -//remoteTargetSDP := s.OverlordClient.SyncSend(resp) -//log.Println("Got back remote host SDP, sending to browser") -//// Send back remote SDP of remote server to browser -//s.BrowserClient.Send(cws.WSPacket{ -//ID: "sdp", -//Data: remoteTargetSDP.Data, -//}, nil) -//log.Println("Init session done, start game on target host") - -//s.OverlordClient.SyncSend(cws.WSPacket{ -//ID: "start", -//Data: gameName, -//TargetHostID: serverID, -//RoomID: roomID, -//PlayerIndex: playerIndex, -//}) -//log.Println("Game is started on remote host") -//} diff --git a/cmd/main.go b/cmd/main.go index 0a2e31a0..d91f9695 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -11,8 +11,8 @@ import ( "time" "github.com/giongto35/cloud-game/config" - "github.com/giongto35/cloud-game/handler" "github.com/giongto35/cloud-game/overlord" + "github.com/giongto35/cloud-game/worker" "github.com/gorilla/websocket" ) @@ -60,7 +60,7 @@ func initializeWorker() { log.Println("Run as a single server") } - handler := handler.NewHandler(conn, *config.IsDebug, gamePath) + handler := worker.NewHandler(conn, *config.IsDebug, gamePath) handler.Run() diff --git a/overlord/browser.go b/overlord/browser.go index 9ecc65bc..66d19af9 100644 --- a/overlord/browser.go +++ b/overlord/browser.go @@ -11,7 +11,7 @@ type BrowserClient struct { *cws.Client } -// RouteBrowser are all routes server received from browser +// RouteBrowser are all routes server accepts for browser func (s *Session) RouteBrowser() { iceCandidates := [][]byte{} @@ -23,6 +23,7 @@ func (s *Session) RouteBrowser() { browserClient.Receive("icecandidate", func(resp cws.WSPacket) cws.WSPacket { log.Println("Received candidates ", resp.Data) + iceCandidates = append(iceCandidates, []byte(resp.Data)) return cws.EmptyPacket }) @@ -30,6 +31,7 @@ func (s *Session) RouteBrowser() { browserClient.Receive("initwebrtc", func(resp cws.WSPacket) cws.WSPacket { log.Println("Overlord: Received a sdp request from a browser") log.Println("Overlord: Relay sdp request from a browser to worker") + // relay SDP to target worker and get back SDP of the worker // TODO: Async log.Println("Overlord: serverID: ", s.ServerID) @@ -42,16 +44,9 @@ func (s *Session) RouteBrowser() { browserClient.Receive("quit", func(resp cws.WSPacket) (req cws.WSPacket) { log.Println("Overlord: Received a relay quit request from a browser") - //s.GameName = resp.Data - //s.RoomID = resp.RoomID - //s.PlayerIndex = resp.PlayerIndex - - //room := s.handler.getRoom(s.RoomID) - //if room.IsPCInRoom(s.peerconnection) { - //s.handler.detachPeerConn(s.peerconnection) - //} - log.Println("Sending to target host", s.ServerID, " ", resp) + log.Println("Overlord: Relay quit request from a browser to worker") + // TODO: Async resp = s.handler.servers[s.ServerID].SyncSend( resp, ) @@ -61,10 +56,7 @@ func (s *Session) RouteBrowser() { browserClient.Receive("start", func(resp cws.WSPacket) cws.WSPacket { log.Println("Overlord: Received a relay start request from a browser") - // TODO: Abstract - // TODO: if resp.TargetHostID != ""c:w { - // relay start to target host - log.Println("Sending to target host", s.ServerID, " ", resp) + log.Println("Overlord: Relay start request from a browser to worker") // TODO: Async resp = s.handler.servers[s.ServerID].SyncSend( resp, @@ -73,23 +65,6 @@ func (s *Session) RouteBrowser() { return resp }) - //browserClient.Receive("initwebrtc", func(resp cws.WSPacket) cws.WSPacket { - //log.Println("Received user SDP") - //localSession, err := s.peerconnection.StartClient(resp.Data, iceCandidates, config.Width, config.Height) - //if err != nil { - //if err != nil { - //log.Println("Error: Cannot create new webrtc session", err) - //return cws.EmptyPacket - //} - //} - - //return cws.WSPacket{ - //ID: "sdp", - //Data: localSession, - //SessionID: s.ID, - //} - //}) - // TODO: Add save and load //browserClient.Receive("save", func(resp cws.WSPacket) (req cws.WSPacket) { //log.Println("Saving game state") diff --git a/overlord/handlers.go b/overlord/handlers.go index ce5195a8..88bffb66 100644 --- a/overlord/handlers.go +++ b/overlord/handlers.go @@ -7,7 +7,6 @@ import ( "log" "math/rand" "net/http" - "strconv" "github.com/giongto35/cloud-game/cws" "github.com/giongto35/cloud-game/overlord/gamelist" @@ -41,12 +40,7 @@ func NewServer() *Server { // GetWeb returns web frontend func (o *Server) GetWeb(w http.ResponseWriter, r *http.Request) { - indexFN := "" - //if h.isDebug { - //indexFN = debugIndex - //} else { - indexFN = gameboyIndex - //} + indexFN := gameboyIndex bs, err := ioutil.ReadFile(indexFN) if err != nil { @@ -55,7 +49,7 @@ func (o *Server) GetWeb(w http.ResponseWriter, r *http.Request) { w.Write(bs) } -// If it's overlord, handle overlord connection (from host to overlord) +// WSO handles all connections from a new worker to overlord func (o *Server) WSO(w http.ResponseWriter, r *http.Request) { fmt.Println("Connected") c, err := upgrader.Upgrade(w, r, nil) @@ -64,7 +58,7 @@ func (o *Server) WSO(w http.ResponseWriter, r *http.Request) { return } // Register new server - serverID := strconv.Itoa(rand.Int()) + serverID := uuid.Must(uuid.NewV4()).String() log.Println("Overlord: A new server connected to Overlord", serverID) // Register to servers map the client connection @@ -100,9 +94,11 @@ func (o *Server) WSO(w http.ResponseWriter, r *http.Request) { Data: o.roomToServer[resp.Data], } }) + client.Listen() } +// WSO handles all connections from frontend to overlord func (o *Server) WS(w http.ResponseWriter, r *http.Request) { log.Println("Browser connected to overlord") //TODO: Add it back @@ -145,6 +141,7 @@ func (o *Server) WS(w http.ResponseWriter, r *http.Request) { wssession.BrowserClient.Listen() } +// findBestServer returns the best server for a session func (o *Server) findBestServer() (string, error) { // TODO: Find best Server by latency, currently return by ping if len(o.servers) == 0 { diff --git a/overlord/worker.go b/overlord/worker.go index 616fccb9..1458db64 100644 --- a/overlord/worker.go +++ b/overlord/worker.go @@ -35,40 +35,24 @@ func (s *Session) RouteWorker() { return cws.EmptyPacket }) - workerClient.Receive("quit", func(resp cws.WSPacket) (req cws.WSPacket) { - log.Println("Received quit", req) - s.GameName = resp.Data - s.RoomID = resp.RoomID - s.PlayerIndex = resp.PlayerIndex + //workerClient.Receive("quit", func(resp cws.WSPacket) (req cws.WSPacket) { + //log.Println("Overlord: Received quit request from a worker") + //log.Println("Overlord: Sending back sdp to browser") + //s.GameName = resp.Data + //s.RoomID = resp.RoomID + //s.PlayerIndex = resp.PlayerIndex - // TODO: - //room := s.handler.getRoom(s.RoomID) - //if room.IsPCInRoom(s.peerconnection) { - //s.handler.detachPeerConn(s.peerconnection) - //} - log.Println("Sending to target host", resp.TargetHostID, " ", resp) - resp = s.handler.servers[resp.TargetHostID].SyncSend( - resp, - ) + //// TODO: + ////room := s.handler.getRoom(s.RoomID) + ////if room.IsPCInRoom(s.peerconnection) { + ////s.handler.detachPeerConn(s.peerconnection) + ////} + //log.Println("Sending to target host", resp.TargetHostID, " ", resp) + //resp = s.handler.servers[resp.TargetHostID].SyncSend( + //resp, + //) - return cws.EmptyPacket - }) - - //browserClient.Receive("initwebrtc", func(resp cws.WSPacket) cws.WSPacket { - //log.Println("Received user SDP") - //localSession, err := s.peerconnection.StartClient(resp.Data, iceCandidates, config.Width, config.Height) - //if err != nil { - //if err != nil { - //log.Println("Error: Cannot create new webrtc session", err) //return cws.EmptyPacket - //} - //} - - //return cws.WSPacket{ - //ID: "sdp", - //Data: localSession, - //SessionID: s.ID, - //} //}) // TODO: Add save and load diff --git a/handler/cloud-storage/storage.go b/worker/cloud-storage/storage.go similarity index 100% rename from handler/cloud-storage/storage.go rename to worker/cloud-storage/storage.go diff --git a/handler/cloud-storage/storage_test.go b/worker/cloud-storage/storage_test.go similarity index 100% rename from handler/cloud-storage/storage_test.go rename to worker/cloud-storage/storage_test.go diff --git a/handler/handlers.go b/worker/handlers.go similarity index 72% rename from handler/handlers.go rename to worker/handlers.go index 8f2d293c..af886360 100644 --- a/handler/handlers.go +++ b/worker/handlers.go @@ -1,13 +1,11 @@ -package handler +package worker import ( - "io/ioutil" "log" - "net/http" - storage "github.com/giongto35/cloud-game/handler/cloud-storage" - "github.com/giongto35/cloud-game/handler/room" "github.com/giongto35/cloud-game/webrtc" + storage "github.com/giongto35/cloud-game/worker/cloud-storage" + "github.com/giongto35/cloud-game/worker/room" "github.com/gorilla/websocket" ) @@ -26,13 +24,8 @@ type Handler struct { rooms map[string]*room.Room // ID of the current server globalwise serverID string - // isDebug determines the mode handler is running - //isDebug bool // Path to game list gamePath string - // All webrtc peerconnections are handled by the server - // ID -> peerconnections - peerconnections map[string]*webrtc.WebRTC // onlineStorage is client accessing to online storage (GCP) onlineStorage *storage.Client // sessions handles all sessions server is handler (key is sessionID) @@ -42,21 +35,18 @@ type Handler struct { // NewHandler returns a new server func NewHandler(overlordConn *websocket.Conn, isDebug bool, gamePath string) *Handler { onlineStorage := storage.NewInitClient() - oClient := NewOverlordClient(overlordConn) + return &Handler{ - oClient: oClient, - rooms: map[string]*room.Room{}, - peerconnections: map[string]*webrtc.WebRTC{}, - - sessions: map[string]*Session{}, - //isDebug: isDebug, - gamePath: gamePath, - + oClient: oClient, + rooms: map[string]*room.Room{}, + sessions: map[string]*Session{}, + gamePath: gamePath, onlineStorage: onlineStorage, } } +// Run starts a Handler running logic func (h *Handler) Run() { go h.oClient.Heartbeat() @@ -64,23 +54,7 @@ func (h *Handler) Run() { h.oClient.Listen() } -// GetWeb returns web frontend -func (h *Handler) GetWeb(w http.ResponseWriter, r *http.Request) { - indexFN := "" - //if h.isDebug { - //indexFN = debugIndex - //} else { - indexFN = gameboyIndex - //} - - bs, err := ioutil.ReadFile(indexFN) - if err != nil { - log.Fatal(err) - } - w.Write(bs) -} - -// Detach peerconnection detach/remove a peerconnection from current room +// detachPeerConn detach/remove a peerconnection from current room func (h *Handler) detachPeerConn(pc *webrtc.WebRTC) { log.Println("Detach peerconnection") roomID := pc.RoomID diff --git a/handler/overlord.go b/worker/overlord.go similarity index 98% rename from handler/overlord.go rename to worker/overlord.go index e7d47935..2ae25f42 100644 --- a/handler/overlord.go +++ b/worker/overlord.go @@ -1,12 +1,12 @@ -package handler +package worker import ( "log" "github.com/giongto35/cloud-game/config" "github.com/giongto35/cloud-game/cws" - "github.com/giongto35/cloud-game/handler/room" "github.com/giongto35/cloud-game/webrtc" + "github.com/giongto35/cloud-game/worker/room" "github.com/gorilla/websocket" ) diff --git a/handler/room/media.go b/worker/room/media.go similarity index 100% rename from handler/room/media.go rename to worker/room/media.go diff --git a/handler/room/room.go b/worker/room/room.go similarity index 98% rename from handler/room/room.go rename to worker/room/room.go index 501ef723..b835f574 100644 --- a/handler/room/room.go +++ b/worker/room/room.go @@ -10,8 +10,8 @@ import ( "sync" emulator "github.com/giongto35/cloud-game/emulator" - storage "github.com/giongto35/cloud-game/handler/cloud-storage" "github.com/giongto35/cloud-game/webrtc" + storage "github.com/giongto35/cloud-game/worker/cloud-storage" ) // Room is a game session. multi webRTC sessions can connect to a same game. diff --git a/handler/session.go b/worker/session.go similarity index 67% rename from handler/session.go rename to worker/session.go index bf578ea7..f18e6f4e 100644 --- a/handler/session.go +++ b/worker/session.go @@ -1,4 +1,4 @@ -package handler +package worker import "github.com/giongto35/cloud-game/webrtc" @@ -7,16 +7,9 @@ import "github.com/giongto35/cloud-game/webrtc" // connection to browser is 1-1. connection to overlord is n - 1 // Peerconnection can be from other server to ensure better latency type Session struct { - ID string - //BrowserClient *BrowserClient - //OverlordClient *OverlordClient + ID string peerconnection *webrtc.WebRTC - // TODO: Decouple this - //handler *Handler - - //ServerID string - //GameName string + // Should I make direct reference RoomID string - //PlayerIndex int }