From: Luigi Pinca Date: Thu, 28 Nov 2013 20:13:27 +0000 (+0100) Subject: abandoned socket.io in favour of Primus X-Git-Url: https://git.saalbach.dev/?a=commitdiff_plain;h=75466776cfc053325f38763a352938385a334558;p=binbsis50.git abandoned socket.io in favour of Primus --- diff --git a/.gitignore b/.gitignore index 846f0de..a196d93 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules/ public/js/app.min.js public/js/home.min.js public/js/leaderboards.min.js +public/js/primus.min.js diff --git a/app.js b/app.js index b722d59..074f9ef 100644 --- a/app.js +++ b/app.js @@ -2,11 +2,9 @@ * Module dependencies. */ -var config = require('./config') - , express = require('express') +var express = require('express') , http = require('http') - , parseCookie = require('express/node_modules/cookie').parse - , parseSignedCookies = require('express/node_modules/connect').utils.parseSignedCookies + , port = require('./config').port , redisstore = require('connect-redis')(express) , secret = process.env.SITE_SECRET || 'shhhh, very secret' , site = require('./routes/site') @@ -19,7 +17,8 @@ var config = require('./config') var app = express() , pub = __dirname + '/public' // Path to public directory - , sessionstore = new redisstore({client: usersdb}); + , sessionstore = new redisstore({client: usersdb}) + , server = http.createServer(app); // HTTP server object // Configuration app.set('view engine', 'jade'); @@ -52,137 +51,17 @@ app.post('/signup', user.validateSignUp, user.userExists, user.emailExists, user app.get('/:room', site.room); app.get('/user/:username', user.profile); -// HTTP server object -var server = http.createServer(app); - -/** - * Setting up Socket.IO. - */ - -var io = require('socket.io').listen(server) - , sockets = Object.create(null); // Sockets of all rooms - -// Configuration -io.enable('browser client minification'); -io.enable('browser client etag'); -io.enable('browser client gzip'); -io.set('log level', 1); -io.set('transports', [ - 'websocket' - , 'htmlfile' - , 'xhr-polling' - , 'jsonp-polling' -]); - -// Authorization -io.set('authorization', function(data, accept) { - if(!data.headers.cookie) { - return accept('no cookie transmitted', false); - } - var signedcookie = parseCookie(data.headers.cookie); - var cookie = parseSignedCookies(signedcookie, secret); - sessionstore.get(cookie['connect.sid'], function(err, session) { - if (err) { - return accept(err.message, false); - } - else if (!session) { - var debuginfos = { - address: data.headers['x-forwarded-for'], - ua: data.headers['user-agent'], - cookie: data.headers.cookie - }; - console.log(debuginfos); - return accept('session not found', false); - } - data.session = session; - accept(null, true); - }); -}); - -io.sockets.on('connection', function(socket) { - var session = socket.handshake.session; - socket.on('disconnect', function() { - if (socket.roomname) { - rooms[socket.roomname].removeUser(socket.nickname); - } - }); - socket.on('getoverview', function(callback) { - if (typeof callback !== 'function') { - return; - } - var data = Object.create(null); - for (var prop in rooms) { - data[prop] = rooms[prop].getPopulation(); - } - callback(data); - }); - socket.on('getstatus', function(callback) { - if (socket.roomname && typeof callback === 'function') { - rooms[socket.roomname].sendStatus(callback); - } - }); - socket.on('guess', function(guess) { - if (socket.roomname && typeof guess === 'string') { - rooms[socket.roomname].guess(socket, guess); - } - }); - socket.on('ignore', function(who, callback) { - if (socket.roomname && typeof who === 'string' && typeof callback === 'function') { - rooms[socket.roomname].ignore(who, socket.nickname, callback); - } - }); - socket.on('joinanonymously', function(nickname, roomname) { - if (!socket.nickname && typeof nickname === 'string' && ~config.rooms.indexOf(roomname)) { - rooms[roomname].setNickName(socket, nickname); - } - }); - socket.on('joinroom', function(room) { - if (session.user && ~config.rooms.indexOf(room)) { - if (sockets[session.user]) { // User already in a room - socket.emit('alreadyinaroom'); - return; - } - socket.nickname = session.user; - rooms[room].joinRoom(socket); - } - }); - socket.on('kick', function(who, why, callback) { - if (socket.roomname && typeof who === 'string' && typeof why === 'string' && - typeof callback === 'function') { - rooms[socket.roomname].kick(who, why, socket.nickname, callback); - } - }); - socket.on('loggedin', function(callback) { - if (typeof callback !== 'function') { - return; - } - return (session.user) ? callback(session.user) : callback(false); - }); - socket.on('sendchatmsg', function(msg, to) { - if (socket.roomname && typeof msg === 'string') { - rooms[socket.roomname].sendChatMessage(msg, socket, to); - } - }); - socket.on('unignore', function(who) { - if (socket.roomname && typeof who === 'string') { - rooms[socket.roomname].unignore(who, socket.nickname); - } - }); -}); - /** * Setting up the rooms. */ -var Room = require('./lib/room')({io: io, sockets: sockets}) - , rooms = Object.create(null); // The Object that contains all the room instances - -config.rooms.forEach(function(room) { - room = rooms[room] = new Room(room); - room.start(); +require('./lib/rooms')({ + secret: secret, + server: server, + sessionstore: sessionstore }); // Begin accepting connections -server.listen(config.port, function() { - console.log('binb server listening on port ' + config.port); +server.listen(port, function() { + console.info('binb server listening on port ' + port); }); diff --git a/lib/redis-clients.js b/lib/redis-clients.js index 8f4838e..28bb76e 100644 --- a/lib/redis-clients.js +++ b/lib/redis-clients.js @@ -17,11 +17,11 @@ if (process.env.NODE_ENV === 'production') { } songsclient.on('error', function(err) { - console.log(err.message); + console.error(err); }); usersclient.on('error', function(err) { - console.log(err.message); + console.error(err); }); /** diff --git a/lib/room.js b/lib/rooms.js similarity index 69% rename from lib/room.js rename to lib/rooms.js index 2521c31..9a5cb2c 100644 --- a/lib/room.js +++ b/lib/rooms.js @@ -7,25 +7,30 @@ var amatch = require('./match') , collectStats = require('./stats') , config = require('../config') , fifolength = config.songsinarun * config.gameswithnorepeats - , io + , isUsername = require('./utils').isUsername + , primus , randInt = require('./prng').randInt - , sockets + , rooms = {} // The Object that contains all the room instances , songsdb = clients.songs - , usersdb = clients.users - , utils = require('./utils') - , isUsername = utils.isUsername - , trackscount = utils.trackscount; + , sparks + , usersdb = clients.users; /** - * Expose the constructor. + * Expose a function to set up the rooms. */ module.exports = function(options) { - io = options.io; - sockets = options.sockets; - return Room; + var refs = require('./sparks')(options); + primus = refs.primus; + sparks = refs.sparks; + config.rooms.forEach(function(room) { + room = rooms[room] = new Room(room); + room.start(); + }); }; +module.exports.rooms = rooms; + /** * Room constructor. */ @@ -45,6 +50,7 @@ function Room(roomname) { , title // Title in lowercase , trackName , trackViewUrl + , trackscount // Number of tracks in the room , totusers = 0 , usersData = Object.create(null); @@ -118,10 +124,10 @@ function Room(roomname) { }; // Add a new user in the room - var addUser = function(socket, loggedin) { - sockets[socket.nickname] = socket; - usersData[socket.nickname] = { - nickname: socket.nickname, + var addUser = function(spark, loggedin) { + sparks[spark.nickname] = spark; + usersData[spark.nickname] = { + nickname: spark.nickname, registered: loggedin, points: 0, roundpoints: 0, @@ -135,9 +141,9 @@ function Room(roomname) { }; totusers++; // Broadcast new user event - io.sockets.emit('updateoverview', roomname, totusers); - socket.emit('ready', usersData, trackscount[roomname], loggedin); - socket.broadcast.to(roomname).emit('newuser', socket.nickname, usersData); + primus.send('updateoverview', roomname, totusers); + spark.send('ready', usersData, trackscount, loggedin); + spark.room(roomname).send('newuser', spark.nickname, usersData); }; var gameOver = function() { @@ -150,7 +156,7 @@ function Room(roomname) { } users.sort(function(a, b) {return b.points - a.points;}); var podium = users.slice(0,3); - io.sockets.in(roomname).emit('gameover', podium); + primus.room(roomname).send('gameover', podium); // Collect podium stats if (podium[0] && podium[0].registered) { @@ -180,64 +186,64 @@ function Room(roomname) { }; // A user is sending a guess - this.guess = function(socket, guess) { + this.guess = function(spark, guess) { if (status === 0) { - if (!usersData[socket.nickname].matched) { // No track no artist + if (!usersData[spark.nickname].matched) { // No track no artist if ((artist === title) && amatch(title, guess, true)) { - addPointsAndStats(socket.nickname, true); - socket.emit('bothmatched'); - io.sockets.in(roomname).emit('updateusers', usersData); + addPointsAndStats(spark.nickname, true); + spark.send('bothmatched'); + primus.room(roomname).send('updateusers', usersData); } else if (amatch(artist, guess, true) || (feat && amatch(feat, guess, true))) { - usersData[socket.nickname].roundpoints++; - usersData[socket.nickname].points++; - usersData[socket.nickname].matched = 'artist'; - socket.emit('artistmatched'); - io.sockets.in(roomname).emit('updateusers', usersData); - if (usersData[socket.nickname].registered) { - var stats = {points:1,userscore:usersData[socket.nickname].points}; - collectStats(socket.nickname, stats); + usersData[spark.nickname].roundpoints++; + usersData[spark.nickname].points++; + usersData[spark.nickname].matched = 'artist'; + spark.send('artistmatched'); + primus.room(roomname).send('updateusers', usersData); + if (usersData[spark.nickname].registered) { + var stats = {points:1,userscore:usersData[spark.nickname].points}; + collectStats(spark.nickname, stats); } } else if (amatch(title, guess)) { - usersData[socket.nickname].roundpoints++; - usersData[socket.nickname].points++; - usersData[socket.nickname].matched = 'title'; - socket.emit('titlematched'); - io.sockets.in(roomname).emit('updateusers', usersData); - if (usersData[socket.nickname].registered) { - var stats = {points:1,userscore:usersData[socket.nickname].points}; - collectStats(socket.nickname, stats); + usersData[spark.nickname].roundpoints++; + usersData[spark.nickname].points++; + usersData[spark.nickname].matched = 'title'; + spark.send('titlematched'); + primus.room(roomname).send('updateusers', usersData); + if (usersData[spark.nickname].registered) { + var stats = {points:1,userscore:usersData[spark.nickname].points}; + collectStats(spark.nickname, stats); } } else { - socket.emit('nomatch'); + spark.send('nomatch'); } } - else if (usersData[socket.nickname].matched !== 'both') { // Track or artist - if (usersData[socket.nickname].matched === 'artist') { + else if (usersData[spark.nickname].matched !== 'both') { // Track or artist + if (usersData[spark.nickname].matched === 'artist') { if (amatch(title, guess)) { - addPointsAndStats(socket.nickname, false); - socket.emit('bothmatched'); - io.sockets.in(roomname).emit('updateusers', usersData); + addPointsAndStats(spark.nickname, false); + spark.send('bothmatched'); + primus.room(roomname).send('updateusers', usersData); } else { - socket.emit('nomatch'); + spark.send('nomatch'); } } else { if (amatch(artist, guess, true) || (feat && amatch(feat, guess, true))) { - addPointsAndStats(socket.nickname, false); - socket.emit('bothmatched'); - io.sockets.in(roomname).emit('updateusers', usersData); + addPointsAndStats(spark.nickname, false); + spark.send('bothmatched'); + primus.room(roomname).send('updateusers', usersData); } else { - socket.emit('nomatch'); + spark.send('nomatch'); } } } else { // The user has guessed both track and artist - socket.emit('stoptrying'); + spark.send('stoptrying'); } } }; @@ -246,17 +252,16 @@ function Room(roomname) { // Check if the player to be ignored is in the room if (usersData[who]) { // Inform the bad player that he/she is being ignored - var recipient = sockets[who]; - recipient.emit('chatmsg', executor+' is ignoring you.', 'binb', who); - return callback(who); + var recipient = sparks[who]; + recipient.send('chatmsg', executor+' is ignoring you.', 'binb', who); + return callback(true, who); } callback(false); }; - this.joinRoom = function(socket) { - socket.roomname = roomname; - socket.join(roomname); - addUser(socket, true); + this.joinRoom = function(spark) { + spark.join(roomname); + addUser(spark, true); }; // Kick a user @@ -268,25 +273,25 @@ function Room(roomname) { why = ' ('+why+')'; } var notice = 'you have been kicked by '+executor+why+'.'; - var recipient = sockets[who]; - recipient.emit('chatmsg', notice, 'binb', who); - recipient.disconnect(); + var recipient = sparks[who]; + recipient.send('chatmsg', notice, 'binb', who); + recipient.end(); } - return; + return callback(true); } - callback(); + callback(false); }); }; // A user has left (DCed, etc.) this.removeUser = function(nickname) { // Delete the references - delete sockets[nickname]; + delete sparks[nickname]; delete usersData[nickname]; totusers--; // Broadcast the event - io.sockets.emit('updateoverview', roomname, totusers); - io.sockets.in(roomname).emit('userleft', nickname, usersData); + primus.send('updateoverview', roomname, totusers); + primus.room(roomname).send('userleft', nickname, usersData); }; var resetPoints = function(roundonly) { @@ -306,13 +311,13 @@ function Room(roomname) { }; // A user is sending a chat message - this.sendChatMessage = function(msg, socket, to) { + this.sendChatMessage = function(msg, spark, to) { if (typeof to === 'string') { // Check if the recipient is in the room if (usersData[to]) { - socket.emit('chatmsg', msg, socket.nickname, to); - var recipient = sockets[to]; - recipient.emit('chatmsg', msg, socket.nickname, to); + spark.send('chatmsg', msg, spark.nickname, to); + var recipient = sparks[to]; + recipient.send('chatmsg', msg, spark.nickname, to); } return; } @@ -321,15 +326,15 @@ function Room(roomname) { if (status === 0 && (amatch(artist, msglcase, true) || (feat && amatch(feat, msglcase, true)) || amatch(title, msglcase))) { var notice = 'You are probably right, but you have to use the box above.'; - socket.emit('chatmsg', notice, 'binb', socket.nickname); + spark.send('chatmsg', notice, 'binb', spark.nickname); return; } - io.sockets.in(roomname).emit('chatmsg', msg, socket.nickname); + primus.room(roomname).send('chatmsg', msg, spark.nickname); }; // Extract a random track from the database and send the load event var sendLoadTrack = function() { - var index = randInt(trackscount[roomname]); + var index = randInt(trackscount); songsdb.zrange(roomname, index, index, function(err, res) { var id = res[0]; // Check if extracted track is in the list of already played tracks @@ -354,7 +359,7 @@ function Room(roomname) { previewUrl = replies[2]; artworkUrl = replies[3]; trackViewUrl = replies[4]; - io.sockets.in(roomname).emit('loadtrack', previewUrl); + primus.room(roomname).send('loadtrack', previewUrl); setTimeout(sendPlayTrack, 5000); }); }); @@ -369,7 +374,7 @@ function Room(roomname) { tot: config.songsinarun, users: usersData }; - io.sockets.in(roomname).emit('playtrack', data); + primus.room(roomname).send('playtrack', data); songTimeLeft(Date.now() + 30000, 50); setTimeout(sendTrackInfo, 30000); }; @@ -391,7 +396,7 @@ function Room(roomname) { trackName: trackName, trackViewUrl: trackViewUrl, }; - io.sockets.in(roomname).emit('trackinfo', trackinfo); + primus.room(roomname).send('trackinfo', trackinfo); finishline = 1; if (songcounter < config.songsinarun) { @@ -405,7 +410,7 @@ function Room(roomname) { }; // A user is submitting a name - this.setNickName = function(socket, nickname) { + this.setNickName = function(spark, nickname) { var feedback = null; if (nickname === 'binb') { @@ -415,12 +420,12 @@ function Room(roomname) { feedback = 'Name must contain only '; feedback += 'alphanumeric characters.'; } - else if (sockets[nickname]) { + else if (sparks[nickname]) { feedback = 'Name already taken.'; } if (feedback) { - return socket.emit('invalidnickname', feedback); + return spark.send('invalidnickname', feedback); } // Check if requested nickname belong to a registered user @@ -429,12 +434,11 @@ function Room(roomname) { if (resp === 1) { feedback = 'That name belongs '; feedback += 'to a registered user.'; - return socket.emit('invalidnickname', feedback); + return spark.send('invalidnickname', feedback); } - socket.nickname = nickname; - socket.roomname = roomname; - socket.join(roomname); - addUser(socket, false); + spark.nickname = nickname; + spark.join(roomname); + addUser(spark, false); }); }; @@ -450,17 +454,22 @@ function Room(roomname) { // Start the room this.start = function() { songsdb.zcard(roomname, function(err, card) { - trackscount[roomname] = card; + trackscount = card; sendLoadTrack(); }); }; + // Return the number of tracks in the room + this.tracksCount = function() { + return trackscount; + }; + this.unignore = function(who, executor) { if (usersData[who]) { // Inform the bad player that he/she is no longer ignored var notice = executor+' has stopped ignoring you.'; - var recipient = sockets[who]; - recipient.emit('chatmsg', notice, 'binb', who); + var recipient = sparks[who]; + recipient.send('chatmsg', notice, 'binb', who); } }; } diff --git a/lib/sparks.js b/lib/sparks.js new file mode 100644 index 0000000..587ad21 --- /dev/null +++ b/lib/sparks.js @@ -0,0 +1,151 @@ +/** + * Module dependencies. + */ + +var config = require('../config') + , fs = require('fs') + , minify = require('uglify-js').minify + , parseCookie = require('express/node_modules/cookie').parse + , parseSignedCookies = require('express/node_modules/connect').utils.parseSignedCookies + , Primus = require('primus') + , primus + , primusemitter = require('primus-emitter') + , primusrooms = require('primus-rooms') + , rooms = require('./rooms').rooms + , secret + , sessionstore + , sparks = Object.create(null); // Sparks of all rooms + +/** + * Expose a function to set up Primus. + */ + +module.exports = function(options) { + secret = options.secret; + sessionstore = options.sessionstore; + + // Create Primus instance + primus = new Primus(options.server, { + authorization: authorize, + plugin: { + emitter: primusemitter, + rooms: primusrooms + }, + transformer: 'websockets' + }); + + // Minify and store the client-side library in the public directory + var library = minify(primus.library(), {fromString: true}); + fs.writeFileSync(__dirname + '/../public/js/primus.min.js', library.code); + + primus.on('connection', connection); + primus.on('log', function(type, message, context) { + if (type === 'error') { + console.error(context); + } + }); + return {primus: primus, sparks: sparks}; +}; + +/** + * Authorization handler. + */ + +var authorize = function(req, authorized) { + var cookie = req.headers.cookie; + if(!cookie) { + var err = new Error('no cookie transmitted'); + console.error(err); + return authorized(err); + } + cookie = parseCookie(cookie); + cookie = parseSignedCookies(cookie, secret); + sessionstore.get(cookie['connect.sid'], function(err, session) { + if (err || !session) { + err = err || new Error('session not found'); + console.error(err); + return authorized(err); + } + req.headers.session = session; + authorized(); + }); +}; + +/** + * Handle `connection` event. + */ + +var connection = function(spark) { + var room + , user = spark.headers.session.user; + delete spark.headers.session; + spark.on('end', function() { + if (room) { + rooms[room].removeUser(spark.nickname); + } + }); + spark.on('getoverview', function(callback) { + if (typeof callback !== 'function') { + return; + } + var data = Object.create(null); + for (var room in rooms) { + data[room] = rooms[room].getPopulation(); + } + callback(data); + }); + spark.on('getstatus', function(callback) { + if (room && typeof callback === 'function') { + rooms[room].sendStatus(callback); + } + }); + spark.on('guess', function(guess) { + if (room && typeof guess === 'string') { + rooms[room].guess(spark, guess); + } + }); + spark.on('ignore', function(who, callback) { + if (room && typeof who === 'string' && typeof callback === 'function') { + rooms[room].ignore(who, spark.nickname, callback); + } + }); + spark.on('joinanonymous', function(nickname, room) { + if (!spark.nickname && typeof nickname === 'string' && ~config.rooms.indexOf(room)) { + rooms[room].setNickName(spark, nickname); + } + }); + spark.on('joinauthenticated', function(room) { + if (user && ~config.rooms.indexOf(room)) { + if (sparks[user]) { // User already in a room + return spark.send('alreadyinaroom'); + } + spark.nickname = user; + rooms[room].joinRoom(spark); + } + }); + spark.on('joinroom', function(roomname) { + room = roomname; + }); + spark.on('kick', function(who, why, callback) { + if (room && typeof who === 'string' && typeof why === 'string' && + typeof callback === 'function') { + rooms[room].kick(who, why, spark.nickname, callback); + } + }); + spark.on('loggedin', function(callback) { + if (typeof callback !== 'function') { + return; + } + return user ? callback(true, user) : callback(false); + }); + spark.on('sendchatmsg', function(msg, to) { + if (room && typeof msg === 'string') { + rooms[room].sendChatMessage(msg, spark, to); + } + }); + spark.on('unignore', function(who) { + if (room && typeof who === 'string') { + rooms[room].unignore(who, spark.nickname); + } + }); +}; diff --git a/lib/utils.js b/lib/utils.js index d806a4f..367e601 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -39,12 +39,6 @@ exports.britishFormat = function(date) { return day+'/'+month+'/'+year; }; -/** - * Helper object for faster and easier access to rooms' cardinalities (number of tracks). - */ - -exports.trackscount = {}; - /** * Check whether a given string is a valid email address. */ diff --git a/package.json b/package.json index 10f71e9..fec7577 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,12 @@ "express": "3.4.x", "jade": "0.35.x", "nodemailer": "0.5.x", + "primus": "1.4.x", + "primus-emitter": "2.0.x", + "primus-rooms": "2.1.x", "redis": "0.9.x", - "socket.io": "0.9.x" + "uglify-js": "2.4.x", + "ws": "0.4.x" }, "devDependencies": { "JSONStream": "0.7.x" @@ -26,5 +30,5 @@ "start": "node app.js" }, "subdomain": "binb", - "version": "0.3.6-13" + "version": "0.3.6-14" } diff --git a/public/js/app.js b/public/js/app.js index ccfa571..66da796 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -12,11 +12,11 @@ , subscriber = false , roundpoints = 0 , roomname = window.location.pathname.replace(/\//g, '') - , socket + , primus , stopanimation = false , touchplay , urlregex = /(https?:\/\/[\-A-Za-z0-9+&@#\/%?=~_()|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|])/ - , uri = window.location.protocol+'//'+window.location.host; // Socket.IO server URI + , uri = window.location.protocol+'//'+window.location.host; // Primus server URI var amstrings = [ 'Yes, that\'s the artist. What about the title?' @@ -444,8 +444,8 @@ outcome.text('(From binb): '+args[0]+' is already ignored.'); return addChatEntry(outcome); } - socket.emit('ignore', args[0], function(player) { - if (player) { + primus.send('ignore', args[0], function(ignored, player) { + if (ignored) { ignoredplayers[player] = true; outcome.text('(From binb): '+player+' is now ignored.'); return addChatEntry(outcome); @@ -457,14 +457,14 @@ // Submitted name was invalid var invalidNickName = function(feedback) { - joinAnonymously(feedback+'
Try with another one:'); + joinAnonymous(feedback+'
Try with another one:'); }; // Prompt for name and send it - var joinAnonymously = function(msg) { + var joinAnonymous = function(msg) { if (/nickname\s*\=/.test(document.cookie) && !msg) { nickname = document.cookie.replace(/.*nickname\s*\=\s*([^;]*);?.*/, '$1'); - return socket.emit('joinanonymously', nickname, roomname); + return primus.send('joinanonymous', nickname, roomname); } if (DOM.modal.hasClass('in')) { @@ -490,7 +490,7 @@ button.click(function() { if ($.trim(login.val()) !== '') { nickname = login.val(); - socket.emit('joinanonymously', nickname, roomname); + primus.send('joinanonymous', nickname, roomname); } else { var txt = 'Nickname can\'t be empty.'; @@ -512,13 +512,13 @@ }; var jplayerReady = function() { - socket.emit('loggedin', function(data) { - if (data) { - nickname = data; + primus.send('loggedin', function(isloggedin, loggedinas) { + if (isloggedin) { + nickname = loggedinas; subscriber = true; - return socket.emit('joinroom', roomname); + return primus.send('joinauthenticated', roomname); } - joinAnonymously(); + joinAnonymous(); }); if (!$.jPlayer.platform.mobile && !$.jPlayer.platform.tablet) { return addVolumeControl(); @@ -544,8 +544,10 @@ return addChatEntry(outcome); } var why = args[1] || ''; - socket.emit('kick', args[0], why, function() { - addChatEntry(outcome); + primus.send('kick', args[0], why, function(success) { + if (!success) { + addChatEntry(outcome); + } }); }; @@ -627,6 +629,16 @@ addFeedback('What is this song?'); }; + // Return a function that will add a random text from the given set, with the given style + var randomFeedback = function(set, style) { + var card = set.length; + return function() { + var index = Math.floor(Math.random() * card) + , text = set[index]; + addFeedback(text, style); + }; + }; + // Successfully joined the room var ready = function(usersData, trackscount, loggedin) { if (!loggedin && !/nickname\s*\=/.test(document.cookie)) { @@ -646,13 +658,13 @@ var val = $.trim(DOM.messagebox.val()); if (val !== '') { if (pvtmsgto) { - socket.emit('sendchatmsg', val, pvtmsgto); + primus.send('sendchatmsg', val, pvtmsgto); } else if (/^\/[^ ]/.test(val)) { slashCommandHandler(val); } else { - socket.emit('sendchatmsg', val); + primus.send('sendchatmsg', val); } } DOM.messagebox.val(''); @@ -665,7 +677,7 @@ var guess = $.trim(DOM.guessbox.val()); if (guess !== '') { if (isplaying) { - socket.emit('guess', guess.toLowerCase()); + primus.send('guess', guess.toLowerCase()); } else { addFeedback('You have to wait the next song...'); @@ -700,30 +712,22 @@ DOM.guessbox.focus(); - socket.on('artistmatched', function() { - addFeedback(amstrings[Math.floor(Math.random()*amstrings.length)], 'correct'); - }); - socket.on('bothmatched', function() { - addFeedback(bmstrings[Math.floor(Math.random()*bmstrings.length)], 'correct'); - }); - socket.on('chatmsg', getChatMessage); - socket.on('gameover', gameOver); - socket.on('loadtrack', loadTrack); - socket.on('newuser', userJoin); - socket.on('nomatch', function() { - addFeedback(nmstrings[Math.floor(Math.random()*nmstrings.length)], 'wrong'); - }); - socket.on('playtrack', playTrack); - socket.on('stoptrying', function() { + primus.on('artistmatched', randomFeedback(amstrings, 'correct')); + primus.on('bothmatched', randomFeedback(bmstrings, 'correct')); + primus.on('chatmsg', getChatMessage); + primus.on('gameover', gameOver); + primus.on('loadtrack', loadTrack); + primus.on('newuser', userJoin); + primus.on('nomatch', randomFeedback(nmstrings, 'wrong')); + primus.on('playtrack', playTrack); + primus.on('stoptrying', function() { addFeedback('You guessed both artist and title. Please wait...'); }); - socket.on('titlematched', function() { - addFeedback(tmstrings[Math.floor(Math.random()*tmstrings.length)], 'correct'); - }); - socket.on('trackinfo', addTrackInfo); - socket.on('updateusers', updateUsers); - socket.on('userleft', userLeft); - socket.emit('getstatus', setStatus); + primus.on('titlematched', randomFeedback(tmstrings, 'correct')); + primus.on('trackinfo', addTrackInfo); + primus.on('updateusers', updateUsers); + primus.on('userleft', userLeft); + primus.send('getstatus', setStatus); }; // Show the number of players inside each room @@ -818,7 +822,7 @@ return addChatEntry(outcome); } delete ignoredplayers[args[0]]; - socket.emit('unignore', args[0]); + primus.send('unignore', args[0]); outcome.text('(From binb): '+args[0]+' is no longer ignored.'); addChatEntry(outcome); }; @@ -970,11 +974,8 @@ e.preventDefault(); } }); - socket = io.connect(uri, { - 'force new connection': true, - 'reconnect': false - }); - socket.on('connect', function() { + primus = Primus.connect(uri, {'strategy': 'none'}); + primus.on('open', function() { jplayer = $('#player').jPlayer({ ready: jplayerReady, swfPath: '/static/swf/', @@ -982,12 +983,12 @@ preload: 'auto', volume: 1 }); - socket.on('alreadyinaroom', alreadyInARoom); - socket.on('disconnect', disconnect); - socket.on('invalidnickname', invalidNickName); - socket.on('ready', ready); - socket.on('updateoverview', updateRoomsOverview); - socket.emit('getoverview', roomsOverview); + primus.on('alreadyinaroom', alreadyInARoom); + primus.on('invalidnickname', invalidNickName); + primus.on('ready', ready); + primus.on('updateoverview', updateRoomsOverview); + primus.send('getoverview', roomsOverview); }); + primus.on('close', disconnect); })(); diff --git a/public/js/home.js b/public/js/home.js index 238bdb5..3a94ad3 100644 --- a/public/js/home.js +++ b/public/js/home.js @@ -14,14 +14,14 @@ }); }); var uri = window.location.protocol+'//'+window.location.host; - var socket = io.connect(uri, {'reconnect':false}); - socket.on('connect', function() { - socket.emit('getoverview', function(data) { + var primus = Primus.connect(uri, {'strategy': 'none'}); + primus.on('open', function() { + primus.send('getoverview', function(data) { for (var prop in data) { $('#'+prop).text(data[prop]); } }); - socket.on('updateoverview', function(room, players) { + primus.on('updateoverview', function(room, players) { $('#'+room).text(players); }); }); diff --git a/routes/site.js b/routes/site.js index b702608..d559f55 100644 --- a/routes/site.js +++ b/routes/site.js @@ -4,12 +4,11 @@ var async = require('async') , Captcha = require('../lib/captcha') + , config = require('../config') , db = require('../lib/redis-clients').songs , randInt = require('../lib/prng').randInt - , rooms = require('../config').rooms - , utils = require('../lib/utils') - , randomSlogan = utils.randomSlogan - , trackscount = utils.trackscount; + , randomSlogan = require('../lib/utils').randomSlogan + , rooms = require('../lib/rooms').rooms; /** * Generate a sub-task. @@ -17,7 +16,7 @@ var async = require('async') var subTask = function(genre) { return function(callback) { - var index = randInt(trackscount[genre]); + var index = randInt(rooms[genre].tracksCount()); db.zrange(genre, index, index, function(err, res) { db.hget('song:'+res[0], 'artworkUrl100', callback); }); @@ -30,7 +29,7 @@ var subTask = function(genre) { exports.artworks = function(req, res) { var tasks = {}; - rooms.forEach(function(room) { + config.rooms.forEach(function(room) { tasks[room] = function(callback) { var subtasks = []; for (var i = 0; i < 6; i++) { @@ -58,7 +57,7 @@ exports.changePasswd = function(req, res) { exports.home = function(req, res) { res.render('home', { loggedin: req.session.user, - rooms: rooms, + rooms: config.rooms, slogan: randomSlogan() }); }; @@ -88,11 +87,11 @@ exports.resetPasswd = function(req, res) { }; exports.room = function(req, res) { - if (~rooms.indexOf(req.params.room)) { + if (~config.rooms.indexOf(req.params.room)) { return res.render('room', { loggedin: req.session.user, roomname: req.params.room, - rooms: rooms, + rooms: config.rooms, slogan: randomSlogan() }); } diff --git a/routes/user.js b/routes/user.js index 7a6955e..edea3c7 100644 --- a/routes/user.js +++ b/routes/user.js @@ -313,7 +313,7 @@ exports.sendEmail = function(req, res) { db.setex('token:'+token, 14400, data, function(err, reply) { mailer.sendEmail(req.body.email, token, function(err, response) { if (err) { - console.log('error sending email: '+err.message); + console.error(err); } }); }); diff --git a/views/home.jade b/views/home.jade index 37fe556..9d77d6f 100644 --- a/views/home.jade +++ b/views/home.jade @@ -56,5 +56,5 @@ block sections | Players append scripts - script(src="/socket.io/socket.io.js") + script(src="/static/js/primus.min.js") script(src="/static/js/home.min.js") diff --git a/views/room.jade b/views/room.jade index d8bf288..7622e35 100644 --- a/views/room.jade +++ b/views/room.jade @@ -97,5 +97,5 @@ block media append scripts script(src="/static/js/jquery.jplayer.min.js") - script(src="/socket.io/socket.io.js") + script(src="/static/js/primus.min.js") script(src="/static/js/app.min.js")