简体   繁体   中英

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) {} }
    }
}

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.

It looks like a NAT Gateway is required for a Lambda to call the postToConnection function provided by the AWS ApiGatewayManagementApi SDK.

Its a shame this requirement isn't specified anywhere regarding Websockets API or API Gateway.

Search for 'NAT' on this page, and read that sentence:

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