我在Amazon Lambda上创建了一个函数。我的情况是我必须在两个不同的URL上同时发送两个HTTP请求。所以我在我的代码中用不同的URL写了两个HTTP请求。问题是大部分时间没有调用第一个HTTP请求,第二个HTTP请求几乎一直在运行。所以请帮我弄清楚问题所在。这是我的代码
console.log('Loading function');
var aws = require('aws-sdk');
var http = require('http');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
var params = {
Bucket: bucket,
Key: decodeURIComponent(key)
};
s3.getObject(params, function(err, data) {
if (err) {
console.log("Error getting object " + key + " from bucket " + bucket +
". Make sure they exist and your bucket is in the same region as this function.");
context.fail("Error getting file: " + err);
} else {
var userString = JSON.stringify(params);
console.log(userString);
var options = {
hostname: 'example1.com',
path: '/api/test1.cfm',
method: 'POST',
Port:'80',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': userString.length
}
};
console.log("Start");
var x = http.request(options,function(res){
console.log("Connected");
console.log('CONTENT TYPE:', data.ContentType);
console.log("Start");
console.log("x");
context.succeed(data.ContentType);
});
x.write(userString);
x.end();
var optionsdev = {
hostname: 'example2.com',
path: '/api/test2.cfm',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': userString.length
}
};
console.log("Start");
var y = http.request(optionsdev,function(res){
console.log("Connected");
console.log('CONTENT TYPE:', data.ContentType);
console.log("Start");
console.log("y");
context.succeed(data.ContentType);
});
y.write(userString);
y.end();
}
});
};
答案 0 :(得分:1)
首先,如果你看一下http.request()
的node.js文档中的示例代码,你会得到一个回调,但是在那个回调中,你传递了一个响应对象,它是一个流,你必须设置事件处理程序。
以下是文档中的基本结构:
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
res.on('end', function() {
console.log('No more data in response.')
})
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write(postData);
req.end();
因此,您必须在收到“数据”时处理回复。并且'结束'响应对象上的事件。
对于大多数请求,这有点不方便,因为您必须累积响应,因为data
事件可以被调用多个。我建议使用请求模块,因为它为您完成了更多的工作。
然后,其次,如果您希望一个接一个地连续处理您的操作,则需要在第一个操作完成之前不要启动第二个操作。有许多不同的方法来构造它,但最像你已经拥有的结构就是在完成第一个请求时启动第二个请求。
以下是使用request()
module:
var aws = require('aws-sdk');
var http = require('http');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
var request = require('request');
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
var params = {
Bucket: bucket,
Key: decodeURIComponent(key)
};
s3.getObject(params, function(err, data) {
if (err) {
console.log("Error getting object " + key + " from bucket " + bucket +
". Make sure they exist and your bucket is in the same region as this function.");
context.fail("Error getting file: " + err);
} else {
var sendData = JSON.stringify(params);
request.post('http://example1.com/api/test1.cfm', {form: sendData}, function(err, httpResponse, body) {
if (err) {
console.log("Error on first post");
} else {
// do something with the response here
console.log("first request = ", body);
// context.succeed(...);
// now launch the second request
request.post('http://example2.com/api/test2.cfm', {form: sendData}, function(err, httpResponse, body) {
if (err) {
console.log("Error on second post");
} else {
// do something with the response here
console.log("second request = ", body)
// context.succeed(...);
// done with both requests here
}
});
}
});
}
});
};