mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-22 09:37:09 +00:00
Merge pull request #28 from giongto35/fix-closed-channel-bug
Fix closed channel bug
This commit is contained in:
commit
ea020bd7ae
5 changed files with 68 additions and 44 deletions
|
|
@ -46,6 +46,9 @@ func (s *Session) RouteBrowser() {
|
|||
req.Data = "ok"
|
||||
if s.RoomID != "" {
|
||||
room := s.handler.getRoom(s.RoomID)
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
err := room.SaveGame()
|
||||
if err != nil {
|
||||
log.Println("[!] Cannot save game state: ", err)
|
||||
|
|
@ -95,17 +98,27 @@ func (s *Session) RouteBrowser() {
|
|||
}
|
||||
}
|
||||
|
||||
// Create new room
|
||||
// Get Room in local server
|
||||
// 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
|
||||
s.handler.detachPeerConn(s.peerconnection)
|
||||
room.AddConnectionToRoom(s.peerconnection, s.PlayerIndex)
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -112,18 +112,14 @@ func (h *Handler) WS(w http.ResponseWriter, r *http.Request) {
|
|||
Data: gamelist.GetEncodedGameList(h.gamePath),
|
||||
}, nil)
|
||||
|
||||
wssession.BrowserClient.Listen()
|
||||
|
||||
// TODO: Use callback
|
||||
// If peerconnection is done (client.Done is signalled), we close peerconnection
|
||||
go func() {
|
||||
for {
|
||||
<-client.Done
|
||||
h.detachPeerConn(wssession.peerconnection)
|
||||
return
|
||||
}
|
||||
<-client.Done
|
||||
log.Println("Socket terminated, detach connection")
|
||||
h.detachPeerConn(wssession.peerconnection)
|
||||
}()
|
||||
|
||||
wssession.BrowserClient.Listen()
|
||||
}
|
||||
|
||||
// Detach peerconnection detach/remove a peerconnection from current room
|
||||
|
|
@ -147,6 +143,11 @@ func (h *Handler) getRoom(roomID string) *room.Room {
|
|||
return room
|
||||
}
|
||||
|
||||
// detachRoom detach room from Handler
|
||||
func (h *Handler) detachRoom(roomID string) {
|
||||
delete(h.rooms, roomID)
|
||||
}
|
||||
|
||||
// createNewRoom creates a new room
|
||||
// Return nil in case of room is existed
|
||||
func (h *Handler) createNewRoom(gameName string, roomID string, playerIndex int) *room.Room {
|
||||
|
|
@ -172,5 +173,5 @@ func (h *Handler) isRoomRunning(roomID string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
return room.IsRunning()
|
||||
return room.IsRunningSessions()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func (r *Room) startAudio() {
|
|||
log.Println("Warn: Room ", r.ID, " audio channel closed unexpectedly")
|
||||
return
|
||||
}
|
||||
if r.Done {
|
||||
if !r.IsRunning {
|
||||
log.Println("Room ", r.ID, " audio channel closed")
|
||||
return
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ func (r *Room) startVideo() {
|
|||
log.Println("Warn: Room ", r.ID, " video channel closed unexpectedly")
|
||||
return
|
||||
}
|
||||
if r.Done {
|
||||
if !r.IsRunning {
|
||||
log.Println("Room ", r.ID, " video channel closed")
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package room
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
|
@ -20,17 +19,22 @@ import (
|
|||
type Room struct {
|
||||
ID string
|
||||
|
||||
// imageChannel is image stream from director
|
||||
imageChannel chan *image.RGBA
|
||||
// audioChannel is audio stream from director
|
||||
audioChannel chan float32
|
||||
// inputChannel is input stream from websocket to room
|
||||
inputChannel chan int
|
||||
// Done channel is to fire exit event when there is no webRTC session running
|
||||
Done bool
|
||||
|
||||
rtcSessions []*webrtc.WebRTC
|
||||
// State of room
|
||||
IsRunning bool
|
||||
// Done channel is to fire exit event when room is closed
|
||||
Done chan struct{}
|
||||
// List of peerconnections in the room
|
||||
rtcSessions []*webrtc.WebRTC
|
||||
// NOTE: Not in use, lock rtcSessions
|
||||
sessionsLock *sync.Mutex
|
||||
|
||||
// Director is emulator
|
||||
director *emulator.Director
|
||||
|
||||
// Cloud storage to store room state online
|
||||
onlineStorage *storage.Client
|
||||
}
|
||||
|
|
@ -58,8 +62,10 @@ func NewRoom(roomID, gamepath, gameName string, onlineStorage *storage.Client) *
|
|||
rtcSessions: []*webrtc.WebRTC{},
|
||||
sessionsLock: &sync.Mutex{},
|
||||
director: director,
|
||||
Done: false,
|
||||
IsRunning: true,
|
||||
onlineStorage: onlineStorage,
|
||||
|
||||
Done: make(chan struct{}),
|
||||
}
|
||||
|
||||
go room.startVideo()
|
||||
|
|
@ -122,7 +128,7 @@ func (r *Room) startWebRTCSession(peerconnection *webrtc.WebRTC, playerIndex int
|
|||
// might consider continue here
|
||||
}
|
||||
|
||||
if peerconnection.Done || !peerconnection.IsConnected() || r.Done {
|
||||
if peerconnection.Done || !peerconnection.IsConnected() || !r.IsRunning {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -147,14 +153,13 @@ func (r *Room) CleanSession(peerconnection *webrtc.WebRTC) {
|
|||
}
|
||||
|
||||
func (r *Room) removeSession(w *webrtc.WebRTC) {
|
||||
fmt.Println("Cleaning session: ", w)
|
||||
fmt.Println("Sessions list", r.rtcSessions)
|
||||
log.Println("Cleaning session: ", w.ID)
|
||||
// TODO: get list of r.rtcSessions in lock
|
||||
for i, s := range r.rtcSessions {
|
||||
fmt.Println("found session: ", s, w)
|
||||
log.Println("found session: ", w.ID)
|
||||
if s.ID == w.ID {
|
||||
r.rtcSessions = append(r.rtcSessions[:i], r.rtcSessions[i+1:]...)
|
||||
fmt.Println("found session: ", len(r.rtcSessions))
|
||||
log.Println("Removed session ", s.ID, " from room: ", r.ID)
|
||||
|
||||
// If room has no sessions, close room
|
||||
// Note: this logic cannot be brought outside of forloop because we only close room if room had at least one session
|
||||
|
|
@ -169,17 +174,28 @@ func (r *Room) removeSession(w *webrtc.WebRTC) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Reuse for remove Session
|
||||
func (r *Room) IsPCInRoom(w *webrtc.WebRTC) bool {
|
||||
for _, s := range r.rtcSessions {
|
||||
if s.ID == w.ID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *Room) Close() {
|
||||
if r.Done {
|
||||
if !r.IsRunning {
|
||||
return
|
||||
}
|
||||
|
||||
r.IsRunning = false
|
||||
log.Println("Closing room", r.ID)
|
||||
log.Println("Closing director of room ", r.ID)
|
||||
close(r.director.Done)
|
||||
log.Println("Closing input of room ", r.ID)
|
||||
close(r.inputChannel)
|
||||
r.Done = true
|
||||
close(r.Done)
|
||||
// Close here is a bit wrong because this read channel
|
||||
//close(r.imageChannel)
|
||||
//close(r.audioChannel)
|
||||
|
|
@ -223,7 +239,7 @@ func (r *Room) LoadGame() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (r *Room) IsRunning() bool {
|
||||
func (r *Room) IsRunningSessions() bool {
|
||||
// If there is running session
|
||||
for _, s := range r.rtcSessions {
|
||||
if s.IsConnected() {
|
||||
|
|
|
|||
|
|
@ -93,12 +93,12 @@ type WebRTC struct {
|
|||
|
||||
// StartClient start webrtc
|
||||
func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println(err)
|
||||
w.StopClient()
|
||||
}
|
||||
}()
|
||||
//defer func() {
|
||||
//if err := recover(); err != nil {
|
||||
//log.Println(err)
|
||||
//w.StopClient()
|
||||
//}
|
||||
//}()
|
||||
|
||||
// reset client
|
||||
if w.isConnected {
|
||||
|
|
@ -156,19 +156,13 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e
|
|||
|
||||
// Register text message handling
|
||||
inputTrack.OnMessage(func(msg webrtc.DataChannelMessage) {
|
||||
//layout .:= "2006-01-02T15:04:05.000Z"
|
||||
//if t, err := time.Parse(layout, string(msg.Data[1])); err == nil {
|
||||
//fmt.Println("Delay ", time.Now().Sub(t))
|
||||
//} else {
|
||||
// TODO: Can add recover here
|
||||
w.InputChannel <- int(msg.Data[0])
|
||||
//}
|
||||
})
|
||||
|
||||
inputTrack.OnClose(func() {
|
||||
log.Println("Data channel closed")
|
||||
log.Println("Closed webrtc")
|
||||
//close(w.Done)
|
||||
//w.StopClient()
|
||||
})
|
||||
|
||||
// WebRTC state callback
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue