2015-12-04 2 views
2

Я создал функцию на Amazon Lambda. Мой сценарий заключается в том, что я должен отправлять два HTTP-запроса одновременно на двух разных URL-адресах. Поэтому я пишу два HTTP-запроса в моем коде с разными URL-адресами. Проблема в том, что большую часть времени первый HTTP-запрос не вызывается, а второй HTTP-запрос почти все время работает. Поэтому, пожалуйста, помогите мне разобраться с проблемой. Вот мой кодДва запроса HTTP-запросов в nodejs

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(); 



     } 
    }); 
}; 
+3

Почему вы говорите, ваш первый запрос не вызывается? –

+0

Ваш код будет иметь два HTTP-запросов, работающих параллельно, и оба будут бороться с 'context.succeed()' first. Сначала вы закончите, но может быть не предсказуемо, какой из них заканчивается первым. Второй будет закончен, а также вызовет 'context.succeed()'. – jfriend00

+0

его не вызывали когда-то, но иногда правильно запускали –

ответ

1

Во-первых, если вы посмотрите на пример кода в Node.js док для http.request(), вы получите обратный вызов, но в этом обратный вызов, вы прошли объект ответа, и это поток что вы должны установить обработчики событий.

Вот основная структура из документации:

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(); 

Таким образом, вы должны обработать ответ, когда вы получаете «данные» и «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 

         } 
        }); 
       } 
      }); 
     } 
    }); 
}; 
Смежные вопросы