Last active
July 28, 2019 23:23
-
-
Save bryanmacfarlane/7684730 to your computer and use it in GitHub Desktop.
node.js http long polling server. using a messaging as an example of longpoll usage.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Crude node.js longpoll example via a simple message queue | |
// | |
//-------------------- | |
// app.js | |
//-------------------- | |
var queue = require('./queue/messagequeue'); | |
app.get('/messages/:queueName/:lastMsgId', queue.getMessages); | |
app.post('/messages/:queueName', queue.postMessages); | |
//-------------------------- | |
// queue/messagequeue.js | |
//-------------------------- | |
// message lists keyed by queuenames (dictionary of arrays) | |
var messages = {}; | |
// counter for each queuename - represents next id to insert @ for a given queue (dictionary of numbers) | |
var counters = {}; | |
// dictionary by queueName with a list of requests for that queueName | |
var queuedRequests = {} | |
exports.postMessages = function(req, res) { | |
var msgs = req.body; | |
var queueName = req.params.queueName; | |
if ((!msgs || !queueName) || (!(msgs instanceof Array))){ | |
res.status(400).send('Bad request. Body must be an array of messages.'); | |
return; | |
} | |
if (!messages.hasOwnProperty(queueName)) { | |
console.log('creating queue ' + queueName); | |
counters = {}; | |
counters[queueName] = 1; // start @ 1 so client starts with lastMsgId of 0 | |
messages[queueName] = [{"data":"0"}]; | |
} | |
messages[queueName] = messages[queueName].concat(msgs); | |
counters[queueName] += msgs.length; | |
// send queued messages | |
if (queuedRequests.hasOwnProperty(queueName)) { | |
queuedRequests[queueName].forEach(function(queuedMessage){ | |
sendMessages(queueName, queuedMessage.lastMsgId, queuedMessage.response); | |
}); | |
} | |
res.status(200).send(msgs); | |
} | |
exports.getMessages = function(req, res) { | |
var queueName = req.params.queueName; | |
var lastMsgId = req.params.lastMsgId; | |
console.log('getMessages ' + queueName); | |
if ((!messages.hasOwnProperty(queueName)) || | |
(lastMsgId == counters[queueName] - 1)) { | |
console.log('queuing response ...'); | |
queueResponse(queueName, lastMsgId, res); | |
return; | |
} | |
if (lastMsgId >= counters[queueName]) { | |
res.status(400).send('Bad request. Invalid lastMsgId.'); | |
} | |
sendMessages(queueName, lastMsgId, res); | |
} | |
var queueResponse = function(queueName, lastMsgId, res) { | |
if (!queuedRequests.hasOwnProperty(queueName)) { | |
queuedRequests[queueName] = []; | |
} | |
queuedRequests[queueName].push({"lastMsgId": lastMsgId, "response": res}); | |
} | |
var sendMessages = function(queueName, lastMsgId, res) { | |
var msgs = messages[queueName].slice(parseInt(lastMsgId) + 1, counters[queueName]); | |
res.status(200).send({"lastMsgId": counters[queueName] - 1, "data": msgs}); | |
} | |
//--------------------------------------------------------------------------------------- | |
// client messagelistener (rest.js is just a class to do get requests and return JSON) | |
//--------------------------------------------------------------------------------------- | |
var rest = require("./rest"); | |
var _queueName; | |
var _host; | |
var _port; | |
var _basePath = "/messages"; | |
var _lastMsgId = 0; | |
var _callback; | |
exports.start = function(queueName, host, port, callback) { | |
_queueName = queueName; | |
_host = host; | |
_port = port; | |
_callback = callback; | |
getMessages(); | |
} | |
var getMessages = function() { | |
var path = _basePath + "/" + _queueName + "/" + _lastMsgId; | |
var options = { | |
host: _host, | |
port: _port, | |
path: path, | |
method: 'GET', | |
headers: { | |
'Content-Type': 'application/json' | |
} | |
}; | |
rest.getJSON(options, | |
function(statusCode, payload) { | |
_lastMsgId = payload.lastMsgId; | |
console.log('lastMsgId: ' + _lastMsgId); | |
_callback(payload.data); | |
getMessages(); | |
}); | |
} | |
//----------------------------------------------- | |
// client.js | |
//----------------------------------------------- | |
var listener = require('./messagelistener'); | |
var queueName = "myqueue"; | |
var host = "localhost"; | |
var port = 3000; | |
console.log('listening to ' + queueName); | |
listener.start(queueName, host, port, function(messages) { | |
console.log('callback ...') | |
console.log(JSON.stringify(messages, null, 2)); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment