无法为GraphQL订阅建立websocket连接



我正试图在服务器上实现一个基于GraphQLWebSocket的@subscription(使用NestJS@subscriptive(。服务器托管在AWS ECS上,位于ALB后面。我们目前有一个AWS API GW连接通过VPC链接到我们的ALB。

我尝试用我们在HTTP API GW中使用的VPC链接来构建一个专用的Websocket API GW。我还尝试在我们的ECS上启动一个新的NLB(网络负载平衡器(,并在专用的Websocket API GW中使用一个新RESTVPC链接。

客户端和服务器使用graphql-ws库通过graphql-transport-ws子协议进行通信,并且通信在localhost设置上运行良好。

当在本地主机上运行以下命令时,我能够建立web套接字连接:

wscat -c ws://localhost:3000/graphql -s graphql-transport-ws

当针对WebSocket API GW URL 运行相同程序时

wscat -c wss://*****.execute-api.*****.amazonaws.com/**** -s graphql-transport-ws

我得到了这个:error: Server sent no subprotocol

该错误表明子协议有问题,因此当删除子协议时,将建立连接,并得到提示:

Connected (press CTRL+C to quit)
>

然而,没有到达服务器的指示,而且似乎只通过WebSocket API GW本身进行连接。

当我绕过网关并直接连接面向互联网的NLB时,我能够建立WebSocket连接。

我不是超级Websocket专家,但我知道Websocket连接将被API网关终止,不能用作连接传递。您可以使用AWS_PROXY集成将web套接字事件转发到graphQL服务器后端,但这不是一个维护的直接连接-API网关终止,事件指向后端集成,并且不会将集成响应返回到WebSocket,因为它是事件驱动的,而不是面向连接的服务-因此您看到的"错误:服务器未发送子协议"。

因此,要使用API GW作为WebSocket层,您需要在某个位置构建连接管理功能,以管理APIGW的基于事件的特性,并向APIGW连接发送数据,或者调整graphql服务器内的集成机制,以利用@connection功能向WebSocket消费者发送响应/通知。

  • 集成后端服务文档:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-routes-integrations.html
  • 向连接的客户端发送响应:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html

API GW Websockets非常适合构建自定义解决方案,但需要付出一些努力,因为您将配置事件的设置。

对于AWS上的GraphQL API,我建议您看看AppSync,这是一种AWS托管GraphQL服务,它通过WebSockets本地处理GraphQL订阅,无需任何额外代码,而且它具有高度可扩展性,可以简化基于ECS的解决方案的GraphSQL托管负担。

我怀疑可能还有很多其他原因需要在ECS上使用现有的GraphQL进行构建,所以要理解,并非总是可以转向像AppSync这样的东西。我觉得你尝试的NLB解决方案在现有的ECS后端环境中是可以的,正如你所指出的,它是面向连接的(通过NLB(,所以会达到你想要的结果。

最新更新