const services = require('../services') const events = require('events'); const random_bytes = require('random-bytes'); const emitter = new events.EventEmitter(); const { longpolling } = services const poll_server_timeout = 20000; const poll_client_timeout = 60000; poll_request_event_identifier = function (id) { return ('poll-request-' + id).toLowerCase(); } poll_response_event_identifier = function (qid) { return ('poll-response-' + qid).toLowerCase(); } poll_request = function (method, action, id, device, data, callback) { function request_listener(message) { ///// Stop timeout clearTimeout(timeout); callback(null, message); }; ///// Create object object = { method: method, nsip: device || '', action: action || '/', data: JSON.stringify(data).replace(/"/g, "'") || '{}', qid: random_bytes.sync(16).toString('hex') }; ///// Wait long polling to open emitter.emit(poll_request_event_identifier(id), object); ///// Start timeout var timeout = setTimeout(() => { ///// Remove listener emitter.removeListener(poll_response_event_identifier(object.qid), request_listener); ///// Send timeout console.log(id + ' did not long poll (' + object.qid + ')'); callback('timeout', null); }, poll_client_timeout); ///// Listen for event emitter.once(poll_response_event_identifier(object.qid), request_listener); } const postPeriodic = async (req, res, next) => { function listener(message) { ///// Stop timeout clearTimeout(timeout); ///// Send response res.send(message); }; ///// Start timeout var timeout = setTimeout(() => { ///// Remove listener emitter.removeListener(poll_request_event_identifier(req.params.id), listener); ///// Send timeout res.sendStatus(408); console.log('Sending timeout to client ' + req.ip + ' (' + req.params.id + ')'); }, poll_server_timeout); ///// Listen for event emitter.once(poll_request_event_identifier(req.params.id), listener); } const postResponse = async (req, res, next) => { ///// Emit event to client emitter.emit(poll_response_event_identifier(req.params.qid), req.body); ///// Response OK res.sendStatus(200); } const getModuleRequest = async (req, res, next) => { ///// Emit event to server url_encoded = req.query; poll_request(req.method, req.params.route, req.params.id, req.params.module, url_encoded, (error, body) => { if (error) { res.send(error); } else { res.send(body); } }); req.on("close", function () { console.log("Request cancelled by client"); }); } const postModuleRequest = async (req, res, next) => { ///// Emit event to server poll_request(req.method, req.params.route, req.params.id, req.params.module, req.body, (error, body) => { if (error) { res.send(error); } else { res.send(body); } }); req.on("close", function () { console.log("Request cancelled by client"); }); } module.exports = { postPeriodic, postResponse, getModuleRequest, postModuleRequest }