使用AWS的API Gateway实现websocket

article/2025/11/1 14:12:20

问题

最近业务上面需要使用到WebSocket长连接来解决某些业务场景。

一图胜千言

AWS API Gateway WebSocket
注意:这里承担WebSocket服务器的是AWS API Gateway;后面的EC2业务服务,其实都是REST接口服务。
这里主要关注API Gateway和REST业务服务怎么实现API Gateway要求的WebSocket协议。VPCLink,ELB和Auto Scaling不是我们的重点。这里假设这些都已经完成了。

初始化网关

选择【构建】,如下图:
websocket构建
设置网关名称,类似如下图:
设置网关名称
全部选择3种路由,如下图:
网关路由选择
集成方式暂时选择mock方式:
网关mock集成
阶段,随便填个名称:
网关阶段
预览一下,即将创建的空websocket网关:
websocket网关预览

网关事件

初始化完成部署后,进入网关会出现如下图:
初始化网关3种路由

路由选择表达式

$request.body.action:这个表示客户端与网关通过ws方式连接上后,可以向网关发送json数据来触发网关来进行路由调用。这里的action就是被选中路由资源的关键字段而已。类似发送这样:

{"action": "getList"
}

接下来介绍默认自带的三种路由:
$connect:表示客户端通过ws方式与网关进行了连接;
$disconnect:表示ws连接中断;
$default:如果客户端发送过来的消息不是json方式,默认就这这个路由。
一般来说,前两个都需要集成后台业务程序进行相关处理;最后一个默认根据业务情况来定,我这里不需要业务程序处理。
接下来介绍前2种路由的集成配置。

$connect路由事件

connect路由配置
上面是该事件的主体配置。接下来我们先看集成请求是怎么配置的?

集成请求

connect集成请求配置
这里选择vpclink方式对后台业务程序进行集成。这里值得关注的是请求集成模板参数如下:
模板选择表达式:\$default
模板密钥名称:$default
生成模板内容:

{"connectionId": "$context.connectionId","payload": $input.body
}

这样后台业务程序,就能够读取到connectionId和payload,这两个字段。业务程序类似如下:

   @PostMapping("/connect")public R connect(@RequestBody WebsocketConn websocketConn) {// 记录connectionIdString connectionId = websocketConn.getConnectionId();log.info(String.format("WebSocket ID: %s 上线", connectionId));redisRepository.setExpire(String.format("%s:%s", TokenConstant.WEBSOCKET_API_ID_PREFIX, connectionId),connectionId, TokenConstant.SESSTION_API_TOKEN_EXPIRE);return R.status(true);}

这段Java代码主要就是实现connect接口,将aws api gateway的ws连接ID保存到redis里面,然后,返回200给api gateway。

集成响应

集成响应配置
这里集成响应配置,主要就是添加响应$default

$disconnect路由事件

disconnect事件主要配置
上图就是disconnect路由事件的主要配置,只要配置一个集成请求就完事了。

集成请求

集成请求
集成请求事件如上图。
这里选择vpclink方式对后台业务程序进行集成。这里值得关注的是请求集成模板参数如下:
模板选择表达式:\$default
模板密钥名称:$default
生成模板内容:

{"connectionId": "$context.connectionId"
}

这样后台业务程序,就能够读取到connectionId,这两个字段。业务程序类似如下:

   @PostMapping("/disconnect")public R disconnect(@RequestBody WebsocketConn websocketConn) {// 移除connectionIdString connectionId = websocketConn.getConnectionId();log.info(String.format("WebSocket ID: %s 下线", connectionId));redisRepository.del(String.format("%s:%s", TokenConstant.WEBSOCKET_API_ID_PREFIX, connectionId));return R.status(true);}

这段Java代码主要就是实现disconnect接口,将aws api gateway的ws连接时保存的连接ID从redis里面移除,然后,返回200给api gateway。

$default路由事件

default路由配置
以上是default路由配置事件。

集成请求

集成请求配置
这里选择mock方式,不需要与后台业务程序集成。这里值得关注的是请求集成模板参数如下:
模板选择表达式:\$default
模板密钥名称:$default
生成模板内容:

{"statusCode": 200
}

部署网关

部署网关
将API Gateway部署到阶段里面去。

查看阶段

阶段
从阶段可以看到两种URL,第一种就是通过ws协议进行连接到URL,第二种就是操作这个API Gateway的接口。

推送消息(Java SDK)

Maven

<dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-core</artifactId><version>1.12.348</version>
</dependency><!-- AWS API Gateway -->
<dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-apigatewaymanagementapi</artifactId><version>1.12.348</version>
</dependency>

ApiGatewayConfig.java(Spring配置类)

package org.xxxx.config;import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApiAsync;
import com.amazonaws.services.apigatewaymanagementapi.AmazonApiGatewayManagementApiAsyncClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ApiGatewayConfig {@Value("${api.gateway.endpoint}")private String endpoint;@Value("${region.name:cn-north-1}")private String regionName;@Beanpublic AmazonApiGatewayManagementApiAsync amazonApiGatewayManagementApi() {Region region = Regions.getCurrentRegion();if (region != null){regionName = region.getName();}AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, regionName);return AmazonApiGatewayManagementApiAsyncClientBuilder.standard().withEndpointConfiguration(endpointConfiguration).withCredentials(DefaultAWSCredentialsProviderChain.getInstance()).build();}
}

注意:这里的EC2运行角色需要设置api gateway调用权限类似:AmazonAPIGatewayInvokeFullAccess,也可以根据情况进行自定义权限设置。

推送消息

    @Overridepublic void pushAllFromMessage(String message) {Set<String> keys = redisRepository.getListKey(TokenConstant.WEBSOCKET_API_ID_PREFIX);if (!CollectionUtils.isEmpty(keys)){for (String key : keys) {String connectionId = (String) redisRepository.get(key);PostToConnectionRequest postToConnectionRequest = new PostToConnectionRequest();postToConnectionRequest.withConnectionId(connectionId);ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes());byteBuffer = byteBuffer.duplicate();postToConnectionRequest.withData(byteBuffer);amazonApiGatewayManagementApi.postToConnectionAsync(postToConnectionRequest);}}}

