Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS API Gateway WebSocket Timeout?

How do I keep an API Gateway Websocket API with a Lambda Java back end from timing out after 30 seconds?

The AWS API Gateway and re:invent videos mention using pings or heartbeats to keep the Websocket connection alive but I haven't found a straight-forward working example (in Java). The front end is using HTML 5 Websockets (vanilla javascript).

I'm including my Lambda test driver in Java. It causes the API Gateway WS API to timeout after 30 seconds as documented. The driver will return successfully if you remove the delay. Any help is appreciated...

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestWSClient implements RequestStreamHandler {

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) {
        try {
            //
            // How do we keep API Gateway from timing out after 30 seconds?
            // Is something like this even needed in the lambda?
            //
            new Thread(() -> {
                while(true) {    
                    try {
                        // Ping client every 15 seconds
                        Thread.sleep(15000);
                        //outputStream.write(); // What to write -- 0x89 0x00?
                        outputStream.flush();
                    } catch(Exception e) { e.printStackTrace(); }
                }
            }).start();

            //
            // Simulate long processing time or streaming
            //
            // NOTE: commenting sleep enables service to return w/o a timeout
            //       connection from API Gateway
            //
            try { Thread.sleep(60000); } catch(Exception e) {}

            var response = Map.of(
                "statusCode", 200,
                "headers", Map.of("Content-Type", "text/csv"),
                "body", "Hello,World"
            );

            ObjectMapper om = new ObjectMapper();

            outputStream.write(om.writeValueAsBytes(response));
            outputStream.flush();
        } catch(Exception e) { e.printStackTrace(); }
        finally { try { outputStream.close(); } catch(Exception e) {} }
    }
}
like image 880
user2536502 Avatar asked Sep 20 '25 18:09

user2536502


1 Answers

I do not think I understand your problem correctly but here is how WebSocket API work in my experience. client(s) <-(1)-> API Gateway <-(2)-> Lambda

1) is the web socket connection which stays open for a maximum of 2 hours, with idle timeout of 10 minutes as mentioned here. https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html

2 )communication is managed using @connection https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html

I believe you want to use @connection for talking to your API Gateway from lambda.

like image 181
vijtrip2 Avatar answered Sep 22 '25 08:09

vijtrip2