如何为 API Gateway Websocket 编写 Java Lambda 处理程序?

Posted

技术标签:

【中文标题】如何为 API Gateway Websocket 编写 Java Lambda 处理程序?【英文标题】:How to write Java Lambda handler for API Gateway Websocket? 【发布时间】:2019-02-18 14:24:17 【问题描述】:

我很难弄清楚如何编写处理 Websocket 消息的 Java Lambda 函数,其中 Websocket 由 2018 年底刚刚发布的新 API Gateway 函数处理。具体问题: * 我应该为输入对象使用什么类型?我目前正在使用 APIGatewayProxyRequestEvent。是否有特定于 Websocket 请求的类型?我在 aws-lambda-java-events-2.2.5.jar 中没有看到。 * 如果我使用了正确的类型,我如何访问连接 ID?我是否需要使用 API 映射?我看到了这个链接,但它实际上并没有告诉你如何为 Websockets 进行映射,对于这类事情,它似乎有与 REST API 不同的选项。 https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html

提前致谢!

公共类 WebsocketHandler 实现 RequestHandler

@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) 
    context.getLogger().log("Input: " + input);
    context.getLogger().log("Context:  " + context);

    ProxyRequestContext requestContext = input.getRequestContext();
    context.getLogger().log("requestContext:  " + requestContext);

    // I don't see Connection ID in any of these

    APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
    response.setStatusCode(200);
    response.setBody("All good here.");
    return response;

【问题讨论】:

【参考方案1】:

这是我从 AWS Support 获得的回复。有用!不过,我还不能寄回给客户。如果有人成功做到这一点,请告诉我。我正在尝试使用 AmazonHTTPClient,但我不清楚如何使用 AWS4Signer 正确签署消息。如果有人成功做到这一点,请告诉我。

目前,我们在 APIGatewayProxyRequestEvent 中不提供对 Web 套接字的支持,就像我们对 REST [1] 所做的那样。不过我已经向负责管理 GitHub 存储库的团队提到了这一点,因此他们最终也会为 Web 套接字实现一个类。

目前,替代方法是将输入视为流并使用任何可用的 JSON 解析器对其进行解析。为了让您开始,我附上了一个示例项目,您可以使用“mvn package”构建并上传到 Lambda。我已经亲自对其进行了测试,并且能够将 API Gateway 返回的整个 requestContext [2] 打印为字符串。唯一缺少的部分是 JSON 字符串的解析。

请注意,我提供的代码来自我能够在内部收集的一些示例,它还没有准备好用于生产,它仅用作样板代码。另外我想提一下,代码支持通常超出 AWS 高级支持的范围,因此我不能保证我或其他 AWS 工程师能够进一步支持此代码。不过,我想为您提供一些入门知识,因为我了解我们的文档缺少 Web Socket API Gateway 和 Java 的示例。

代码示例

package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class LambdaBasicStreamFunction implements RequestStreamHandler 
    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException 
        int letter;
        String eventObject = "";

        while ((letter = inputStream.read()) > -1) 
            char inputChar= (char) letter;
            eventObject += inputChar;
        

        //Passing a custom response as the output string
        String response = "\n" +
                "    \"statusCode\": 200,\n" +
                "    \"headers\": \"Content-Type\": \"application/json\",\n" +
                "    \"body\": \"plain text response\"\n" +
                "";
        outputStream.write(response.getBytes());

        System.out.println("Input-Event: " + eventObject);
    

【讨论】:

对我来说,与客户的通信是这样的:` AmazonApiGatewayManagementApi api = AmazonApiGatewayManagementApiClientBuilder.standard().withEndpointConfiguration( new EndpointConfiguration("api-id.execute-api.region.amazonaws. com/stage", "region") ).build(); PostToConnectionRequest post = new PostToConnectionRequest(); post.setConnectionId(connectionId); post.setData(ByteBuffer.wrap("消息".getBytes())); api.postToConnection(post);` 您好!前几天我开始玩AWS WebSocket API Gateway,我目前正在使用Map,如下: public class Handler implements RequestHandler, String> @Override public String handleRequest(Map 事件, 上下文上下文) logger.info("EVENT: ", event);输入效果很好,但是输出是我想要自定义的。通过使用 json 作为字符串不能按我的意愿工作。希望对你有帮助

以上是关于如何为 API Gateway Websocket 编写 Java Lambda 处理程序?的主要内容,如果未能解决你的问题,请参考以下文章