Skip to content

Commit

Permalink
support for endMatch via QR code
Browse files Browse the repository at this point in the history
  • Loading branch information
mkleine committed May 10, 2012
1 parent cbc4d96 commit b978325
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 147 deletions.
52 changes: 6 additions & 46 deletions server/js-nodejs/src/main/js/core-foos-sockets.js
@@ -1,52 +1,12 @@
const http = require('http');
const url = require('url');
const socketIO = require('socket.io');
const static = require('node-static');
const repository = require('./core-foos-server');
const util = require('./lib/core-foos-util');
const config = util.parseConfig();
var logger = util.createLogger('core-foos-socket');

var clientFiles = new static.Server(config.dir ? config.dir : './client');
const repository = require('./lib/core-foos-repository');
repository.initialize();

logger.log("Ready to listen");

var httpServer = http.createServer(function (request, response) {

const parsedURL = url.parse(request.url, true);
logger.log("handling request: "+ JSON.stringify(parsedURL));
if(parsedURL.pathname == '/quickmatch') {

const playerName = "chillout-" + new Date().toLocaleTimeString();

repository.requestImmediateMatch(playerName, function(upsertMatch, removeMatch, waitingPlayers){
const newState = {upsert : upsertMatch, remove: removeMatch, waiting_players : waitingPlayers};
console.log('broadcasting state update: ' + JSON.stringify(newState));

webSocket.sockets.emit('update_state',newState);
});

// serve something useful
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('okay');

} else {
request.addListener('end', function () {
clientFiles.serve(request, response);
});
}
});
httpServer.listen(config.port ? config.port : 2000);
const util = require('./lib/core-foos-util');
const config = util.parseConfig();
const logger = util.createLogger('### SOCKETS');

var webSocket = socketIO.listen(httpServer);
if(config.deployment == "heroku") {
webSocket.configure(function () {
// taken from https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku
webSocket.set("transports", ["xhr-polling"]);
webSocket.set("polling duration", 10);
});
}
// create a socket.io http server
const webSocket = require('./lib/core-foos-http').createSocketServer();

