簡體   English   中英

AWS API 網關 Websocket 未知錯誤

[英]AWS API Gateway Websocket UnknownError

我們在執行 SDK postToConnection()調用時遇到錯誤作為承諾,下面給出了完整的錯誤詳細信息。 具有不同連接 ID 的同一函數中的其他調用成功發生。 預期的 410 連接錯誤在幾毫秒內正確發生,並且得到妥善處理。

然后,此錯誤需要 40 秒到一分鍾以上的時間才能返回,這導致它始終在 Web 套接字 API 中導致“端點請求超時”錯誤,因為它有 30 秒的最大請求超時。 之前有沒有人遇到過這個問題和/或實施過任何解決方案? 任何解決此問題的想法將不勝感激,謝謝。

UnknownError:網絡錯誤與 Object.extractError 端點通信(/opt/nodejs/node_modules/aws-sdk/lib/protocol/json.js:51:27)

你想在連接處理程序中使用 postToConnection 嗎? websocket 連接僅在連接處理程序返回 statusCode 200創建。您不應在連接處理程序內使用 postToConnection。

為避免在無服務器上使用 websockets 時出現 410 問題,請不要忘記捕獲異常:

export const ApiGatewayConnector = (event) => {

  const endpoint = process.env.IS_OFFLINE
            ? 'http://localhost:3001'
            : `${event.requestContext.domainName}/${event.requestContext.stage}`
            const apiVersion = '2018-11-29'
            return new AWS.ApiGatewayManagementApi({ apiVersion, endpoint })
}

....

if (event.requestContext.stage == 'local') {
              await ApiGatewayConnector(event)
              .postToConnection({ ConnectionId, Data })
              .promise()
              .catch(_ => removeId(ConnectionId));<----- N.B. Remove disconnected IDs
            } else {
              await ws.send(Data, ConnectionId)
            }
}
        

在調用 .postToConnection 以響應 $connect 事件時會拋出該錯誤。 您可以調用 .postConnection 而不會錯誤地回答 $default 事件。

// index.js
// the handler is defined as: index.handler

const AWS = require("aws-sdk");

exports.handler = function (event, context, callback) {

    console.log('event.requestContext.eventType', event && event.requestContext && event.requestContext.eventType)

    if (event.requestContext.eventType === "CONNECT") {

        console.log('$connect event')

        // calling apigwManagementApi.postToConnection will throw an exception

        callback(null, {
            statusCode: 200,
            body: "Connected"
        });

    } else if (event.requestContext.eventType === "DISCONNECT") {

        console.log('$disconnect event')

        // calling apigwManagementApi.postToConnection is pointless since the client has disconneted

        callback(null, {
            statusCode: 200,
            body: "Disconnected"
        });
    } else {

        console.log('$default event')

        const ConnectionId = event.requestContext.connectionId
        const bodyString = event.body
        const Data = bodyString

        const apigwManagementApi = new AWS.ApiGatewayManagementApi({
            apiVersion: "2018-11-29",
            endpoint: event.requestContext.domainName + "/" + event.requestContext.stage
        });

        apigwManagementApi
        .postToConnection({ ConnectionId, Data })
        .promise().then(() => {

            callback(null, {
                statusCode: 200,
                body: "Disconnected"
            });

        })

    }

};

不確定這是否遵循最佳實踐,但我能夠在connect處理程序中使用postToConnection (通過在啟動postToConnection之前調用callback

exports.handler = async (event, context, callback) => {
  try {
    const {
      body = '{}',
      requestContext: { apiId, connectionId, routeKey, stage },
    } = event;

    const apigwManagementApi = new ApiGatewayManagementApi({
      endpoint: 'local' === stage ? `http://localhost:4002` : `https://${apiId}.execute-api.${process.env.AWS_REGION}.amazonaws.com/${stage}`,
    });

    switch(routeKey) {
      case '$connect':

        // call callback to create connection
        callback(null, {
          statusCode: 200,
          body: "Connected"
        });

        await apigwManagementApi.postToConnection({
          ConnectionId: connectionId,
          Data: JSON.stringify({
            action: 'test-message'
          }),
        }).promise();

        break;
      case '$disconnect':
        console.log('DISCONNECT');
        break;
      default:
        console.log('DEFAULT');
        break;
    }

    return { statusCode: 200 };
  } catch (error) {
    console.log('Got error', error)
  }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM