couple
Version:
Couple is an event based collaboration of NodeJS, Express, Socket.IO, Jade and Stylus
164 lines (125 loc) • 4.63 kB
JavaScript
var ee2 = require('eventemitter2').EventEmitter2;
var util = require('util');
var args = require('optimist').argv;
var express = require('express');
var socketio = require('socket.io');
var Session = require('connect').middleware.session.Session;
var MemoryStore = express.session.MemoryStore;
var parseCookie = require('connect').utils.parseCookie;
var server = function( options ){
options = (options)?options:{};
this.port = (options.port)?options.port:80;
this.sid = (options.sid)?options.sid:'couple.sid';
this.secret = (options.secret)?options.secret:'secret';
this.views = (options.views)?options.views:'';
this.viewCache = (options.viewCache)?options.viewCache:false;
this.viewLayout = (options.viewLayout)?options.viewLayout:false;
this.layout = (options.layout)?options.layout:'layout.jade';
this.static = (options.static)?options.static:'public';
this.routes = (typeof(options.routes)=='function')?options.routes:function(express){};
this.ioLog = (options.ioLog)?options.ioLog==true:false;
this._sessionStore = new MemoryStore();
this._express = express.createServer();
this._io = null;
this.__defineGetter__('io', function(){
return this._io;
});
this.__defineGetter__('express', function(){
return this._express;
});
ee2.call(this, {
wildcard: true,
delimiter: '::'
});
};
util.inherits(server,ee2);
server.prototype._expressInit = function(){
this._express.set('views', this.views);
this._express.set('view cache', this.viewCache);
this._express.set('view engine', 'jade');
this._express.set('view options',{
layout: this.viewLayout
});
this._express.use( express.bodyParser() );
this._express.use( express.cookieParser() );
this._express.use( express.session({
store: this._sessionStore,
secret: this.secret,
key: this.sid
}));
this._express.use( require('stylus').middleware({
src: this.static,
compile: function(str,path){
return require('stylus')(str)
.set('filename', path)
.set('compress', true)
.use(require('nib')());
},
compress: true
}));
this.emit('express::init', this._express);
var self = this;
process.nextTick( function(){
self._express.use( express.static(self.static) );
self._express.use( self._express.router );
self.routes(self._express);
self._express.all('*', function(req,res){
self.emit('express::request', req,res);
var request = (req.params.length>0)?req.params[0].substr(1):'index';
res.render( request, {layout: self.layout} );
});
self._express.listen(self.port);
});
};
server.prototype._ioInit = function(){
var self = this;
this._io = socketio.listen(this._express, {log:this.ioLog});
this._io.set('authorization', function(data,accept){
if( data.headers.cookie ){
data.cookie = parseCookie( data.headers.cookie );
data.sessionID = data.cookie[self.sid];
data.sessionStore = self._sessionStore;
self._sessionStore.get(data.sessionID, function(err,session){
if( err || !session ){
accept( 'Error', false );
}else{
data.session = new Session(data,session);
accept(null, true);
}
});
}else{
return accept('No Cookie Transmitted.', false);
}
});
this.emit('io::init', this._io);
var self = this;
process.nextTick( function(){
self._io.sockets.on('connection', function(socket){
var hs = socket.handshake;
var intervalID = setInterval( function(){
hs.session.reload( function(){
hs.session.touch().save();
});
}, 60 * 1000);
self.emit('io::connect', socket);
socket.on('disconnect', function(){
clearInterval(intervalID);
});
});
});
};
server.prototype.start = function(){
this._expressInit();
this._ioInit();
this.emit('express::start');
this.emit('io::start');
};
server.prototype.stop = function(){
try{
this._io.server.close();
this._express.close();
}catch( e ){}
this.emit('express::stop');
this.emit('io::start');
};
module.exports = server;