这里主要使用postToConnectionAsync方法进行消息推送,注意这里的ByteBuffer的使用,是需要调用duplicate方法的。

测试

安装wscat客户端:

npm install -g wscat

使用wscat连接上去,即可接收消息推送了。

wscat -c wss://aabbccddee.execute-api.cn-north-1.amazonaws.com.cn/test

总结

到这里就完成了AWS API Gateway中使用websocket的功能。注意,我们的业务程序不要集成任何websocket库,只用正常的restful方式实现aws要求的那个几个路由事件接口即可。再集成api gateway相关的sdk就可以对websocket连接进行管理了。

参考:

  • AWS API Gateway - WebSocket API + EC2 (HTTP & VPC Link & Auth & API Keys & Lambda Authorizer)
  • awsapigw-ws-springboot
  • AmazonApiGatewayManagementApi
  • 使用 IAM 授权
  • 使用 wscat 连接到 WebSocket API 并向其发送消息

http://chatgpt.dhexx.cn/article/SKuEcPTy.shtml

相关文章

使用API Gateway

使用API Gateway 转自&#xff1a;http://www.open-open.com/lib/view/open1436089902667.html 它讨论了采用微服务的优点和缺点&#xff0c;除了一些复杂的微服务&#xff0c;这种模式还是复杂应用的理想选择。 当你决定将应用作为一组微服务时&#xff0c;需要决定应用客户端…

aws api gateway 创建

在这个章节中&#xff0c;你将创建一个无服务器API。无服务器API让你专注于你的应用&#xff0c;而不是花时间配置和管理服务器。 首先&#xff0c;你使用AWS Lambda控制台创建一个Lambda函数。接下来&#xff0c;你使用API网关控制台创建一个HTTP API。然后&#xff0c;你调用…

微服务实践(二):使用API Gateway

【编者的话】本系列的第一篇介绍了微服务架构模式。它讨论了采用微服务的优点和缺点&#xff0c;除了一些复杂的微服务&#xff0c;这种模式还是复杂应用的理想选择。 点击这里获取云原生干货 当你决定将应用作为一组微服务时&#xff0c;需要决定应用客户端如何与微服务交互。…

AWS API GATEWAY的使用

AWS API GATEWAY 文章目录 1、Create Vpc endpoint2、Target Groups与Load Balancer2.1、Create target type为Instances的Target Groups2.2、Create Application Load Balancer2.3、Create target type为Application Load Balancer的Target Groups2.4、Create Network Load Ba…

API Gateway简介

Amazon API Gateway可以让开发人员创建、发布、维护、监控和保护任何规模的API。你可以创建能够访问 AWS、其他 Web 服务以及存储在 AWS 云中的数据的API。 API Gateway没有最低使用成本&#xff0c;我们用多少服务内容就花费多少。 比如在最新的A Cloud Guru的serverless 会…

API Gateway介绍

使用微服务架构开发应用后&#xff0c;每个微服务都将拥有自己的API&#xff0c;设计应用外部API的任务因客户端的多样性而变得更具有挑战性。不同客户端通常需要不同的数据。通常基于PC浏览器的用户界面显示的信息要远多于移动设备的用户界面。此外&#xff0c;不同的客户端通…

API 网关 ( API gateway )

前言 在 IOT &#xff08; 物联网 &#xff09;中&#xff0c;当我们的一些设备。例如&#xff08; 监控、传感器等 &#xff09;需要将收集到的数据和信息进行汇总时&#xff0c;我们就需要一个 API 网关来接收从千百个终端发出的请求&#xff0c;它实现对外统一接口&#xf…

【学习笔记】API网关(GateWay)

项目场景 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 微服务将一个大型工程转成了诺干个微服务&#xff0c;每个微服务都是一个独立的项目因此每一个项目都有不同的端口&#xff0c;那我们怎样在前端发送请求的时候能精确的发送到我们所需要的服务里。 提…

APIGateway简介

综合了一下网上的APIGateway教学&#xff0c;总结了一下&#xff08;所有图片来源于网络&#xff09;: 目录 1.什么是APIGateway 2.APIGateway的作用 3.APIGateway的重要功能 1.什么是APIGateway APIGateway 即API网关是一个服务器&#xff0c;所有请求首先会经过这个网关…

java 中 ajax 的学习

1、原生 ajax 实现 首先在 web 工程下创建一个 .jsp 文件&#xff0c;用来与前台 ajax 进行数据传递 在创建的 .jsp 文件中->引入 jquery-1.8.3.min.js 文件&#xff08;可直接粘贴至 web 目录下&#xff0c;也可新建一个 js 文件夹&#xff0c;然后粘贴进去&#xff09; …

Java要学到什么程度?

在刚开始学习Java的同学都关心这么一个问题&#xff1a;到底把Java学到何种程度才能找到第一份工作呢&#xff1f;大部分人的目标是一致的&#xff0c;也比较现实&#xff0c;都是为了能找到像别人高薪的工作。那到底一个Java初学者要学多少Java知识&#xff0c;才能找到第一份…

学了python再学java要多久,有java基础学python要多久

python的学习难度如何&#xff0c;已经掌握java的话&#xff0c;想学习python批量处理文件的脚本&#xff0c;大概需要多长时间&#xff1f; 谷歌人工智能写作项目&#xff1a;小发猫 学会python大概要多久&#xff1f; 系统的学习&#xff0c;大概6个月就够了vue哪个版本支持…

自学Java开发一般需要多久?

自学Java开发一般需要多久&#xff1f;相信有很多想转行或者想学习Java的人都会关注这个问题&#xff01;那我们今天就来说一下这个问题&#xff0c;具体需要多久呢&#xff1f;这个时间因人而异&#xff0c;毕竟每个人的学习能力和效率都是不同的&#xff01; 打个比方&#x…

Java后端学习路线分享

Java后端学习路线&#xff1f;最近有些网友问我如何学习 Java 后端&#xff0c;还有些是想从别的方向想转过来&#xff0c;但都不太了解 Java 后端究竟需要学什么&#xff0c;究竟要从哪里学起&#xff0c;哪些是主流的 Java 后端技术等等&#xff0c;导致想学&#xff0c;但又…

老Java程序员谈谈swing要不要学

老Java程序员谈谈Swing要不要学 老java程序员谈谈要不要学swing Swing是什么&#xff1f; 1&#xff09;AWT 在早期JDK1.0发布时&#xff0c;Sun公司就为GUI开发提供了一套基础类库&#xff0c;这套类库被称为AWT(Abstract Window Toolkit)&#xff0c;即抽象窗口工具包。AWT…

学习Java一般多久?

学习Java一般多久&#xff1f;Java作为编程界应用最广泛的编程语言之一&#xff0c;另外Java开发薪资、工作环境、发展前景让大家都争先想进入Java开发工程师的行列。学习Java一般多久是Java初学者十分关心的问题&#xff0c;但是这些问题并没有一个明确的答案&#xff0c;毕竟…

史上最强 Java 学习路线图!

网上看到一首诗&#xff1a;“代码尽头谁为峰&#xff0c;一见秃头道成空。编程修真路破折&#xff0c;一步一劫渡飞升。”感觉还挺有意境的。 第一部分&#xff1a;Java 基础篇 这个阶段就是编程入门&#xff0c;掌握 Java 这门编程语言的基本语法&#xff0c;为后面的修行之…

Java自学需要学多久?学习路线是怎样的?别慌这里都整理好了

学java一般要多久&#xff1f; 因人而异&#xff0c;例如一个零基础的小白自学java&#xff0c;每天学习8个小时来算&#xff0c;而且在有学习资料的基础上&#xff0c;每天学习&#xff0c;从零到找到工作&#xff0c;起码要半年起步&#xff0c;而且还要有项目经验&#xff…

Java学习需要多久?程序员学习指南

要知道Java学习没有终点&#xff0c;Java在不断地更新发展&#xff0c;所以我们也需要不断学习&#xff0c;让自己不落到后面。 学习Java的时间因人而异&#xff0c;有的人学的快&#xff0c;有得人学的慢&#xff0c;一切都看自己的节奏来&#xff0c;不要心急觉得自己学的慢&…

学习java一般多久

Java作为编程语言中的常青树&#xff0c;二十多年来一直立于不败的地位&#xff0c;没有人一直学java&#xff0c;但一直有人在学java。但对于一些时间不充裕却又想学java的小伙伴来说有一个问题至关重要&#xff0c;那就是&#xff1a;学习java一般多久。若想要知道答案&#…