webSocket.on('connection', function (client) {

Expand Down
183 changes: 97 additions & 86 deletions server/js-nodejs/src/main/js/lib/core-foos-http.js
@@ -1,99 +1,110 @@
var connect = require('connect');
var urlparser = require('url');

var minPwdLenght = 1;

// TODO replace this with some users db
const users = Object.create(null);
users['max'] = {name: 'max', pwd :'max'};

var loginOrRegister = function (req, res, next) {
url = req.urlp = urlparser.parse(req.url, true);
console.log('req.body: '+ JSON.stringify(req.body));

if(url.body) {
try {
if( url.body.action == "login") {
// TODO access user db here
var user = users[url.body.name];
if(user && user.pwd === url.body.pwd) {
console.log(user.name + "logged in");
req.session.auth = true;
}
} else if(url.body.action == "register") {
const pwds = url.body.pwd;
if((pwds[0] + "").length >= minPwdLenght && pwds[0] === pwds[1]) {
const userName = url.body.name;
// TODO really register user
users[userName] = {name : userName, pwd : pwds[0]};
console.log("user " + userName + " registered");
req.session.auth = true;
}
}
const http = require('http');
const url = require('url');
const socketIO = require('socket.io');
const nodeStatic = require('node-static');
const repository = require('./core-foos-repository');
const util = require('./core-foos-util');
const config = util.parseConfig();
var logger = util.createLogger('### HTTP');

if(req.sesstion.auth) {
console.log('redirecting to root page');
res.writeHead(302, {'Location': '/'});
res.end();
return;
}
} catch(e){
console.error(e);
}
}
next();
};
const clientFiles = new nodeStatic.Server(config.dir ? config.dir : './client');

const COOKIE_USER_NAME = 'core_foos_user_name';

var authCheck = function (req, res, next) {
url = req.urlp = urlparser.parse(req.url, true);
function getCookies(request) {
const cookies = Object.create(null);
request.headers.cookie && request.headers.cookie.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
cookies[ parts[ 0 ].trim() ] = ( parts[ 1 ] || '' ).trim();
});
return cookies;
}

// ####
// Logout
if ( url.pathname == "/logout" ) {
req.session.destroy();
function setCookie(response, name, value, secondsToLive) {
const object = {
'Set-Cookie': name + "="+value,
'Content-Type': 'text/plain'
};
if(millisToLive){
object['Max-Age'] = secondsToLive;
}
response.writeHead(200, object);
}

// ###
// Do nothing if user wants to register or to login
if(['/login.html', '/register.html'].indexOf(url.pathname) > -1
||
(req.body && ['login','register'].indexOf(req.body.action) > -1)
) {
console.log("login or register request detected");
next();
return;
} else {
console.log("########## " + url.pathname + (req.body ? " / " + JSON.stringify(req.body) : ""));
function determineUserName(request,response) {
const cookies = getCookies(request);
var userName = cookies[COOKIE_USER_NAME];
if(!userName){
userName = "quick-match";
}
return userName;
}

function serveQuickHandles(webSocket, request, response){

// ####
// Is User already validated?
if (req.session && req.session.auth == true) {
next(); // stop here and pass to the next onion ring of connect
return;
function broadcastStateUpdate(upsertMatch, removeMatch, waitingPlayers) {
const newState = {upsert:upsertMatch, remove:removeMatch, waiting_players:waitingPlayers};
logger.log('broadcasting state update: ' + JSON.stringify(newState));

webSocket.sockets.emit('update_state', newState);
}

console.log('redirecting to login page');
res.writeHead(302, {'Location': '/login.html'});
res.end();
return;
const parsedURL = url.parse(request.url, true);
const playerName = determineUserName(request, response);

if(parsedURL.pathname == '/quickmatch') {
logger.log("handling quickmatch request: "+ JSON.stringify(parsedURL) + " (user: "+playerName+")");
repository.requestImmediateMatch(playerName, broadcastStateUpdate);
return true;

} else if(parsedURL.pathname == '/endactivematch'){
logger.log("handling quickmatch request: "+ JSON.stringify(parsedURL) + " (user: "+playerName+")");
repository.getActiveMatch(function(activeMatch){
if(activeMatch) {
repository.endMatch({matchId : activeMatch._id}, function(finishedMatch){

// ####
// This user is not authorized.
res.writeHead(403);
res.end('You are not authorized.');
return;
if (finishedMatch) {
repository.startMatch(function(startedMatch){
logger.log("starting match: "+ JSON.stringify(startedMatch));
broadcastStateUpdate(startedMatch, finishedMatch);
});
}

});
}
});
return true;
}
return false;
}

var server = connect.createServer(
connect.logger({ format: ':method :url' }),
connect.cookieParser("secret"),
connect.session({ secret: 'foobar' }),
connect.bodyParser(),
loginOrRegister,
authCheck,
connect.static('../client')
);

server.listen(3000);
module.exports = {
createSocketServer : function(){

const httpServer = http.createServer(function (request, response) {
if(serveQuickHandles(webSocket, request, response)) {
// serve something useful
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('okay');
} else {
request.addListener('end', function () {
clientFiles.serve(request, response);
});
}
});

httpServer.listen(config.port ? config.port : 2000);

const webSocket = socketIO.listen(httpServer);

if(config.deployment == "heroku") {
webSocket.configure(function () {
// taken from https://devcenter.heroku.com/articles/using-socket-io-with-node-js-on-heroku
webSocket.set("transports", ["xhr-polling"]);
webSocket.set("polling duration", 10);
});
}

return webSocket;
}
};
2 changes: 1 addition & 1 deletion server/js-nodejs/src/main/js/lib/core-foos-mongo.js
@@ -1,7 +1,7 @@
//noinspection JSUnresolvedFunction
const util = require('./core-foos-util.js');
const mongodb = require('mongodb');
var logger = util.createLogger('core-foos-mongo');
var logger = util.createLogger('### MONGO');

function wrapId(data) {
if(data._id){
Expand Down
@@ -1,6 +1,6 @@
var mongo = require('./lib/core-foos-mongo');
const util = require('./lib/core-foos-util');
const logger = util.createLogger('core-foos-server');
var mongo = require('./core-foos-mongo');
const util = require('./core-foos-util');
const logger = util.createLogger('### REPO:');

var users;
var matches;
Expand All @@ -9,17 +9,21 @@ const MATCH_STATE_FINISHED = "FINISHED";
const MATCH_STATE_WAITING = "WAITING";
const MATCH_STATE_ACTIVE = "ACTIVE";

var initialized = false;
var initialize = function () {
config = util.parseConfig();
mongo.openConnection(function (mongoResult) {
users = mongoResult.users;
matches = mongoResult.matches;

if(config.generateTestData){
logger.log("generating test data ...");
generateTestData();
}
});
if(!initialized) {
config = util.parseConfig();
mongo.openConnection(function (mongoResult) {
users = mongoResult.users;
matches = mongoResult.matches;

if(config.generateTestData){
logger.log("generating test data ...");
generateTestData();
}
});
}
initialized = true;
};

var generateTestData = function () {
Expand Down Expand Up @@ -223,16 +227,25 @@ exports.requestImmediateMatch = function(playerName, callback) {
// first reset current active match, if any
exports.getActiveMatch(function(activeMatch){
if(activeMatch) {
if(activeMatch.player1 == playerName
|| activeMatch.player2 == playerName
|| activeMatch.player3 == playerName
|| activeMatch.player4 == playerName){
logger.info('ignoring immediate match request for '+ playerName);
return; // no need to invoke callback
}

const newValue = {state:MATCH_STATE_WAITING, startDate:null};
mongo.update(matches, {_id:activeMatch._id}, newValue, function (err, result) {

activeMatch.state = newValue.state;
activeMatch.startDate = null;
// first callback sends upsert of active match
callback(activeMatch);
});
}

// finally request the immediate match
// finally request the immediate match, possibly leading to a second invocation of callback
exports.requestMatch([playerName,playerName,playerName,playerName],callback);
});
};

0 comments on commit b978325

Please sign in to comment.