cloud-game/pkg/coordinator/browser.go
trichimtrich 5dcf4ac95f
Add support firefox safari ios (#175)
* change rtc offer/answer direction

* remove overlay log

* merge browser+session, fix log, add browser map

* add candidate transfer on worker + web
2020-04-28 02:20:49 +08:00

174 lines
4.4 KiB
Go

package coordinator
import (
"fmt"
"log"
"github.com/giongto35/cloud-game/pkg/cws"
"github.com/gorilla/websocket"
)
type BrowserClient struct {
*cws.Client
SessionID string
RoomID string
WorkerID string // TODO: how about pointer to workerClient?
}
// NewCoordinatorClient returns a client connecting to browser.
// This connection exchanges information between browser and coordinator.
func NewBrowserClient(c *websocket.Conn, browserID string) *BrowserClient {
return &BrowserClient{
Client: cws.NewClient(c),
SessionID: browserID,
}
}
// Register new log
func (bc *BrowserClient) Printf(format string, args ...interface{}) {
newFmt := fmt.Sprintf("Browser %s] %s", bc.SessionID, format)
log.Printf(newFmt, args...)
}
func (bc *BrowserClient) Println(args ...interface{}) {
msg := fmt.Sprintf("Browser %s] %s", bc.SessionID, fmt.Sprint(args...))
log.Println(msg)
}
// RouteBrowser
// Register callbacks for connection from browser -> coordinator
func (o *Server) RouteBrowser(client *BrowserClient) {
/* WebSocket */
client.Receive("heartbeat", func(resp cws.WSPacket) cws.WSPacket {
return resp
})
/* WebRTC */
client.Receive("initwebrtc", func(resp cws.WSPacket) cws.WSPacket {
// initwebrtc now only sends signal to worker, asks it to createOffer
client.Printf("Received initwebrtc request -> relay to worker: %s", client.WorkerID)
// relay request to target worker
// worker creates a PeerConnection, and createOffer
// send SDP back to browser
resp.SessionID = client.SessionID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
sdp := wc.SyncSend(resp)
client.Println("Received SDP from worker -> sending back to browser")
return sdp
})
client.Receive("answer", func(resp cws.WSPacket) cws.WSPacket {
// contains SDP of browser createAnswer
// forward to worker
client.Println("Received browser answered SDP -> relay to worker")
resp.SessionID = client.SessionID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
wc.Send(resp, nil)
// no need to response
return cws.EmptyPacket
})
client.Receive("candidate", func(resp cws.WSPacket) cws.WSPacket {
// contains ICE candidate of browser
// forward to worker
client.Println("Received IceCandidate from browser -> relay to worker")
resp.SessionID = client.SessionID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
wc.Send(resp, nil)
return cws.EmptyPacket
})
/* GameLogic */
client.Receive("quit", func(resp cws.WSPacket) (req cws.WSPacket) {
client.Println("Received quit request from a browser -> relay to worker")
// TODO: Async
resp.SessionID = client.SessionID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
// Send but, waiting
wc.SyncSend(resp)
return cws.EmptyPacket
})
client.Receive("start", func(resp cws.WSPacket) cws.WSPacket {
client.Println("Received start request from a browser -> relay to worker")
// TODO: Async
resp.SessionID = client.SessionID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
workerResp := wc.SyncSend(resp)
// Response from worker contains initialized roomID. Set roomID to the session
client.RoomID = workerResp.RoomID
client.Println("Received room response from browser: ", workerResp.RoomID)
return workerResp
})
client.Receive("save", func(resp cws.WSPacket) (req cws.WSPacket) {
client.Println("Received save request from a browser -> relay to worker")
// TODO: Async
resp.SessionID = client.SessionID
resp.RoomID = client.RoomID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
resp = wc.SyncSend(resp)
return resp
})
client.Receive("load", func(resp cws.WSPacket) (req cws.WSPacket) {
client.Println("Received load request from a browser -> relay to worker")
// TODO: Async
resp.SessionID = client.SessionID
resp.RoomID = client.RoomID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
resp = wc.SyncSend(resp)
return resp
})
client.Receive("playerIdx", func(resp cws.WSPacket) (req cws.WSPacket) {
client.Println("Received update player index request from a browser -> relay to worker")
// TODO: Async
resp.SessionID = client.SessionID
resp.RoomID = client.RoomID
wc, ok := o.workerClients[client.WorkerID]
if !ok {
return cws.EmptyPacket
}
resp = wc.SyncSend(resp)
return resp
})
}