secret
Last active

A pushlet for nodejs

  • Download Gist
pushlet.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
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);

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.