Skip to content

Instantly share code, notes, and snippets.

@MilosRasic
Created June 27, 2011 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MilosRasic/0ec8b5581bdbf80fb433 to your computer and use it in GitHub Desktop.
Save MilosRasic/0ec8b5581bdbf80fb433 to your computer and use it in GitHub Desktop.
A pushlet for nodejs
var http = require('http');
var querystring = require('querystring');
var pushlet = {};
//actions, like in an MVC controller
pushlet.actions = {};
//2d array of pairs of requests and responses and ids of streams for clients that registered for notifications, grouped by modules
pushlet.clients = [];
//calls one of defined actions based on the request url or returns false if the action is not defined
pushlet.route = function(request, response) {
console.log('routing '+request.url);
var uriComponents = request.url.split('/');
console.log(uriComponents[1]);
if (typeof pushlet.actions[uriComponents[1]] == 'function') {
console.log('action '+uriComponents[1]+' found');
request.connection.setTimeout(0);
pushlet.actions[uriComponents[1]].apply(pushlet, [request, response, uriComponents[2]]);
return true;
}
return false;
};
//starts a text/event-stream response
pushlet.startStream = function(request, response) {
console.log('starting stream');
response.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
return 'pushlet-stream-'+(new Date()).getTime();
}
//turns the received data into a string which is sent as respone
pushlet.parseData = function(data) {
if (typeof data == 'object' && data.length) {
console.log('parsing data recursively for '+data);
var response = '';
for (var d in data)
response += pushlet.parseData(data[d]);
return response;
}
else {
if (typeof data != 'string' && typeof data.toString == 'function')
data = data.toString();
return "data: " + data + '\n';
}
}
//sends an event to the stream
pushlet.sendEvent = function(response, id, data) {
console.log('sending event');
response.write('id: ' + id + '\n');
response.write(pushlet.parseData(data)+'\n');
}
//starts a response and puts it into the clients array
pushlet.actions.register = function(request, response, module) {
console.log('registering client for module '+module);
var id = pushlet.startStream(request, response);
if (typeof pushlet.clients[module] == 'undefined')
pushlet.clients[module] = [];
var clientIndex = pushlet.clients[module].push([id, response]) - 1;
request.on('close', function() {
console.log('connection closed by the client, removing client at index '+clientIndex+' from array.');
pushlet.clients.splice(clientIndex, 1);
});
}
//notification
pushlet.actions.notify = function(request, response, module, data) {
console.log('notification received from module '+module);
console.log('method is '+request.method);
if (typeof pushlet.clients[module] != 'undefined') {
var postData = '';
request.on('data', function(chunk) {
console.log('data event');
postData += chunk;
});
request.on('end', function() {
console.log('end event');
response.writeHead(200);
console.log('code 200 header sent');
response.end('ok\n\n');
console.log('response sent');
var eventData = (request.method == 'GET')? data : querystring.parse(postData).data;
if (typeof eventData == 'undefined')
eventData = '';
console.log('sending events for module '+module);
console.log('data is: '+eventData);
for (var c in pushlet.clients[module])
pushlet.sendEvent(pushlet.clients[module][c][1], pushlet.clients[module][c][0], eventData);
});
if (request.method == 'GET')
request.emit('end');
} else {
console.log('No listeners for the module.');
response.writeHead(200);
response.end('ok\n\n');
}
}
//initialising the server
http.createServer(function(request, response) {
console.log('received request '+request.url);
if (!pushlet.route(request, response)) {
console.log('bad request');
response.writeHead(404);
response.end();
}
}).listen(6969);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment