Navigation Menu

Skip to content

Commit

Permalink
Split stuff up into individual files
Browse files Browse the repository at this point in the history
  • Loading branch information
felixge committed Oct 29, 2009
1 parent 11381d5 commit 1496078
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 274 deletions.
276 changes: 2 additions & 274 deletions server/lib/node-channel.js
@@ -1,276 +1,4 @@
node.libraryPaths.unshift(node.path.dirname(__filename)+'/..');

var http = require('/http.js');
var multipart = require('/multipart.js');
var utils = require('/utils.js');

exports.uuid = function() {
var uuid = '';
for (i = 0; i < 32; i++) {
uuid += Math.floor(Math.random() * 16).toString(16);
}
return uuid;
};


var Server = require('node-channel/server.js').Server;
exports.createServer = function() {
return new exports.Server();
};

exports.Server = function() {
node.EventEmitter.call(this);

this.channels = {};
this.responses = {};

var self = this;
this.httpServer = http.createServer(function(req, res) {
var request = new exports.Request(req, res);
request
.parse()
.addErrback(function() {
request.respond(500, {error: 'Could not parse request.'});
})
.addCallback(function() {
p(request.form);
p('no');
self.emit('request', request);
});
});

this.addListener('request', function(request) {
var prefix = request.uri.path.substr(1, 1);
if (prefix == '_') {
var data = {};
if (request.form.data) {
try {
data = JSON.parse(request.form.data);
} catch (e) {
// @fixme needs to be handled
}
}

switch (request.uri.path) {
case '/_response':
var request_id = request.uri.params._request_id;
var response = self.responses[request_id];
if (response) {
request.respond(response.code, response.response);
} else {
request.respond(404, {error:
'Unknown request_id: '+
JSON.stringify(request_id)
})

}
break;
case '/_create_channel':
var uuid = exports.uuid();
var channel = self.createChannel(uuid);

request.respond(200, {
ok: true,
id: uuid
});
break;
default:
request.respond(404, {error:
'Unknown command: '+
JSON.stringify(req.uri.path)
})
break;
}

if (data._request_id) {
self.responses[data._request_id] = request.response;
}
return;
}

var id = request.uri.path.substr(1);
if (!id) {
return request.respond(200, {ok: true, welcome: 'node-channel'});
}

if (!(id in this.channels)) {
return request.respond(404, {error: 'Unknown channel: '+JSON.stringify(id)})
}

var channel = this.channels[id];
if (request.method === 'post') {
this.emit('postEvents', channel, request);
} else {
this.emit('getEvents', channel, request);
}
});

this.addListener('getEvents', function(channel, request) {
var since = parseInt(request.req.uri.params.since || 0, 10);
channel.onHistory(since, function(history) {
request.respond(200, {
ok: true,
since: since,
history: history
});
});
});

this.addListener('postEvents', function(channel, request) {
var parser = new multipart.parse(request.req), self = this;

parser.addCallback(function(parts) {
if (!('data' in parts) || !parts.data) {
return request.respond(400, 'Sorry, but your message body contained no data!');
}

var events = JSON.parse(parts.data);
for (var i = 0; i < events.length; i++) {
var event = events[i], args = event.args;
args.unshift(event.name);
channel.emit.apply(channel, args);
}

request.respond(200, {
ok: true
});
});
});
};
node.inherits(exports.Server, node.EventEmitter);

exports.Server.prototype.listen = function(port) {
this.httpServer.listen(port);
};

exports.Server.prototype.createChannel = function(id) {
var channel = new exports.Channel(id);
return this.channels[id] = channel;
};

exports.Request = function(req, res) {
node.EventEmitter.call(this);

this.req = req;
this.res = res;

this.method = this.req.method.toLowerCase();
this.uri = this.req.uri;
this.form = {};

this.response = null;
};
node.inherits(exports.Request, node.EventEmitter);

exports.Request.prototype.respond = function(code, response) {
this.response = {code: code, response: response};

response = JSON.stringify(response);

var jsonp = this.req.uri.params.callback;
if (jsonp) {
response = jsonp + '('+response+')';
this.res.sendHeader(200, {'Content-Type': 'text/javascript'});
} else {
this.res.sendHeader(code, {'Content-Type': 'text/javascript'});
}

this.res.sendBody(response);
this.res.finish();
};

exports.Request.prototype.parse = function() {
var promise = new node.Promise();

if (this.method === 'get') {
setTimeout(function() {
promise.emitSuccess();
});
return promise;
}

var self = this, parser = new multipart.parse(this.req);
parser
.addErrback(function() {
promise.emitError();
})
.addCallback(function(parts) {
self.form = parts;
promise.emitSuccess();
});
return promise;
};

exports.Request.prototype.parts = function(callback) {
if (this.req.method === 'get') {
return callback();
}

var parser = new multipart.parse(this.req);
parser.addCallback(function(parts) {
callback(parts);
});
};

exports.Channel = function(id) {
node.EventEmitter.call(this);

this.id = id;

this.monitor = new node.EventEmitter();
this.ignores = ['newListener'];
this.history = [];
};
node.inherits(exports.Channel, node.EventEmitter);

exports.Channel.prototype.seek = function(since) {
if (!since) {
return this.history;
}

for (var i = this.history.length - 1; i >= 0; i--) {
if (this.history[i].time <= since) {
i++;
break;
}
}

if (i < 0 ) {
i = 0;
}
return this.history.slice(i);
}

exports.Channel.prototype.onHistory = function(since, callback) {
var history = this.seek(since);
if (history.length) {
return callback(history);
}

var self = this, emitListener = function() {
var history = self.seek(since);
if (!history.length) {
return;
}

setTimeout(function() {
var listeners = self.monitor.listeners('emit');
listeners.splice(listeners.indexOf(emitListener), 1);
});
callback(history);
};
this.monitor.addListener('emit', emitListener);
};

exports.Channel.prototype.emit = function() {
var args = Array.prototype.slice.call(arguments);
node.EventEmitter.prototype.emit.apply(this, args);

var name = args.shift();
if (this.ignores.indexOf(name) > -1) {
return;
}

var event = {name: name, time: (+new Date()), args: args};
this.history.push(event);
this.monitor.emit('emit', event);
return new Server();
};
63 changes: 63 additions & 0 deletions server/lib/node-channel/channel.js
@@ -0,0 +1,63 @@
exports.Channel = function(id) {
node.EventEmitter.call(this);

this.id = id;

this.monitor = new node.EventEmitter();
this.ignores = ['newListener'];
this.history = [];
};
node.inherits(exports.Channel, node.EventEmitter);

exports.Channel.prototype.seek = function(since) {
if (!since) {
return this.history;
}

for (var i = this.history.length - 1; i >= 0; i--) {
if (this.history[i].time <= since) {
i++;
break;
}
}

if (i < 0 ) {
i = 0;
}
return this.history.slice(i);
}

exports.Channel.prototype.onHistory = function(since, callback) {
var history = this.seek(since);
if (history.length) {
return callback(history);
}

var self = this, emitListener = function() {
var history = self.seek(since);
if (!history.length) {
return;
}

setTimeout(function() {
var listeners = self.monitor.listeners('emit');
listeners.splice(listeners.indexOf(emitListener), 1);
});
callback(history);
};
this.monitor.addListener('emit', emitListener);
};

exports.Channel.prototype.emit = function() {
var args = Array.prototype.slice.call(arguments);
node.EventEmitter.prototype.emit.apply(this, args);

var name = args.shift();
if (this.ignores.indexOf(name) > -1) {
return;
}

var event = {name: name, time: (+new Date()), args: args};
this.history.push(event);
this.monitor.emit('emit', event);
};
7 changes: 7 additions & 0 deletions server/lib/node-channel/misc.js
@@ -0,0 +1,7 @@
exports.uuid = function() {
var uuid = '';
for (i = 0; i < 32; i++) {
uuid += Math.floor(Math.random() * 16).toString(16);
}
return uuid;
};

0 comments on commit 1496078

Please sign in to comment.