AWS API Gateway WebSocket API:如何将其与 React / NodeJS / 本机 WebSocket 一起使用?

AWS API Gateway WebSocket API: how to use it with React / NodeJS / native WebSocket?

我正在构建我的应用程序:

前端:ReactJS / Javascript 本机 Websocket: 在我使用 websocket 的组件中:

  useEffect(() => {  
    const orgId = localData.get('currentOrganizationId');
    const username = localData.get('username');

    let socket = new WebSocket(process.env.REACT_APP_WEBSOCKET_URL); // this is the AWS WebSocket URL after I have deployed it. 
    // let socket = new WebSocket("ws://127.0.0.1:3001");
    socket.onopen = function(e) {
      console.log('socket on onopen'); 
      const info = JSON.stringify({orgId:orgId, username: username, action: "message"});
      socket.send(info);
    };

    socket.onmessage = function(event) {
      console.log(`[message] Data received from server: ${event.data}`);
    };
    
    socket.onclose = function(event) {
      if (event.wasClean) {
        console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
      } else {
        console.log(`[close] Connection died; code=${event.code}`);
      }
    };
    
    socket.onerror = function(error) {
      console.log(`[error] ${error.message}`);
    };

  }, [])

后端:NodeJS / ExpressJS / ws websocket 库:

./utils/websocket:

import WebSocket from "ws";
import queryString from "query-string";
import { StateManager } from '../state';
import logger from '../logger';


export default async (expressServer) => {

  StateManager.addToState('sockets', {});

  const websocketServer = new WebSocket.Server({
    noServer: true,
    // path: "/websockets",
    path: "/",
  });

  expressServer.on("upgrade", (request, socket, head) => {
    logger.info(`on upgrade: ${JSON.stringify(head)}`);
    websocketServer.handleUpgrade(request, socket, head, (websocket) => {
      websocketServer.emit("connection", websocket, request);
    });
  });

  websocketServer.on("connection", function connection(websocketConnection, connectionRequest) {
      logger.info(`on connection`);

      websocketConnection.on("message", (message) => {
        const info = JSON.parse(message);
        logger.info(`info: ${typeof info}  ${info}`);
        const sockets = StateManager.readFromState('sockets');
        sockets[info.username] = websocketConnection;
      });

  });

  return websocketServer;
};

并在 index.ts 中:

  import websocket from './utils/websocket';

  ...other code

  const app = express();

  ...other code

  const server = app.listen(parseInt(process.env.PORT) || 3001);  

  websocket(server);

虽然这在本地开发环境中运行良好,但我真的很困惑如何像这样将其移动到 AWS:

前端 WebSocket 客户端 ---> AWS API 网关 Websocket API ----> EC2 实例中的后端

我是这样配置的:

我已经阅读了文档,但我仍然不知道从哪里开始。我应该如何配置 $connect$disconnect$default 路由? 它们与我当前在 EC2 中的 websocket 客户端和 nodejs 服务器有什么关系 运行?

我应该如何更改代码以将其与 AWS API Gateway Websocket API 集成?

目前根本没有回复:

不过我提供的 Websocket URL 确实是正确的。

即使阅读了文档,我仍然不知道从哪里开始解决这个问题。

连接到 websocket 时没有响应的原因是您的后端 express 应用程序中没有设置 HTTP 端点。

当您连接到 AWS API 网关 WebSocket API 时,WebSocket API 会执行您的 $connect 集成设置的操作。在您当前的配置中,您已在目标 url 上设置 VPC Link 与 HTTP Method Any 的集成。因此,要调用您的后端端点,您需要创建一个 HTTP 端点并将端点的地址设置为“Endpoint URL”。“=11=]

例如,假设您设置了以下路线。

app.get('/connect', function(req, res) {
    res.send('success');
});

如果您将 'Endpoint URL' 设置为“/connect”,您将在连接到 WebSocket 时收到 'success'。

简而言之,您不需要 运行 在后端连接 websocket 服务器,因为 WebSocket API 会处理它。通过路由集成,您只需要设置如何根据通过 WebSocket 发送的消息调用不同的方法(由后端 Node.js 服务器的 HTTP 端点提供)。

作为旁注,我建议使用以下选项之一。

  1. 如果您需要 运行 自己的后端,请不要使用 AWS API Gateway WebSocket API 因为没有必要。您可以改用 AWS ALB。
  2. 如果您不需要 运行 自己的后端并且功能不是太复杂,请使用 AWS Lambda 与 WebSocket 的集成 API 并采用无服务器实时功能。 -- 编辑(基于评论的另一个建议)--
  3. 如果您需要使用 API 网关,您可以在 Node.js 后端设置 HTTP 端点,并将其集成到 WebSocket API $connect 集成中。然后,您集成的 HTTP 端点将在连接时被调用。