diff --git a/README.md b/README.md
index 557fd6c5..3d5ddc9b 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/cmd/main.go b/cmd/main.go
index 7209e05a..a8ac70ab 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -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)
}
}
diff --git a/cws/cws.go b/cws/cws.go
index 2a5abebb..47e3dc78 100644
--- a/cws/cws.go
+++ b/cws/cws.go
@@ -159,6 +159,7 @@ func (c *Client) Listen() {
err = json.Unmarshal(rawMsg, &wspacket)
if err != nil {
+ log.Println("Warn: error decoding", rawMsg)
continue
}
diff --git a/overlord/handlers.go b/overlord/handlers.go
index 34a404c2..7869495a 100644
--- a/overlord/handlers.go
+++ b/overlord/handlers.go
@@ -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
}
diff --git a/run_local_docker.sh b/run_local_docker.sh
index d4874e0f..999da164 100755
--- a/run_local_docker.sh
+++ b/run_local_docker.sh
@@ -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"
diff --git a/static/game.html b/static/game.html
index 9523ee19..c3232865 100644
--- a/static/game.html
+++ b/static/game.html
@@ -94,7 +94,7 @@
-
+
diff --git a/static/js/ws.js b/static/js/ws.js
index 6a99564b..b3682fed 100644
--- a/static/js/ws.js
+++ b/static/js/ws.js
@@ -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)