【问题标题】:AWS API Gateway WebSocket API: how to use it with React / NodeJS / native WebSocket?AWS API Gateway WebSocket API:如何与 React / NodeJS / native WebSocket 一起使用?
【发布时间】:2022-01-12 10:32:16
【问题描述】:

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

前端:ReactJS / Javascript Native 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 Gateway Websocket API ----> EC2 实例中的后端

我的配置是这样的:

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

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

目前根本没有回应:

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

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

【问题讨论】:

    标签: node.js reactjs amazon-web-services websocket aws-api-gateway


    【解决方案1】:

    连接websocket时没有响应的原因是你的后端快递应用程序中没有设置HTTP端点。

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

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

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

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

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

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

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

    【讨论】:

    • 感谢您的精彩回答!我想我会选择选项 1。但是,您提到使用 AWS ALB - 我需要在 EC2 实例中运行我自己的 Express API 后端,但我还必须将它放在 AWS API 网关后面,以便 API 网关充当我的后端 API 的单点入口,而不是 ALB。我已经在 AWS API Gateway 中配置了一个 Restful API。我不确定它是否也能覆盖 websocket。
    • 我明白了。在这种情况下,您只需在 Node.js 后端设置 HTTP 端点,并将其集成到 WebSocket API $connect 集成中。然后,您集成的 HTTP 端点将在连接时被调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2022-08-15
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    相关资源
    最近更新 更多