mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-23 10:07:30 +00:00
Register server IP
This commit is contained in:
parent
d58f8e37c8
commit
3a34fab098
3 changed files with 191 additions and 91 deletions
190
main.go
190
main.go
|
|
@ -145,13 +145,14 @@ func isRoomRunning(roomID string) bool {
|
|||
}
|
||||
|
||||
// startSession handles one session call
|
||||
func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerIndex int) string {
|
||||
func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerIndex int) (rRoomID string, isNewRoom bool) {
|
||||
cleanSession(webRTC)
|
||||
// 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
|
||||
|
|
@ -161,40 +162,14 @@ func startSession(webRTC *webrtc.WebRTC, gameName string, roomID string, playerI
|
|||
webRTC.AttachRoomID(roomID)
|
||||
go startWebRTCSession(room, webRTC, playerIndex)
|
||||
|
||||
return roomID
|
||||
return roomID, false
|
||||
}
|
||||
|
||||
// If it's overlord, handle overlord connection (from host to overlord)
|
||||
func wso(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("Connected")
|
||||
c, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Print("[!] WS upgrade:", err)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
client := NewClient(c, webrtc.NewWebRTC())
|
||||
|
||||
client.syncReceive("ping", func(req WSPacket) WSPacket {
|
||||
log.Println("received Ping, sending Pong")
|
||||
return WSPacket{
|
||||
ID: "pong",
|
||||
}
|
||||
})
|
||||
client.listen()
|
||||
}
|
||||
|
||||
const overlordHost = "ws://localhost:9000/wso"
|
||||
|
||||
func createOverlordClient() (*websocket.Conn, error) {
|
||||
c, _, err := websocket.DefaultDialer.Dial(overlordHost, nil)
|
||||
if err != nil {
|
||||
log.Fatal("dial:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
// Session represents a session connected from the browser to the current server
|
||||
type Session struct {
|
||||
client *Client
|
||||
oclient *Client
|
||||
ServerID string
|
||||
}
|
||||
|
||||
// Handle normal traffic (from browser to host)
|
||||
|
|
@ -209,11 +184,22 @@ func ws(w http.ResponseWriter, r *http.Request) {
|
|||
var roomID string
|
||||
var playerIndex int
|
||||
|
||||
var oclient *Client
|
||||
// Create connection to overlord
|
||||
client := NewClient(c, webrtc.NewWebRTC())
|
||||
|
||||
client.syncReceive("initwebrtc", func(req WSPacket) WSPacket {
|
||||
wssession := Session{
|
||||
client: client,
|
||||
// The server session is maintaining
|
||||
}
|
||||
|
||||
if !IsOverlord {
|
||||
wssession.NewOverlordClient()
|
||||
}
|
||||
|
||||
client.syncReceive("initwebrtc", func(resp WSPacket) WSPacket {
|
||||
log.Println("Received user SDP")
|
||||
localSession, err := client.peerconnection.StartClient(req.Data, width, height)
|
||||
localSession, err := client.peerconnection.StartClient(resp.Data, width, height)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
|
@ -224,84 +210,75 @@ func ws(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
})
|
||||
|
||||
client.syncReceive("save", func(req WSPacket) (res WSPacket) {
|
||||
client.syncReceive("save", func(resp WSPacket) (req WSPacket) {
|
||||
log.Println("Saving game state")
|
||||
res.ID = "save"
|
||||
res.Data = "ok"
|
||||
req.ID = "save"
|
||||
req.Data = "ok"
|
||||
if roomID != "" {
|
||||
err = rooms[roomID].director.SaveGame()
|
||||
if err != nil {
|
||||
log.Println("[!] Cannot save game state: ", err)
|
||||
res.Data = "error"
|
||||
req.Data = "error"
|
||||
}
|
||||
} else {
|
||||
res.Data = "error"
|
||||
req.Data = "error"
|
||||
}
|
||||
|
||||
return res
|
||||
return req
|
||||
})
|
||||
|
||||
client.syncReceive("load", func(req WSPacket) (res WSPacket) {
|
||||
client.syncReceive("load", func(resp WSPacket) (req WSPacket) {
|
||||
log.Println("Loading game state")
|
||||
res.ID = "load"
|
||||
res.Data = "ok"
|
||||
req.ID = "load"
|
||||
req.Data = "ok"
|
||||
if roomID != "" {
|
||||
err = rooms[roomID].director.LoadGame()
|
||||
if err != nil {
|
||||
log.Println("[!] Cannot load game state: ", err)
|
||||
res.Data = "error"
|
||||
req.Data = "error"
|
||||
}
|
||||
} else {
|
||||
res.Data = "error"
|
||||
req.Data = "error"
|
||||
}
|
||||
|
||||
return res
|
||||
return req
|
||||
})
|
||||
|
||||
client.syncReceive("start", func(req WSPacket) (res WSPacket) {
|
||||
gameName = req.Data
|
||||
roomID = req.RoomID
|
||||
playerIndex = req.PlayerIndex
|
||||
client.syncReceive("start", func(resp WSPacket) (req WSPacket) {
|
||||
gameName = resp.Data
|
||||
roomID = resp.RoomID
|
||||
playerIndex = resp.PlayerIndex
|
||||
isNewRoom := false
|
||||
//log.Println("Ping from server with game:", gameName)
|
||||
//res.ID = "pong"
|
||||
log.Println("Starting game")
|
||||
roomID = startSession(client.peerconnection, gameName, roomID, playerIndex)
|
||||
res.ID = "start"
|
||||
res.RoomID = roomID
|
||||
roomID, isNewRoom = startSession(client.peerconnection, gameName, roomID, playerIndex)
|
||||
if isNewRoom {
|
||||
oclient.send(WSPacket{
|
||||
ID: "RegisterRoom",
|
||||
Data: roomID,
|
||||
})
|
||||
}
|
||||
req.ID = "start"
|
||||
req.RoomID = roomID
|
||||
|
||||
return res
|
||||
return req
|
||||
})
|
||||
|
||||
client.syncReceive("candidate", func(req WSPacket) (res WSPacket) {
|
||||
client.syncReceive("candidate", func(resp WSPacket) (req WSPacket) {
|
||||
// Unuse code
|
||||
hi := pionRTC.ICECandidateInit{}
|
||||
err = json.Unmarshal([]byte(req.Data), &hi)
|
||||
err = json.Unmarshal([]byte(resp.Data), &hi)
|
||||
if err != nil {
|
||||
log.Println("[!] Cannot parse candidate: ", err)
|
||||
} else {
|
||||
// webRTC.AddCandidate(hi)
|
||||
}
|
||||
res.ID = "candidate"
|
||||
req.ID = "candidate"
|
||||
|
||||
return res
|
||||
return req
|
||||
})
|
||||
|
||||
// Create connection to overlord
|
||||
if !IsOverlord {
|
||||
oc, err := createOverlordClient()
|
||||
if err != nil {
|
||||
log.Println("Cannot connect to overlord")
|
||||
}
|
||||
oclient := NewClient(oc, webrtc.NewWebRTC())
|
||||
oclient.syncSend(WSPacket{
|
||||
ID: "ping",
|
||||
},
|
||||
func(resp WSPacket) {
|
||||
log.Println("pong")
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
client.listen()
|
||||
}
|
||||
|
||||
|
|
@ -398,12 +375,57 @@ func removeSession(w *webrtc.WebRTC, room *Room) {
|
|||
}
|
||||
}
|
||||
|
||||
//func (o *Overlord) isRemoteRoom(roomID string) bool {
|
||||
//err := c.WriteMessage(websocket.TextMessage, []byte(stRes))
|
||||
//o.ws.WriteMessage()
|
||||
//_, message, err := o.ws.ReadMessage()
|
||||
//if message == "isRemoteRoom" {
|
||||
//return true
|
||||
//}
|
||||
//return false
|
||||
//}
|
||||
func GetServerIDOfRoom(oc Client, roomID string) chan string {
|
||||
res := make(chan string)
|
||||
|
||||
oc.syncSend(WSPacket{
|
||||
ID: "getRoom",
|
||||
}, func(resp WSPacket) {
|
||||
res <- resp.Data
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
const overlordHost = "ws://localhost:9000/wso"
|
||||
|
||||
func createOverlordConnection() (*websocket.Conn, error) {
|
||||
c, _, err := websocket.DefaultDialer.Dial(overlordHost, nil)
|
||||
if err != nil {
|
||||
log.Fatal("dial:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (s *Session) NewOverlordClient() {
|
||||
oc, err := createOverlordConnection()
|
||||
if err != nil {
|
||||
log.Println("Cannot connect to overlord")
|
||||
}
|
||||
oclient := NewClient(oc, webrtc.NewWebRTC())
|
||||
oclient.syncSend(
|
||||
WSPacket{
|
||||
ID: "ping",
|
||||
},
|
||||
func(resp WSPacket) {
|
||||
log.Println("Received pong full flow")
|
||||
},
|
||||
)
|
||||
|
||||
// Received from overlord the serverID
|
||||
oclient.syncReceive(
|
||||
"serverID",
|
||||
func(response WSPacket) (request WSPacket) {
|
||||
// Stick session with serverID got from overlord
|
||||
log.Println("Received serverID ", response.Data)
|
||||
s.ServerID = response.Data
|
||||
|
||||
return EmptyPacket
|
||||
},
|
||||
)
|
||||
|
||||
go oclient.listen()
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
|||
57
overlord.go
Normal file
57
overlord.go
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/giongto35/cloud-game/webrtc"
|
||||
)
|
||||
|
||||
var overlordRooms = map[string]string{}
|
||||
|
||||
// servers are the map serverID to server Client
|
||||
var servers = map[string]Client{}
|
||||
|
||||
// If it's overlord, handle overlord connection (from host to overlord)
|
||||
func wso(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("Connected")
|
||||
c, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
log.Print("[!] WS upgrade:", err)
|
||||
return
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
// register new server
|
||||
serverID := strconv.Itoa(rand.Int())
|
||||
log.Println("A new server connected ", serverID)
|
||||
|
||||
client := NewClient(c, webrtc.NewWebRTC())
|
||||
|
||||
client.send(
|
||||
WSPacket{
|
||||
ID: "serverID",
|
||||
Data: serverID,
|
||||
},
|
||||
)
|
||||
|
||||
client.syncReceive("ping", func(resp WSPacket) WSPacket {
|
||||
log.Println("received Ping, sending Pong")
|
||||
return WSPacket{
|
||||
ID: "pong",
|
||||
}
|
||||
})
|
||||
|
||||
client.syncReceive("registerRoom", func(resp WSPacket) WSPacket {
|
||||
log.Println("received registerRoom")
|
||||
overlordRooms[resp.Data] = serverID
|
||||
return WSPacket{
|
||||
ID: "registerRoom",
|
||||
}
|
||||
})
|
||||
|
||||
client.listen()
|
||||
}
|
||||
35
ws.go
35
ws.go
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/giongto35/cloud-game/webrtc"
|
||||
|
|
@ -31,6 +33,8 @@ type WSPacket struct {
|
|||
PacketID string
|
||||
}
|
||||
|
||||
var EmptyPacket = WSPacket{}
|
||||
|
||||
func NewClient(conn *websocket.Conn, webrtc *webrtc.WebRTC) *Client {
|
||||
sendCallback := map[string]func(WSPacket){}
|
||||
recvCallback := map[string]func(WSPacket){}
|
||||
|
|
@ -43,22 +47,39 @@ func NewClient(conn *websocket.Conn, webrtc *webrtc.WebRTC) *Client {
|
|||
}
|
||||
}
|
||||
|
||||
// syncSend sends a packet and trigger callback when the packet comes back
|
||||
func (c *Client) syncSend(packet WSPacket, callback func(msg WSPacket)) {
|
||||
data, err := json.Marshal(packet)
|
||||
// send sends a normal packet
|
||||
func (c *Client) send(request WSPacket) {
|
||||
data, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.conn.WriteMessage(websocket.TextMessage, data)
|
||||
c.sendCallback[packet.PacketID] = callback
|
||||
}
|
||||
|
||||
// syncSend sends a packet and trigger callback when the packet comes back
|
||||
func (c *Client) syncSend(request WSPacket, callback func(response WSPacket)) {
|
||||
request.PacketID = strconv.Itoa(rand.Int())
|
||||
data, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.conn.WriteMessage(websocket.TextMessage, data)
|
||||
c.sendCallback[request.PacketID] = callback
|
||||
}
|
||||
|
||||
// syncReceive receive and response back
|
||||
func (c *Client) syncReceive(id string, f func(request WSPacket) (response WSPacket)) {
|
||||
c.recvCallback[id] = func(request WSPacket) {
|
||||
packet := f(request)
|
||||
func (c *Client) syncReceive(id string, f func(response WSPacket) (request WSPacket)) {
|
||||
c.recvCallback[id] = func(response WSPacket) {
|
||||
packet := f(response)
|
||||
// Add Meta data
|
||||
packet.PacketID = response.PacketID
|
||||
|
||||
// Skip rqeuest if it is EmptyPacket
|
||||
if packet == EmptyPacket {
|
||||
return
|
||||
}
|
||||
resp, err := json.Marshal(packet)
|
||||
if err != nil {
|
||||
log.Println("[!] json marshal error:", err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue