mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-22 17:47:11 +00:00
Separate create room logic
This commit is contained in:
parent
7ea7e9b5f0
commit
c00d7c8491
6 changed files with 103 additions and 46 deletions
|
|
@ -116,7 +116,6 @@ func initClient(t *testing.T, host string) {
|
|||
RoomID: "",
|
||||
PlayerIndex: 1,
|
||||
}, func(resp cws.WSPacket) {
|
||||
fmt.Println("Received response")
|
||||
fmt.Println("RoomID:", resp.RoomID)
|
||||
roomID <- resp.RoomID
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package handler
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/giongto35/cloud-game/config"
|
||||
|
|
@ -80,7 +81,6 @@ func (s *Session) RegisterBrowserClient() {
|
|||
s.GameName = resp.Data
|
||||
s.RoomID = resp.RoomID
|
||||
s.PlayerIndex = resp.PlayerIndex
|
||||
isNewRoom := false
|
||||
|
||||
log.Println("Starting game")
|
||||
// If we are connecting to overlord, request serverID from roomID
|
||||
|
|
@ -94,9 +94,11 @@ func (s *Session) RegisterBrowserClient() {
|
|||
}
|
||||
}
|
||||
|
||||
s.RoomID, isNewRoom = startSession(s.peerconnection, s.GameName, s.RoomID, s.PlayerIndex)
|
||||
room := s.handler.createNewRoom(s.GameName, s.RoomID, s.PlayerIndex)
|
||||
room.addConnectionToRoom(s.peerconnection, s.PlayerIndex)
|
||||
s.RoomID = room.ID
|
||||
// Register room to overlord if we are connecting to overlord
|
||||
if isNewRoom && s.OverlordClient != nil {
|
||||
if room != nil && s.OverlordClient != nil {
|
||||
s.OverlordClient.Send(cws.WSPacket{
|
||||
ID: "registerRoom",
|
||||
Data: s.RoomID,
|
||||
|
|
@ -105,6 +107,7 @@ func (s *Session) RegisterBrowserClient() {
|
|||
req.ID = "start"
|
||||
req.RoomID = s.RoomID
|
||||
req.SessionID = s.ID
|
||||
fmt.Println("Response from start", req)
|
||||
|
||||
return req
|
||||
})
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ func (h *Handler) WS(w http.ResponseWriter, r *http.Request) {
|
|||
BrowserClient: client,
|
||||
OverlordClient: h.oClient,
|
||||
peerconnection: webrtc.NewWebRTC(),
|
||||
handler: h,
|
||||
}
|
||||
wssession.RegisterBrowserClient()
|
||||
fmt.Println("oclient : ", h.oClient)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import (
|
|||
"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
|
||||
|
|
@ -26,6 +28,7 @@ func NewOverlordClient(oc *websocket.Conn) *OverlordClient {
|
|||
return oclient
|
||||
}
|
||||
|
||||
// RegisterOverlordClient routes overlord Client
|
||||
func (s *Session) RegisterOverlordClient() {
|
||||
oclient := s.OverlordClient
|
||||
|
||||
|
|
@ -64,7 +67,7 @@ func (s *Session) RegisterOverlordClient() {
|
|||
},
|
||||
)
|
||||
|
||||
// Received start from overlord. This is happens when bridging
|
||||
// Received start from overlord. This happens when bridging
|
||||
// TODO: refactor
|
||||
oclient.Receive(
|
||||
"start",
|
||||
|
|
@ -74,16 +77,24 @@ func (s *Session) RegisterOverlordClient() {
|
|||
|
||||
peerconnection := oclient.peerconnections[resp.SessionID]
|
||||
log.Println("start session")
|
||||
roomID, isNewRoom := startSession(peerconnection, resp.Data, resp.RoomID, resp.PlayerIndex)
|
||||
|
||||
//room := s.handler.createNewRoom(s.GameName, s.RoomID, s.PlayerIndex)
|
||||
room := s.handler.getRoom(s.RoomID)
|
||||
if room == nil {
|
||||
log.Println("Room not found", s.RoomID)
|
||||
return cws.EmptyPacket
|
||||
}
|
||||
room.addConnectionToRoom(peerconnection, s.PlayerIndex)
|
||||
//roomID, isNewRoom := startSession(peerconnection, resp.Data, resp.RoomID, resp.PlayerIndex)
|
||||
log.Println("Done, sending back")
|
||||
// Bridge always access to old room
|
||||
// TODO: log warn
|
||||
if isNewRoom == true {
|
||||
if room != nil {
|
||||
log.Fatal("Bridge should not spawn new room")
|
||||
}
|
||||
|
||||
req.ID = "start"
|
||||
req.RoomID = roomID
|
||||
req.RoomID = room.ID
|
||||
return req
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import (
|
|||
// Room is a game session. multi webRTC sessions can connect to a same game.
|
||||
// A room stores all the channel for interaction between all webRTCs session and emulator
|
||||
type Room struct {
|
||||
ID string
|
||||
|
||||
imageChannel chan *image.RGBA
|
||||
audioChannel chan float32
|
||||
inputChannel chan int
|
||||
|
|
@ -36,7 +38,7 @@ func generateRoomID() string {
|
|||
}
|
||||
|
||||
// init initilizes a room returns roomID
|
||||
func initRoom(roomID, gameName string) string {
|
||||
func (h *Handler) initRoom(roomID, gameName string) *Room {
|
||||
// if no roomID is given, generate it
|
||||
if roomID == "" {
|
||||
roomID = generateRoomID()
|
||||
|
|
@ -50,6 +52,8 @@ func initRoom(roomID, gameName string) string {
|
|||
director := emulator.NewDirector(roomID, imageChannel, audioChannel, inputChannel)
|
||||
|
||||
room := &Room{
|
||||
ID: roomID,
|
||||
|
||||
imageChannel: imageChannel,
|
||||
audioChannel: audioChannel,
|
||||
inputChannel: inputChannel,
|
||||
|
|
@ -58,18 +62,17 @@ func initRoom(roomID, gameName string) string {
|
|||
director: director,
|
||||
Done: make(chan struct{}),
|
||||
}
|
||||
rooms[roomID] = room
|
||||
|
||||
go room.startVideo()
|
||||
go room.startAudio()
|
||||
go director.Start([]string{"games/" + gameName})
|
||||
go director.Start([]string{"../games/" + gameName})
|
||||
|
||||
return roomID
|
||||
return room
|
||||
}
|
||||
|
||||
// isRoomRunning check if there is any running sessions.
|
||||
// TODO: If we remove sessions from room anytime a session is closed, we can check if the sessions list is empty or not.
|
||||
func isRoomRunning(roomID string) bool {
|
||||
func (h *Handler) isRoomRunning(roomID string) bool {
|
||||
// If no roomID is registered
|
||||
if _, ok := rooms[roomID]; !ok {
|
||||
return false
|
||||
|
|
@ -84,24 +87,32 @@ func isRoomRunning(roomID string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (r *Room) addConnectionToRoom(peerconnection *webrtc.WebRTC, playerIndex int) {
|
||||
r.cleanSession(peerconnection)
|
||||
peerconnection.AttachRoomID(r.ID)
|
||||
go r.startWebRTCSession(peerconnection, playerIndex)
|
||||
|
||||
r.rtcSessions = append(r.rtcSessions, peerconnection)
|
||||
}
|
||||
|
||||
// startWebRTCSession fan-in of the same room to inputChannel
|
||||
func startWebRTCSession(room *Room, webRTC *webrtc.WebRTC, playerIndex int) {
|
||||
inputChannel := room.inputChannel
|
||||
log.Println("room, inputChannel", room, inputChannel)
|
||||
func (r *Room) startWebRTCSession(peerconnection *webrtc.WebRTC, playerIndex int) {
|
||||
inputChannel := r.inputChannel
|
||||
log.Println("room, inputChannel", r, inputChannel)
|
||||
for {
|
||||
select {
|
||||
case <-webRTC.Done:
|
||||
removeSession(webRTC, room)
|
||||
case <-peerconnection.Done:
|
||||
r.removeSession(peerconnection)
|
||||
default:
|
||||
}
|
||||
// Client stopped
|
||||
if webRTC.IsClosed() {
|
||||
if peerconnection.IsClosed() {
|
||||
return
|
||||
}
|
||||
|
||||
// encode frame
|
||||
if webRTC.IsConnected() {
|
||||
input := <-webRTC.InputChannel
|
||||
if peerconnection.IsConnected() {
|
||||
input := <-peerconnection.InputChannel
|
||||
// the first 8 bits belong to player 1
|
||||
// the next 8 belongs to player 2 ...
|
||||
// We standardize and put it to inputChannel (16 bits)
|
||||
|
|
@ -111,26 +122,22 @@ func startWebRTCSession(room *Room, webRTC *webrtc.WebRTC, playerIndex int) {
|
|||
}
|
||||
}
|
||||
|
||||
func cleanSession(w *webrtc.WebRTC) {
|
||||
room, ok := rooms[w.RoomID]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
removeSession(w, room)
|
||||
func (r *Room) cleanSession(peerconnection *webrtc.WebRTC) {
|
||||
r.removeSession(peerconnection)
|
||||
}
|
||||
|
||||
func removeSession(w *webrtc.WebRTC, room *Room) {
|
||||
room.sessionsLock.Lock()
|
||||
defer room.sessionsLock.Unlock()
|
||||
for i, s := range room.rtcSessions {
|
||||
func (r *Room) removeSession(w *webrtc.WebRTC) {
|
||||
r.sessionsLock.Lock()
|
||||
defer r.sessionsLock.Unlock()
|
||||
for i, s := range r.rtcSessions {
|
||||
if s == w {
|
||||
room.rtcSessions = append(room.rtcSessions[:i], room.rtcSessions[i+1:]...)
|
||||
r.rtcSessions = append(r.rtcSessions[:i], r.rtcSessions[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
// If room has no sessions, close room
|
||||
if len(room.rtcSessions) == 0 {
|
||||
room.Done <- struct{}{}
|
||||
if len(r.rtcSessions) == 0 {
|
||||
r.Done <- struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,30 +13,66 @@ type Session struct {
|
|||
OverlordClient *OverlordClient
|
||||
peerconnection *webrtc.WebRTC
|
||||
|
||||
// TODO: Decouple this
|
||||
handler *Handler
|
||||
|
||||
ServerID string
|
||||
GameName string
|
||||
RoomID string
|
||||
PlayerIndex int
|
||||
}
|
||||
|
||||
// startSession handles one session call
|
||||
func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerIndex int) (rRoomID string, isNewRoom bool) {
|
||||
isNewRoom = false
|
||||
cleanSession(webRTC)
|
||||
// getRoom returns room from roomID
|
||||
func (h *Handler) getRoom(roomID string) *Room {
|
||||
room, ok := h.rooms[roomID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return room
|
||||
}
|
||||
|
||||
// createNewRoom creates a new room
|
||||
// Return nil in case of room is existed
|
||||
func (h *Handler) createNewRoom(gameName string, roomID string, playerIndex int) *Room {
|
||||
//cleanSession(peerconnection)
|
||||
// If the roomID is empty,
|
||||
// or the roomID doesn't have any running sessions (room was closed)
|
||||
// we spawn a new room
|
||||
if roomID == "" || !isRoomRunning(roomID) {
|
||||
roomID = initRoom(roomID, gameName)
|
||||
isNewRoom = true
|
||||
if roomID == "" || !h.isRoomRunning(roomID) {
|
||||
room := h.initRoom(roomID, gameName)
|
||||
h.rooms[roomID] = room
|
||||
return room
|
||||
}
|
||||
|
||||
// TODO: Might have race condition
|
||||
rooms[roomID].rtcSessions = append(rooms[roomID].rtcSessions, webRTC)
|
||||
room := rooms[roomID]
|
||||
//rooms[roomID].rtcSessions = append(rooms[roomID].rtcSessions, peerconnection)
|
||||
//room := rooms[roomID]
|
||||
|
||||
webRTC.AttachRoomID(roomID)
|
||||
go startWebRTCSession(room, webRTC, playerIndex)
|
||||
//peerconnection.AttachRoomID(roomID)
|
||||
//go startWebRTCSession(room, peerconnection, playerIndex)
|
||||
|
||||
return roomID, isNewRoom
|
||||
return nil
|
||||
}
|
||||
|
||||
// startPeerConnection handles one peerconnection call
|
||||
//func (s *Handler) startPeerConnection( gameName string, roomID string, playerIndex int) (rRoomID string, isNewRoom bool) {
|
||||
//isNewRoom = false
|
||||
//cleanSession(peerconnection)
|
||||
//// If the roomID is empty,
|
||||
//// or the roomID doesn't have any running sessions (room was closed)
|
||||
//// we spawn a new room
|
||||
//if roomID == "" || !isRoomRunning(roomID) {
|
||||
//roomID = initRoom(roomID, gameName)
|
||||
//isNewRoom = true
|
||||
//}
|
||||
|
||||
//// TODO: Might have race condition
|
||||
//rooms[roomID].rtcSessions = append(rooms[roomID].rtcSessions, peerconnection)
|
||||
//room := rooms[roomID]
|
||||
|
||||
//peerconnection.AttachRoomID(roomID)
|
||||
//go startWebRTCSession(room, peerconnection, playerIndex)
|
||||
|
||||
//return roomID, isNewRoom
|
||||
//}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue