mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-01-23 02:34:42 +00:00
Match best worker based on latency + Experiment with Singapore Host (#60)
* Add echo endpoint * Fix async * Use latency map * Only start webRTC after worker match * Experiment with Singapore server * Update comments
This commit is contained in:
parent
e33126c67c
commit
fafae16756
7 changed files with 74 additions and 22 deletions
2
README.md
vendored
2
README.md
vendored
|
|
@ -1,6 +1,6 @@
|
|||
# Klog, Web-based Cloud Gaming Service
|
||||
- **US West (San Francisco)**: [http://usw.cloud.webgame2d.com](http://usw.cloud.webgame2d.com) - **US East(New York)**: [http://use.cloud.webgame2d.com](http://use.cloud.webgame2d.com)
|
||||
- **Singapore**: [http://sg.cloud.webgame2d.com](http://sg.cloud.webgame2d.com) - **Europe (London)**: [http://eu.cloud.webgame2d.com](http://eu.cloud.webgame2d.com)
|
||||
- **Singapore**: [http://cloud.webgame2d.com](http://sg.cloud.webgame2d.com) - **Europe (London)**: [http://eu.cloud.webgame2d.com](http://eu.cloud.webgame2d.com)
|
||||
|
||||
- [**Game Instruction**](document/instruction/)
|
||||
For the best gaming experience, please select the closest region to you.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
|
|
@ -77,6 +78,12 @@ func initializeWorker() {
|
|||
http.Handle("/metrics", promhttp.Handler())
|
||||
}
|
||||
|
||||
// echo endpoint is where user will request to test latency
|
||||
http.HandleFunc("/echo", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
fmt.Fprintf(w, "echo")
|
||||
})
|
||||
|
||||
http.ListenAndServe(":"+strconv.Itoa(port), nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ func (c *Client) Listen() {
|
|||
err = json.Unmarshal(rawMsg, &wspacket)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Warn: error decoding", rawMsg)
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package overlord
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
|
@ -8,7 +9,6 @@ import (
|
|||
"math"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/giongto35/cloud-game/config"
|
||||
|
|
@ -232,13 +232,18 @@ func (o *Server) getLatencyMapFromBrowser(client *BrowserClient) map[*WorkerClie
|
|||
ID: "checkLatency",
|
||||
Data: strings.Join(addressList, ","),
|
||||
})
|
||||
log.Println("Received latency list:", data.Data)
|
||||
latencies := strings.Split(data.Data, ",")
|
||||
log.Println("Received latency list:", latencies)
|
||||
|
||||
for i, workerClient := range workersList {
|
||||
il, _ := strconv.Atoi(latencies[i])
|
||||
latencyMap[workerClient] = int64(il)
|
||||
respLatency := map[string]int64{}
|
||||
err := json.Unmarshal([]byte(data.Data), &respLatency)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return latencyMap
|
||||
}
|
||||
|
||||
for _, workerClient := range workersList {
|
||||
if latency, ok := respLatency[workerClient.Address]; ok {
|
||||
latencyMap[workerClient] = latency
|
||||
}
|
||||
}
|
||||
return latencyMap
|
||||
}
|
||||
|
|
|
|||
2
run_local_docker.sh
vendored
2
run_local_docker.sh
vendored
|
|
@ -3,4 +3,4 @@ docker build . -t cloud-game-local
|
|||
docker stop cloud-game-local
|
||||
docker rm cloud-game-local
|
||||
# Overlord and worker should be run separately. Local is for demo purpose
|
||||
docker run --privileged -d --name cloud-game-local -p 8000:8000 cloud-game-local bash -c "cmd -overlordhost ws://localhost:8000/wso & cmd -overlordhost overlord"
|
||||
docker run --privileged -d --name cloud-game-local -p 8000:8000 -p 9000:9000 cloud-game-local bash -c "cmd -overlordhost ws://localhost:8000/wso & cmd -overlordhost overlord"
|
||||
|
|
|
|||
2
static/game.html
vendored
2
static/game.html
vendored
|
|
@ -94,7 +94,7 @@
|
|||
<script src="/static/js/gesture_keyboard.js?1"></script>
|
||||
<script src="/static/js/gesture_touch.js?1"></script>
|
||||
<script src="/static/js/gesture_joystick.js?1"></script>
|
||||
<script src="/static/js/ws.js?2"></script>
|
||||
<script src="/static/js/ws.js?4"></script>
|
||||
|
||||
<script src="/static/js/init.js?1"></script>
|
||||
|
||||
|
|
|
|||
63
static/js/ws.js
vendored
63
static/js/ws.js
vendored
|
|
@ -10,7 +10,6 @@ conn.onopen = () => {
|
|||
log("Send ping pong frequently")
|
||||
pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS)
|
||||
|
||||
startWebRTC();
|
||||
}
|
||||
|
||||
conn.onerror = error => {
|
||||
|
|
@ -90,24 +89,63 @@ conn.onmessage = e => {
|
|||
var s = d["data"];
|
||||
var latencyList = [];
|
||||
curPacketID = d["packet_id"];
|
||||
latencyPacketID = curPacketID;
|
||||
addrs = s.split(",")
|
||||
|
||||
var latenciesMap = {};
|
||||
var cntResp = 0;
|
||||
beforeTime = Date.now();
|
||||
for (const addr of addrs) {
|
||||
beforeTime = Date.now();
|
||||
var sumLatency = 0
|
||||
|
||||
// TODO: Clean code, use async
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open( "GET", addr+"/echo", false ); // false for synchronous request
|
||||
xmlHttp.send( null );
|
||||
xmlHttp.open( "GET", "http://"+addr+":9000/echo?_=" + beforeTime, true ); // false for synchronous request, add date to not calling cache
|
||||
xmlHttp.timeout = 1000
|
||||
xmlHttp.ontimeout = () => {
|
||||
cntResp++;
|
||||
afterTime = Date.now();
|
||||
//sumLatency += afterTime - beforeTime
|
||||
latenciesMap[addr] = afterTime - beforeTime
|
||||
if (cntResp == addrs.length) {
|
||||
log(`Send latency list ${latenciesMap}`)
|
||||
log(curPacketID)
|
||||
|
||||
resp = xmlHttp.responseText
|
||||
afterTime = Date.now();
|
||||
latencyList.push(afterTime - beforeTime)
|
||||
conn.send(JSON.stringify({"id": "checkLatency", "data": JSON.stringify(latenciesMap), "packet_id": latencyPacketID}));
|
||||
startWebRTC();
|
||||
}
|
||||
}
|
||||
xmlHttp.onload = () => {
|
||||
cntResp++;
|
||||
afterTime = Date.now();
|
||||
//sumLatency += afterTime - beforeTime
|
||||
latenciesMap[addr] = afterTime - beforeTime
|
||||
if (cntResp == addrs.length) {
|
||||
log(`Send latency list ${latenciesMap}`)
|
||||
log(curPacketID)
|
||||
|
||||
//conn.send(JSON.stringify({"id": "checkLatency", "data": latenciesMap, "packet_id": latencyPacketID}));
|
||||
conn.send(JSON.stringify({"id": "checkLatency", "data": JSON.stringify(latenciesMap), "packet_id": latencyPacketID}));
|
||||
startWebRTC();
|
||||
}
|
||||
}
|
||||
xmlHttp.send( null );
|
||||
}
|
||||
log(`Send latency list ${latencyList.join()}`)
|
||||
log(curPacketID)
|
||||
conn.send(JSON.stringify({"id": "checkLatency", "data": latencyList.join(), "packet_id": curPacketID}));
|
||||
}
|
||||
}
|
||||
|
||||
function updateLatencies(beforeTime, addr, latenciesMap, cntResp, curPacketID) {
|
||||
afterTime = Date.now();
|
||||
//sumLatency += afterTime - beforeTime
|
||||
latenciesMap[addr] = afterTime - beforeTime
|
||||
if (cntResp == addrs.length) {
|
||||
log(`Send latency list ${latenciesMap}`)
|
||||
log(curPacketID)
|
||||
|
||||
conn.send(JSON.stringify({"id": "checkLatency", "data": latenciesMap, "packet_id": curPacketID}));
|
||||
}
|
||||
}
|
||||
|
||||
function sendPing() {
|
||||
// TODO: format the package with time
|
||||
conn.send(JSON.stringify({"id": "heartbeat", "data": Date.now().toString()}));
|
||||
|
|
@ -256,7 +294,8 @@ function startWebRTC() {
|
|||
session = btoa(JSON.stringify(pc.localDescription));
|
||||
log("Send SDP to remote peer");
|
||||
// TODO: Fix curPacketID
|
||||
conn.send(JSON.stringify({"id": "initwebrtc", "data": session, "packet_id": curPacketID}));
|
||||
//conn.send(JSON.stringify({"id": "initwebrtc", "data": session, "packet_id": curPacketID}));
|
||||
conn.send(JSON.stringify({"id": "initwebrtc", "data": session}));
|
||||
iceSent = true
|
||||
}
|
||||
} else {
|
||||
|
|
@ -267,7 +306,7 @@ function startWebRTC() {
|
|||
if (!iceSent) {
|
||||
log("Ice gathering timeout, send anyway")
|
||||
session = btoa(JSON.stringify(pc.localDescription));
|
||||
conn.send(JSON.stringify({"id": "initwebrtc", "data": session, "packet_id": curPacketID}));
|
||||
conn.send(JSON.stringify({"id": "initwebrtc", "data": session}));
|
||||
iceSent = true;
|
||||
}
|
||||
}, ICE_TIMEOUT)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue