Added WebSocket for responses
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
7ec798d0ed
commit
0bc96d5121
@ -530,8 +530,6 @@ class Table extends React.Component {
|
||||
};
|
||||
this.componentDidMount = this.componentDidMount.bind(this);
|
||||
this.throwDice = this.throwDice.bind(this);
|
||||
this.resetGameLoad = this.resetGameLoad.bind(this);
|
||||
this.loadGame = this.loadGame.bind(this);
|
||||
this.rollDice = this.rollDice.bind(this);
|
||||
this.setGameState = this.setGameState.bind(this);
|
||||
this.shuffleTable = this.shuffleTable.bind(this);
|
||||
@ -612,7 +610,6 @@ class Table extends React.Component {
|
||||
this.setState({error: error.message});
|
||||
}).then(() => {
|
||||
this.setState({ loading: this.state.loading - 1 });
|
||||
this.resetGameLoad();
|
||||
});
|
||||
}
|
||||
|
||||
@ -679,53 +676,6 @@ class Table extends React.Component {
|
||||
return this.sendAction('roll');
|
||||
}
|
||||
|
||||
loadGame() {
|
||||
if (this.loadTimer) {
|
||||
window.clearTimeout(this.loadTimer);
|
||||
this.loadTimer = null;
|
||||
}
|
||||
|
||||
if (!this.state.game) {
|
||||
console.error('Attempting to loadGame with no game set');
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ loading: this.state.loading + 1 });
|
||||
return window.fetch(`${base}/api/v1/games/${this.state.game.id}`, {
|
||||
method: "GET",
|
||||
cache: 'no-cache',
|
||||
credentials: 'same-origin',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.status >= 400) {
|
||||
console.log(res);
|
||||
throw new Error(`Server temporarily unreachable.`);
|
||||
}
|
||||
return res.json();
|
||||
}).then((game) => {
|
||||
const error = (game.status !== 'success') ? game.status : undefined;
|
||||
this.updateGame(game);
|
||||
this.updateMessage();
|
||||
this.setState({ error: error });
|
||||
}).catch((error) => {
|
||||
console.error(error);
|
||||
this.setState({error: error.message});
|
||||
}).then(() => {
|
||||
this.setState({ loading: this.state.loading - 1 });
|
||||
this.resetGameLoad();
|
||||
});
|
||||
}
|
||||
|
||||
resetGameLoad() {
|
||||
if (this.loadTimer) {
|
||||
window.clearTimeout(this.loadTimer);
|
||||
this.loadTimer = 0;
|
||||
}
|
||||
this.loadTimer = window.setTimeout(this.loadGame, 1000);
|
||||
}
|
||||
|
||||
setGameState(state) {
|
||||
if (this.loadTimer) {
|
||||
window.clearTimeout(this.loadTimer);
|
||||
@ -755,7 +705,6 @@ class Table extends React.Component {
|
||||
this.setState({error: error.message});
|
||||
}).then(() => {
|
||||
this.setState({ loading: this.state.loading + 1 });
|
||||
this.resetGameLoad();
|
||||
return this.game.state;
|
||||
});
|
||||
}
|
||||
@ -808,7 +757,7 @@ class Table extends React.Component {
|
||||
this.setState( { signature: game.signature });
|
||||
}
|
||||
// console.log("Update Game", game);
|
||||
this.setState( { game: game });
|
||||
this.setState( { game });
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
@ -904,21 +853,44 @@ class Table extends React.Component {
|
||||
} else {
|
||||
new_uri = "ws";
|
||||
}
|
||||
new_uri = `${new_uri}://${loc.host}${base}/ws`;
|
||||
new_uri = `${new_uri}://${loc.host}${base}/api/v1/games/ws/${this.id}`;
|
||||
this.ws = new WebSocket(new_uri);
|
||||
|
||||
this.ws.onopen = (event) => {
|
||||
console.log(event);
|
||||
//ws.send(JSON.stringify(apiCall));
|
||||
console.log(`WebSocket open:`, event);
|
||||
};
|
||||
|
||||
this.ws.onmessage = (event) => {
|
||||
const json = JSON.parse(event.data);
|
||||
console.log(json);
|
||||
};
|
||||
let data;
|
||||
try {
|
||||
data = JSON.parse(event.data);
|
||||
} catch (error) {
|
||||
this.setState({ error });
|
||||
return;
|
||||
}
|
||||
let update;
|
||||
switch (data.type) {
|
||||
case 'game-update':
|
||||
update = data.update;
|
||||
const error = (update.status !== 'success') ? update.status : undefined;
|
||||
this.updateGame(update);
|
||||
this.updateMessage();
|
||||
this.setState({ error });
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown event type: ${data.type}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.ws.onerror = (event) => {
|
||||
console.error(event);
|
||||
this.setState({ error: event.message });
|
||||
console.error(`WebSocket error:`, event);
|
||||
};
|
||||
|
||||
this.ws.onclose = (event) => {
|
||||
this.setState({ error: event.message });
|
||||
console.error(`WebSocket close:`, event);
|
||||
};
|
||||
|
||||
const params = {};
|
||||
@ -982,7 +954,6 @@ class Table extends React.Component {
|
||||
this.setState({error: error.message});
|
||||
}).then(() => {
|
||||
this.setState({ loading: this.state.loading - 1 });
|
||||
this.resetGameLoad();
|
||||
});
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 29 KiB |
@ -4,7 +4,7 @@ module.exports = function(app) {
|
||||
const base = process.env.PUBLIC_URL;
|
||||
console.log('http-proxy-middleware');
|
||||
app.use(createProxyMiddleware(
|
||||
`${base}/ws`, {
|
||||
`${base}/api/v1/games/ws`, {
|
||||
ws: true,
|
||||
target: 'http://localhost:8930',
|
||||
changeOrigin: true,
|
||||
|
@ -10,7 +10,10 @@ const express = require("express"),
|
||||
session = require('express-session'),
|
||||
hb = require("handlebars"),
|
||||
SQLiteStore = require('connect-sqlite3')(session),
|
||||
basePath = require("./basepath");
|
||||
basePath = require("./basepath"),
|
||||
app = express(),
|
||||
server = require("http").createServer(app),
|
||||
ws = require('express-ws')(app, server);
|
||||
|
||||
require("./console-line.js"); /* Monkey-patch console.log with line numbers */
|
||||
|
||||
@ -21,8 +24,6 @@ console.log("Hosting server from: " + basePath);
|
||||
|
||||
let userDB, gameDB;
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(bodyParser.json());
|
||||
|
||||
|
||||
@ -81,6 +82,7 @@ app.use(basePath, index);
|
||||
/* /games loads the default index */
|
||||
app.use(basePath + "games", index);
|
||||
|
||||
|
||||
/* Allow access to the 'users' API w/out being logged in */
|
||||
/*
|
||||
const users = require("./routes/users");
|
||||
@ -113,7 +115,8 @@ app.use(basePath, function(req, res, next) {
|
||||
/* Everything below here requires a successful authentication */
|
||||
app.use(basePath, express.static(frontendPath, { index: false }));
|
||||
|
||||
app.use(basePath + "api/v1/games", require("./routes/games"));
|
||||
app.set('ws', ws);
|
||||
app.use(`${basePath}api/v1/games`, require("./routes/games"));
|
||||
|
||||
/* Declare the "catch all" index route last; the final route is a 404 dynamic router */
|
||||
app.use(basePath, index);
|
||||
@ -123,8 +126,6 @@ app.use(basePath, index);
|
||||
*/
|
||||
app.set("port", serverConfig.port);
|
||||
|
||||
const server = require("http").createServer(app);
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
server.close(() => {
|
||||
console.log("Gracefully shutting down from SIGINT (Ctrl-C)");
|
||||
@ -132,8 +133,6 @@ process.on('SIGINT', () => {
|
||||
});
|
||||
});
|
||||
|
||||
const WebSocket = require('ws');
|
||||
|
||||
require("./db/games").then(function(db) {
|
||||
gameDB = db;
|
||||
}).then(function() {
|
||||
@ -142,33 +141,6 @@ require("./db/games").then(function(db) {
|
||||
});
|
||||
}).then(function() {
|
||||
console.log("DB connected. Opening server.");
|
||||
|
||||
/* Create web socket server on top of a regular http server */
|
||||
const ws = new WebSocket.Server({
|
||||
server
|
||||
});
|
||||
|
||||
/* Mount the Express app here */
|
||||
|
||||
//server.on('request', app);
|
||||
|
||||
app.set('ws', ws);
|
||||
|
||||
ws.on('connection', (req) => {/*
|
||||
sessionParser(req.upgradeReq, {}, () => {
|
||||
console.log("New websocket connection:");
|
||||
var sess = req.upgradeReq.session;
|
||||
console.log("working = " + sess.working);
|
||||
});*/
|
||||
});
|
||||
|
||||
ws.on('message', (message) => {
|
||||
console.log(`received: ${message}`);
|
||||
ws.send(JSON.stringify({
|
||||
answer: 42
|
||||
}));
|
||||
});
|
||||
|
||||
server.listen(serverConfig.port, () => {
|
||||
console.log(`http/ws server listening on ${serverConfig.port}`);
|
||||
});
|
||||
|
@ -17,6 +17,7 @@
|
||||
"core-js": "^3.2.1",
|
||||
"express": "^4.17.1",
|
||||
"express-session": "^1.17.1",
|
||||
"express-ws": "^5.0.2",
|
||||
"handlebars": "^4.7.6",
|
||||
"moment": "^2.24.0",
|
||||
"morgan": "^1.9.1",
|
||||
|
21
server/pass
Executable file
21
server/pass
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
ADMIN=$(jq -r .admin config/local.json)
|
||||
if [[ "${ADMIN}" == "" ]]; then
|
||||
echo "You need to set your { 'admin': 'secret' } in config/local.json"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
id=$1
|
||||
|
||||
if [[ "${id}" == "" ]]; then
|
||||
echo "Usage: pass GAME-ID"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl --noproxy '*' -s -L \
|
||||
--request PUT \
|
||||
--header "PRIVATE-TOKEN: ${ADMIN}" \
|
||||
--header "Content-Type: application/json" \
|
||||
http://localhost:8930/ketr.ketran/api/v1/games/${id}/pass |
|
||||
jq -r .status
|
||||
|
8
server/reset
Executable file
8
server/reset
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
cp games/held_riding_farm_hat.67 games/held_riding_farm_hat
|
||||
set -m
|
||||
npm start &
|
||||
sleep 3
|
||||
./pass held_riding_farm_hat
|
||||
./roll held_riding_farm_hat 3-3
|
||||
fg %1
|
@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const express = require("express"),
|
||||
router = express.Router(),
|
||||
crypto = require("crypto"),
|
||||
{ readFile, writeFile } = require("fs").promises,
|
||||
fs = require("fs"),
|
||||
@ -19,8 +20,6 @@ require("../db/games").then(function(db) {
|
||||
gameDB = db;
|
||||
});
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
function shuffle(array) {
|
||||
var currentIndex = array.length, temporaryValue, randomIndex;
|
||||
|
||||
@ -2490,6 +2489,22 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
return sendGame(req, res, game, error);
|
||||
})
|
||||
|
||||
router.ws("/ws/:id", (ws, req) => {
|
||||
const { id } = req.params;
|
||||
ws.on('message', (msg) => {
|
||||
console.log(msg);
|
||||
});
|
||||
if (id in games) {
|
||||
const game = games[id];
|
||||
|
||||
const session = getSession(game, req.session);
|
||||
if (session) {
|
||||
console.log(`WebSocket connected for ${session.name}`);
|
||||
session.ws = ws;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/:id", async (req, res/*, next*/) => {
|
||||
const { id } = req.params;
|
||||
// console.log("GET games/" + id);
|
||||
@ -2640,6 +2655,9 @@ const sendGame = async (req, res, game, error) => {
|
||||
if (reduced.player) {
|
||||
delete reduced.player;
|
||||
}
|
||||
if (reduced.ws) {
|
||||
delete reduced.ws;
|
||||
}
|
||||
reducedGame.sessions[id] = reduced;
|
||||
|
||||
/* Do not send session-id as those are secrets */
|
||||
@ -2658,7 +2676,11 @@ const sendGame = async (req, res, game, error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const player = session.player ? session.player : undefined;
|
||||
for (let id in game.sessions) {
|
||||
const target = game.sessions[id],
|
||||
useWS = target !== session,
|
||||
player = target.player ? target.player : undefined;
|
||||
|
||||
if (player) {
|
||||
player.haveResources = player.wheat > 0 ||
|
||||
player.brick > 0 ||
|
||||
@ -2673,14 +2695,29 @@ const sendGame = async (req, res, game, error) => {
|
||||
const playerGame = Object.assign({}, reducedGame, {
|
||||
timestamp: Date.now(),
|
||||
status: error ? error : "success",
|
||||
name: session.name,
|
||||
color: session.color,
|
||||
order: (session.color in game.players) ? game.players[session.color].order : 0,
|
||||
name: target.name,
|
||||
color: target.color,
|
||||
order: (target.color in game.players) ? game.players[target.color].order : 0,
|
||||
player: player,
|
||||
sessions: reducedSessions,
|
||||
layout: layout
|
||||
});
|
||||
return res.status(200).send(playerGame);
|
||||
|
||||
if (useWS) {
|
||||
if (!target.ws) {
|
||||
console.error(`No WebSocket connection to ${target.name}`);
|
||||
} else {
|
||||
console.log(`Sending update to ${target.name}`);
|
||||
target.ws.send(JSON.stringify({
|
||||
type: 'game-update',
|
||||
update: playerGame
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
console.log(`Returning update to ${target.name}`);
|
||||
res.status(200).send(playerGame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const resetGame = (game) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user