How can I maintain persist a Cloud Functions connection using ExpressJS - node.js

const http = require('http');
const functions = require('firebase-functions');
const agent = new http.Agent({keepAlive: true});
exports.function = functions.https.onRequest((request, response) => {
req = http.request({
host: '',
port: 80,
path: '',
method: 'GET',
agent: agent,
}, res => {
let rawData = '';
res.setEncoding('utf8');
res.on('data', chunk => { rawData += chunk; });
res.on('end', () => {
response.status(200).send(`Data: ${rawData}`);
});
});
req.on('error', e => {
response.status(500).send(`Error: ${e.message}`);
});
req.end();
});
This is the code from Optimizing networking using Cloud Functions. How can I update it to use expressJS.
So from the code I see that the trick is this line const agent = new http.Agent({keepAlive: true}) and then in the request agent: agent.
I tried doing something like
const server = express()
server.use((req, res, next) => {
req.agent = new http.Agent({keepAlive: true})
next()
})
But did't work. HELP!!!

Just put on index.js
require('https').globalAgent.keepAlive = true;

Related

How to subscribe a HTTP endpoint to SNS in node js?

I am trying to subscribe my endpoint to a topic (I am using an EC2 instance), I have tried visiting my endpoint in a browser (GET request) to call sns.subscribe but I am not receiving a POST request afterwards.
The response I get from calling sns.subscribe is this.
{ ResponseMetadata: { RequestId: 'xxxx-xxxx-xxxx-xxx-xxxx' },
SubscriptionArn: 'arn:aws:sns:topic_location:xxxx:topic_name:xxxx-xxxx-xxxx-xxx-xxxx' }
This is my code.
const express = require("express");
const AWS = require('aws-sdk');
const request = require('request')
const bodyParser = require('body-parser')
const app = express();
var SNS_TOPIC_ARN = "arn:aws:sns:topic_location:xxxx:topic_name";
// configure AWS
AWS.config.update({
'accessKeyId': 'mykey',
'secretAccessKey': 'mysecretkey',
"region":"myregion"
});
const sns = new AWS.SNS();
app.get('/', (req, res) => {
var params = {
Protocol: 'http', /* required */ //http , https ,application
TopicArn: SNS_TOPIC_ARN, /* required */ // topic you want to subscribe
Endpoint: 'http://ec2-xx-xx-xx-xxx.myregion.compute.amazonaws.com/:80', // the endpoint that you want to receive notifications.
ReturnSubscriptionArn: true //|| false
};
sns.subscribe(params, function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
res.end();
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.post('/', (req, res) => {
let body = ''
req.on('data', (chunk) => {
body += chunk.toString()
})
req.on('end', () => {
let payload = JSON.parse(body)
if (payload.Type === 'SubscriptionConfirmation') {
const promise = new Promise((resolve, reject) => {
const url = payload.SubscribeURL
request(url, (error, response) => {
if (!error && response.statusCode == 200) {
console.log('Yess! We have accepted the confirmation from AWS')
return resolve()
} else {
return reject()
}
})
})
promise.then(() => {
res.end("ok")
})
}
})
})
app.listen(80, process.env.IP, function(request, response){
console.log("## SERVER STARTED ##");
});
I had to remove my port number from the endpoint when calling sns.subscribe! My subscription has now been confirmed :D The new endpoint looks like this.
Endpoint: 'http://ec2-xx-xx-xx-xxx.myregion.compute.amazonaws.com/

how to send response in hhtp module

I'm new to node.js, So how to send duration in response in http module i tried sending it through req.write and req.writeHead(), but its not working.Help me with this issue
var https = require('https');
const config_KEYS = require('./config.js');
exports.handler = (event, context, callback) => {
var userLat = event.userLat;
var userLong = event.userLong;
var destinationLat = event.destinationLat;
var destinationLong = event.destinationLong;
var params = {
host:'maps.googleapis.com',
path: '/maps/api/distancematrix/json?units=imperial&origins='+userLat+","+userLong+'&destinations='+destinationLat+","+destinationLong+'&key='+config_KEYS.GOOGLE_API_KEY+'&departure_time=now'
};
var req = https.request(params, function(res) {
let data = '';
console.log('STATUS: ' + res.statusCode);
// res.setEncoding('utf8');
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
console.log("DONE");
const parsedData = JSON.parse(data);
console.log("data ===>>>>",parsedData);
var duration = parsedData.rows[0].elements[0].duration_in_traffic.text;
var obj = {}
obj.duration = duration
res.end(duration) ;
});
});
req.write(callback)
req.end();
};
In node js https there is one method like res.end() to send data after https request ends
Example:
const https = require('https');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
passphrase: 'sample'
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
Here what you want to achieve is use function in res.on('end', ) and then return to that function. So, In your case it will not send in res.on('end', ) because untimately you're returning a value to function not a method.
Here is the solution:
const parsedData = JSON.parse(data);
console.log("data ===>>>>",parsedData);
var duration = parsedData.rows[0].elements[0].duration_in_traffic.text;
req.end('duration');
one more way is you can use callback. For the reference I am providing one link
Callback https

http-proxy-middleware blocking web page

Do you have any idea why when opening the following web page on the browser it keeps loading (blocking)?
http://localhost:3002/
If you place a return; just before the line: res.writeHead = (...args) => { writeHeadArgs = args; };, the page works normal but the logic of the code is not executed. If you place the return after that line, it keeps loading forever.
Run
$ node server.js
server.js
var express = require('express');
var http = require('http');
var proxy = require('http-proxy-middleware');
function bodyTransform(body) {
return body.replace('World', 'People');
}
var onProxyRes = (proxyRes, req, res) => {
const end = res.end;
const writeHead = res.writeHead;
let writeHeadArgs;
let body;
var buffer = new Buffer('');
proxyRes.on('data', (chunk) => {
console.log("inside: .on('data', ...)");
buffer = Buffer.concat([buffer, chunk]);
});
proxyRes.on('end', () => {
console.log("inside: .on('end', ...)");
body = buffer.toString('utf8');
});
res.write = () => { };
res.writeHead = (...args) => { writeHeadArgs = args; };
res.end = () => {
const output = bodyTransform(buffer.toString());
res.setHeader('content-length', output.length);
if (writeHeadArgs)
writeHead.apply(res, writeHeadArgs);
end.apply(res, [output]);
console.log('after: end.apply(res, [output]);');
};
}
const portApp01 = 3001;
const app01 = express()
app01.get('/', (req, res) => {
res.send('Hello World!');
});
app01.listen(portApp01, () => {
console.log('app01 is listening on port: ' + portApp01);
});
const portProxy = 3002;
const appProxy = express()
appProxy.use(proxy({ target:'http://localhost:3001', onProxyRes: onProxyRes, changeOrigin: true }));
http.createServer(appProxy).listen(portProxy, function () {
console.log('appProxy is listening on port: ' + portProxy);
});
This is the output I get on the terminal:
[HPM] Proxy created: / -> http://localhost:3001
app01 is listening on port: 3001
appProxy is listening on port: 3002
inside: .on('data', ...)
inside: .on('end', ...)
after: end.apply(res, [output]);
Any idea on how to solve this?
Thanks!

Express nodejs router always on dealing

In my app.js, I definite a search router
app.use('/search', require('./router/search'))
In the search.js files, what I do is request a website and response website data, but the router always on dealing.
const express = require('express')
const router = express()
const url = require('url')
const http = require('http')
router.get('/', searchHandler)
function searchHandler(req, res) {
request('http://baidu.com', 'get')
.then(result => {
res.end(result)
})
}
function request(link, method, data) {
return new Promise((resolve, reject) => {
link = url.parse(link)
const result = '';
const options = {
hostname: link.hostname,
port: 80,
path: link.path,
method: method
}
http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function(chunk) {
result += chunk;
});
res.on('end', function() {
resolve(result)
})
req.on('error', function(err) {
reject(err);
});
})
})
}
module.exports = router
why does my res.end(result) not works?

how to get data from an api on the server side and pass the data retrieved to pugjs file using expressjs?

sample code:
// index.pug
p #{polls}
// apiendpoint
http://localhost:8080/api/polls
// routes file (index.js):
Here, how do I make get request to the api, and pass the retrieved result from api(locals) to polls variable while rendering the profile.pug
app.route('/profile')
.get(isLoggedIn, function (req, res) {
res.render('profile', {'polls': passvaluehere});
});
});
You can also use **http** module like this
var http = require('http');
var options = {
host: 'localhost',
path: '/api/polls',
port: '80',
method: 'GET'
};
var req = http.request(options, response);
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
res.render('profile', {'polls': str});
});
req.end();

Resources