如何为 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 处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 AWS API Gateway Custom Authorizer 提供 Lambda 权限?

如何为我的 API 和我的 websocket 设置路由

如何为 CORS 预检请求绕过 AWS API Gateway 代理资源上的 Cognito 授权方?

从 VPC 内将“禁止”异常发布到 API Gateway Websocket API

通过 HTTP 集成从 AWS Api Gateway 中的 websocket 提取 websocket 连接 ID 和其他详细信息

Cloud Endpoint 和 API Gateway (GCP) 是不是支持 Websocket?