Home > Mobile >  How to implement AWS API Gateway WebSocket heartbeat?
How to implement AWS API Gateway WebSocket heartbeat?

Time:07-18

I am trying to figure out how to implement heartbeat on ApiGateway WebSocket.

I understand that WebSocket close after 10 minutes, so I need to send a ping to a server to keep a connection alive.

I set up client code like this.

  const socket = new WebSocket('wss://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod');
  socket.addEventListener('error', function (event) {
            console.log('WebSocket error: ', event);
          });
  socket.addEventListener('open', (event) => {
            console.log('open',event);
            setInterval(ping,60000)
          });
  socket.addEventListener('message', function (event) {
            console.log('Message from server ', event.data);
          });

  function ping() {
    const res = socket.send(JSON.stringify({"action":"pong"}));
    console.log("ping");
  }

And this is the lambda function set for pong and $default path.

const AWS = require('aws-sdk');

exports.handler = event => {
  console.log("pong");
  return {
    statusCode: 200,
    body: "pong"
  };
};

When socket.send(JSON.stringify({"action":"pong"})); being executed, I receive errors say [Log] Message from server – "{\"message\": \"Internal server error\", \"connectionId\":\"VUeh8f60tjMCF1A=\", \"requestId\":\"VUelwHaYtjMFcJw=\"}"

I enabled error logs on WebSocket API, I found logs like

{
    "requestId": "VUek0FQXtjMFYbg=",
    "ip": "XX.XX.XX.XXX",
    "caller": "-",
    "user": "-",
    "requestTime": "15/Jul/2022:17:59:07  0000",
    "eventType": "MESSAGE",
    "routeKey": "$default",
    "status": "502",
    "connectionId": "VUeh8f60tjMCF1A="
}

I expect the routeKey to be like "routeKey": "pong", but $default path is executed and returns 502 errors. In order to return the response to the client, I need to use postToConnection function of ApiGatewayManagementApi, but my goal is to keep the connection alive with the same connectionId. I can't understand why I am getting this error. Both $default and $connection path don't have an integration response, but $connection path returns 200 after a connection being made.

I expect to receive something like [Log] Message from server - Event {isTrusted : true, type: "message", target: Websocket, ...} on client, but I keep receiving errors. I want to get rid of this.

My question is, How to keep a connection alive after 10 minutes correctly?

CodePudding user response:

I changed exports.handler = event => to exports.handler = async event => then everything worked as expected.

  • Related