Init ws once

This commit is contained in:
giongto35 2019-04-14 00:08:27 +08:00
parent b1eb29431b
commit 324231b10c
3 changed files with 130 additions and 128 deletions

54
main.go
View file

@ -1,7 +1,6 @@
package main
import (
"os"
"encoding/json"
"fmt"
"image"
@ -10,6 +9,7 @@ import (
"math/rand"
"net/http"
_ "net/http/pprof"
"os"
"strconv"
"time"
@ -21,15 +21,15 @@ import (
)
const (
width = 256
height = 240
scale = 3
title = "NES"
width = 256
height = 240
scale = 3
title = "NES"
gameboyIndex = "./static/gameboy.html"
debugIndex = "./static/index_ws.html"
debugIndex = "./static/index_ws.html"
)
var indexFN = gameboyIndex
var indexFN = debugIndex
// Time allowed to write a message to the peer.
var readWait = 30 * time.Second
@ -61,7 +61,7 @@ var rooms map[string]*Room
func main() {
fmt.Println("Usage: ./game [debug]")
if len(os.Args) > 1 {
if len(os.Args) > 1 {
// debug
indexFN = debugIndex
fmt.Println("Use debug version")
@ -80,7 +80,6 @@ func main() {
http.ListenAndServe(":8000", nil)
}
func getWeb(w http.ResponseWriter, r *http.Request) {
bs, err := ioutil.ReadFile(indexFN)
if err != nil {
@ -101,13 +100,13 @@ func initRoom(roomID, gameName string) string {
// create director
director := ui.NewDirector(roomID, imageChannel, inputChannel, closedChannel)
rooms[roomID] = &Room{
imageChannel: imageChannel,
inputChannel: inputChannel,
closedChannel: closedChannel,
rtcSessions: []*webrtc.WebRTC{},
director: director,
director: director,
}
go fanoutScreen(imageChannel, roomID)
@ -163,13 +162,13 @@ func ws(w http.ResponseWriter, r *http.Request) {
// streaming game
// start new games and webrtc stuff?
isDone := false
//isDone := false
var gameName string
var roomID string
var playerIndex int
for !isDone {
for {
c.SetReadDeadline(time.Now().Add(readWait))
mt, message, err := c.ReadMessage()
if err != nil {
@ -189,14 +188,14 @@ func ws(w http.ResponseWriter, r *http.Request) {
// SDP connection initializations follows WebRTC convention
// https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols
switch req.ID {
case "ping":
gameName = req.Data
roomID = req.RoomID
playerIndex = req.PlayerIndex
log.Println("Ping from server with game:", gameName)
res.ID = "pong"
//case "ping":
//gameName = req.Data
//roomID = req.RoomID
//playerIndex = req.PlayerIndex
//log.Println("Ping from server with game:", gameName)
//res.ID = "pong"
case "sdp":
case "initwebrtc":
log.Println("Received user SDP")
localSession, err := webRTC.StartClient(req.Data, width, height)
if err != nil {
@ -218,6 +217,11 @@ func ws(w http.ResponseWriter, r *http.Request) {
res.ID = "candidate"
case "start":
gameName = req.Data
roomID = req.RoomID
playerIndex = req.PlayerIndex
//log.Println("Ping from server with game:", gameName)
//res.ID = "pong"
log.Println("Starting game")
roomID = startSession(webRTC, gameName, roomID, playerIndex)
res.ID = "start"
@ -225,7 +229,7 @@ func ws(w http.ResponseWriter, r *http.Request) {
// maybe we wont close websocket
// isDone = true
case "save":
log.Println("Saving game state")
res.ID = "save"
@ -262,10 +266,10 @@ func ws(w http.ResponseWriter, r *http.Request) {
c.SetWriteDeadline(time.Now().Add(writeWait))
err = c.WriteMessage(mt, []byte(stRes))
if err != nil {
log.Println("write:", err)
break
}
//if err != nil {
//log.Println("write:", err)
//break
//}
}
}

View file

@ -3,23 +3,17 @@
function showMenuScreen() {
log("Clean up connection / frame");
// clean up before / after menu
try {
inputChannel.close();
} catch (err) {
log(`> [Warning] input channel: ${err}`);
}
//try {
//inputChannel.gameboyIndeoclose();
//} catch (err) {
//log(`> [Warning] peer connection: ${err}`);
//}
try {
pc.close();
} catch (err) {
log(`> [Warning] peer connection: ${err}`);
}
try {
conn.close();
} catch (err) {
log(`> [Warning] Websocket connection: ${err}`);
}
//try {
//conn.close();
//} catch (err) {
//log(`> [Warning] Websocket connection: ${err}`);
//}
$("#game-screen").hide();
if (!DEBUG) {
@ -90,7 +84,7 @@ document.body.onkeyup = function (e) {
}
} else if (screenState === "game") {
setState(e, false);
switch (KEY_MAP[e.keyCode]) {
case "save":
conn.send(JSON.stringify({"id": "save", "data": ""}));

View file

@ -1,93 +1,68 @@
var pc;
// web socket
function startGame() {
log("Starting game screen");
conn = new WebSocket(`ws://${location.host}/ws`);
// clear
endInput();
document.getElementById('div').innerHTML = "";
if (!DEBUG) {
$("#menu-screen").fadeOut(400, function() {
$("#game-screen").show();
});
// Clear old roomID
conn.onopen = () => {
log("WebSocket is opened. Send ping");
log("Send ping pong frequently")
pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS)
startWebRTC();
}
conn.onerror = error => {
log(`Websocket error: ${error}`);
}
conn.onclose = () => {
log("Websocket closed");
}
conn.onmessage = e => {
d = JSON.parse(e.data);
switch (d["id"]) {
case "sdp":
log("Got remote sdp");
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"]))));
break;
case "pong":
// TODO: Change name use one session
log("Recv pong. Start webrtc");
//startWebRTC();
break;
case "pingpong":
// TODO: Calc time
break;
case "start":
log("Got start");
roomID.value = ""
currentRoomID.innerText = d["room_id"]
break;
case "save":
log(`Got save response: ${d["data"]}`);
break;
case "load":
log(`Got load response: ${d["data"]}`);
break;
}
// end clear
}
conn = new WebSocket(`ws://${location.host}/ws`);
// Clear old roomID
conn.onopen = () => {
log("WebSocket is opened. Send ping");
conn.send(JSON.stringify({"id": "ping", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer
log("Send ping pong frequently")
pingpongTimer = setInterval(sendPing, 1000 / PINGPONGPS)
}
conn.onerror = error => {
log(`Websocket error: ${error}`);
}
conn.onclose = () => {
log("Websocket closed");
}
conn.onmessage = e => {
d = JSON.parse(e.data);
switch (d["id"]) {
case "pong":
// TODO: Change name use one session
log("Recv pong. Start webrtc");
startWebRTC();
break;
case "pingpong":
// TODO: Calc time
break;
case "sdp":
log("Got remote sdp");
pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(d["data"]))));
break;
case "start":
log("Got start");
roomID.value = ""
currentRoomID.innerText = d["room_id"]
break;
case "save":
log(`Got save response: ${d["data"]}`);
break;
case "load":
log(`Got load response: ${d["data"]}`);
break;
}
}
function sendPing() {
// TODO: format the package with time
conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"}));
}
function sendPing() {
// TODO: format the package with time
//conn.send(JSON.stringify({"id": "pingpong", "data": "pingpong"}));
}
function startWebRTC() {
// webrtc
pc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.l.google.com:19302'}]})
// input channel
inputChannel = pc.createDataChannel('foo')
inputChannel.onclose = () => {
log('inputChannel has closed');
}
inputChannel.onopen = () => {
log('inputChannel has opened');
}
inputChannel.onmessage = e => {
log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`);
}
pc.oniceconnectionstatechange = e => {
log(`iceConnectionState: ${pc.iceConnectionState}`);
if (pc.iceConnectionState === "connected") {
conn.send(JSON.stringify({"id": "start", "data": ""}));
startInput();
//conn.send(JSON.stringify({"id": "start", "data": ""}));
screenState = "game";
}
else if (pc.iceConnectionState === "disconnected") {
@ -110,19 +85,48 @@ function startGame() {
session = btoa(JSON.stringify(pc.localDescription));
localSessionDescription = session;
log("Send SDP to remote peer");
conn.send(JSON.stringify({"id": "sdp", "data": session}));
conn.send(JSON.stringify({"id": "initwebrtc", "data": session}));
} else {
console.log(JSON.stringify(event.candidate));
}
}
function startWebRTC() {
// receiver only tracks
pc.addTransceiver('video', {'direction': 'recvonly'});
// receiver only tracks
pc.addTransceiver('video', {'direction': 'recvonly'});
// create SDP
pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).then(d => {
pc.setLocalDescription(d).catch(log);
})
}
// create SDP
pc.createOffer({offerToReceiveVideo: true, offerToReceiveAudio: false}).then(d => {
pc.setLocalDescription(d).catch(log);
})
}
function startGame() {
log("Starting game screen");
conn.send(JSON.stringify({"id": "start", "data": GAME_LIST[gameIdx].nes, "room_id": roomID.value, "player_index": parseInt(playerIndex.value, 10)}));inputTimer
// clear menu screen
//endInput();
document.getElementById('div').innerHTML = "";
if (!DEBUG) {
$("#menu-screen").fadeOut(400, function() {
$("#game-screen").show();
});
}
// end clear
// input channel
inputChannel = pc.createDataChannel('foo')
inputChannel.onclose = () => {
log('inputChannel has closed');
}
inputChannel.onopen = () => {
log('inputChannel has opened');
}
inputChannel.onmessage = e => {
log(`Message from DataChannel '${inputChannel.label}' payload '${e.data}'`);
}
startInput();
}