简体   繁体   中英

How to return net.socket data from AWS Lambda Node.js 8.10 async function to AWS API gateway?

I have this Lambda function:

exports.handler = async (event,context,callback) => {
  // console.log('Received event:', JSON.stringify(event, null, 2));
  var key=event.queryStringParameters.ref;
  // console.log('index.handler started with key : '+key);
  var RemoteServer='aaa.bbb.ccc.ddd';
  var net = require('net');
  var responce={
      "statusCode": 200,
      "headers": {
          "Content-Type": "*/*"
      }
  };

  var socket = new net.Socket();

  socket.setEncoding('utf8');

  socket.on('close', () => {
    console.log('Close.');
    console.log(JSON.stringify(responce));
    callback(null, JSON.stringify(responce));

  });
  socket.on('connect', () => {
    // console.log('Connect');
    var senddata='1,'+key;
    // console.log(('About to write :'+senddata));
    socket.write(senddata);
    console.log(('Wrote :'+senddata));
  });
  socket.on('data', (data) => {
    console.log('Data.');
    responce.body = data;
    console.log(JSON.stringify(responce));
    socket.end();
  });
  socket.on('end', () => {
    console.log('End.');
    console.log(JSON.stringify(responce));
  });
  socket.on('error', (error) => {
    console.log('Error' + error);
    socket.destroy;
    callback(error);
  });
  socket.on('timeout', () => {
    console.log('Timeout');
    socket.close;
    callback('Timeout');
  });

  socket.connect(11010, RemoteServer, () => { 
    // console.log('socket connect');
  });

  callback(null,responce); // This is here to get this to do anything.
};

It works, in as such that the console.log shows that I am getting the correct data in the socket.on('data') routine.

However, it fails to return the responce.body in the callback. Also, it only works if I have a callback in the async function, not in the event listeners.

This is my output - console.log:

START RequestId: 7e1876fe-4255-12de-56d6-c187bcfff9ee Version: $LATEST
Wrote :1,R9H39X
Data.
{"statusCode":200,"headers":{"Content-Type":"*/*"},"body":"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<group>\r\n  <data>\r\n    <name>COLIN MANNING</name>\r\n    <from>26/03/2018</from>\r\n    <to>31/05/2018</to>\r\n    <room>A31</room>\r\n    <location>X,Y</location>\r\n  </data>\r\n</group>\r\n"}
End.
{"statusCode":200,"headers":{"Content-Type":"*/*"},"body":"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<group>\r\n  <data>\r\n    <name>COLIN MANNING</name>\r\n    <from>26/03/2018</from>\r\n    <to>31/05/2018</to>\r\n    <room>A31</room>\r\n    <location>X,Y</location>\r\n  </data>\r\n</group>\r\n"}
Close.
{"statusCode":200,"headers":{"Content-Type":"*/*"},"body":"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<group>\r\n  <data>\r\n    <name>COLIN MANNING</name>\r\n    <from>26/03/2018</from>\r\n    <to>31/05/2018</to>\r\n    <room>A31</room>\r\n    <location>X,Y</location>\r\n  </data>\r\n</group>\r\n"}
END RequestId: 7e1876fe-4255-12de-56d6-c187bcfff9ee
REPORT RequestId: 7e1876fe-4255-12de-56d6-c187bcfff9ee    Duration: 178.76 ms     Billed Duration: 200 ms Memory Size: 1536 MB    Max Memory Used: 33 MB 

and callback:

{"statusCode":200,"headers":{"Content-Type":"*/*"}}

And this is the console.log without the last callback:

START RequestId: c3dc7e69-87aa-1608-76d4-093a0e28711b Version: $LATEST
END RequestId: c3dc7e69-87aa-1608-76d4-093a0e28711b
REPORT RequestId: c3dc7e69-87aa-1608-76d4-093a0e28711b    Duration: 3.43 ms       Billed Duration: 100 ms Memory Size: 1536 MB    Max Memory Used: 33 MB

and callback:

null

So without the callback, nothing runs.

What I want to achieve is: Open socket to server. send data through socket get reply from server through socket close socket return reply to API Gateway

This is my first attempt at Node.js async, Lambda and API Gateway. I assume that I have an error in the way I understand Node.js async and callbacks.

How do I return the data from the socket.on('close') listener?

It appears to me that the callback in the listener is never called, I and cannot determine how to make the callback in the async function await for the data from the listener.

Am I supposed to use EventAsPromise and then block with a while (!done) {....}? This seams to go against the Node async philosophy.

OK, so I found this post:

How Can I Wait In Node.js (Javascript), l need to pause for a period of time

and went down to Aminadav's answer.

So I end up with this function declared ahead of my existing code:

function sleep(ms){
    return new Promise(resolve=>{
        setTimeout(resolve,ms)
    })
};

and now the end of my original code looks like this:

  socket.connect(11010, RemoteServer, () => {
    // console.log('socket connect');
  });

  while (!socket.destroyed) {
    await sleep(10);
  }

  callback(null,responce);
};

So now I get the data returned to my calling function.

I'm not sure that a sleep() is the best way to do this, but it gets me moving on. This is an answer, but I appreciate that it may not be the best answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM