未找到 API 网关 WSS Endpoint

0

【以下的问题经过翻译处理】 我使用AWS的.NET Lambda模板中的示例创建了一个WSS聊天应用程序。我的Web前端可以连接正常,并且它在Dynamo中创建了一条记录,但是当我尝试广播消息给所有连接时,我收到了以下错误:

`Name or service not known (execute-api.ap-southeast-2.amazonaws.com:443) `

我正在使用以下代码进行设置:

var protocol = "https";
  //var protocol = "wss";
  
  var domainName = request.RequestContext.DomainName;
  //var domainName = "ID HERE.execute-api.ap-southeast-2.amazonaws.com";
  
  var stage = request.RequestContext.Stage;
  // var stage = "";
  //var stage = "test";
  //var stage = "test/@connections";
  
  var endpoint = $"{protocol}://{domainName}/{stage}";

并记录如下内容:

API Gateway management endpoint: https://ID HERE.execute-api.ap-southeast-2.amazonaws.com/test

我尝试了所有的组合,甚至使用了自定义域名。我在这个问题上卡了一段时间了,准备放弃了。有没有人有什么想法??

更新:以下是发送消息的代码 - 它只是示例的更新版本。从启动代码中:

public Functions()
  {
    DDBClient = new AmazonDynamoDBClient();

    // Grab the name of the DynamoDB from the environment variable setup in the CloudFormation template serverless.template
    if (Environment.GetEnvironmentVariable(TABLE_NAME_ENV) == null)
    {
      throw new ArgumentException($"Missing required environment variable {TABLE_NAME_ENV}");
    }

    ConnectionMappingTable = Environment.GetEnvironmentVariable(TABLE_NAME_ENV) ?? "";

    this.ApiGatewayManagementApiClientFactory = (Func<string, AmazonApiGatewayManagementApiClient>)((endpoint) =>
    {
      return new AmazonApiGatewayManagementApiClient(new AmazonApiGatewayManagementApiConfig
      {
        ServiceURL = endpoint,
        
        RegionEndpoint = RegionEndpoint.APSoutheast2, // without this I get Credential errors
        LogResponse = true,  // dont see anything extra with these
        LogMetrics = true,
        DisableLogging = false
      });
    });
  }

然后SendMessageFunction:

try
    {
      // Construct the API Gateway endpoint that incoming message will be broadcasted to.
      var protocol = "https";
      //var protocol = "wss";
      
      var domainName = request.RequestContext.DomainName;
      //var domainName = "?????.execute-api.ap-southeast-2.amazonaws.com";
      
      var stage = request.RequestContext.Stage;
      // var stage = "";
      //var stage = "test";
      //var stage = "test/@connections";
      
      var endpoint = $"{protocol}://{domainName}/{stage}";
      
      context.Logger.LogInformation($"API Gateway management endpoint: {endpoint}");
      
      JObject message = JObject.Parse(request.Body);
      context.Logger.LogInformation(request.Body);


      if (!GetRecipient(message, context, out WSMessageRecipient? recipient))
      {
        context.Logger.LogError($"Invalid or empty WSMessageRecipient");
        return new APIGatewayProxyResponse
        {
          StatusCode = (int)HttpStatusCode.BadRequest, Body = "Nothing to do or invalid request"
        };
      }
      
      if (!GetData(message, context, out string? data))
      {
        context.Logger.LogError($"Invalid or empty WSSendMessage");
        return new APIGatewayProxyResponse
        {
          StatusCode = (int)HttpStatusCode.BadRequest, Body = "Nothing to do or invalid request"
        };
      }

      var stream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data!));
      
      if (stream.Length == 0)
      {
        context.Logger.LogError($"Empty Stream");
        return new APIGatewayProxyResponse
        {
          StatusCode = (int)HttpStatusCode.BadRequest, Body = "Empty data stream"
        };
      }

      // List all of the current connections. In a more advanced use case the table could be used to grab a group of connection ids for a chat group.
      ScanResponse scanResponse = await GetConnectionItems(recipient);

      // Construct the IAmazonApiGatewayManagementApi which will be used to send the message to.
      var apiClient = ApiGatewayManagementApiClientFactory(endpoint);

      context.Logger.LogInformation($"Table scan of {ConnectionMappingTable} got {scanResponse.Items.Count} records.");
      
      // Loop through all of the connections and broadcast the message out to the connections.
      var count = 0;
      foreach (var item in scanResponse.Items)
      {
        var connectionId = item[ConnectionIdField].S;

        context.Logger.LogInformation($"Posting to connection {count}: {connectionId}");

        var postConnectionRequest = new PostToConnectionRequest
        {
          ConnectionId = connectionId, Data = stream
        };

        try
        {
          stream.Position = 0;
          await apiClient.PostToConnectionAsync(postConnectionRequest);
          context.Logger.LogInformation($"Posted to connection {count}: {connectionId}");
          count++;
        }
        catch (AmazonServiceException e)
        {
          // API Gateway returns a status of 410 GONE then the connection is no
          // longer available. If this happens, delete the identifier
          // from our DynamoDB table.
          if (e.StatusCode == HttpStatusCode.Gone)
          {
            context.Logger.LogInformation($"Deleting gone connection: {connectionId}");
            var ddbDeleteRequest = new DeleteItemRequest
            {
              TableName = ConnectionMappingTable,
              Key = new Dictionary<string, AttributeValue>
              {
                {ConnectionIdField, new AttributeValue {S = connectionId}}
              }
            };

            await DDBClient.DeleteItemAsync(ddbDeleteRequest);
          }
          else
          {
            context.Logger.LogError(
              $"Error posting message to {connectionId}: {e.Message}");
            context.Logger.LogInformation(e.StackTrace);
          }
        }
        catch (Exception ex)
        {
          context.Logger.LogError($"Bugger, something fecked up: {ex.Message}");
          context.Logger.LogInformation(ex.StackTrace);
        }
      }

      return new APIGatewayProxyResponse
      {
        StatusCode = (int)HttpStatusCode.OK, Body = "Data sent to " + count + " connection" + (count == 1 ? "" : "s")
      };
    }
    catch (Exception e)
    {
      context.Logger.LogInformation("Error Sending Message: " + e.Message);
      context.Logger.LogInformation(e.StackTrace);
      return new APIGatewayProxyResponse
      {
        StatusCode = (int)HttpStatusCode.InternalServerError, Body = $"Failed to send message: {e.Message}"
      };
    }
1 Antwort
0

【以下的回答经过翻译处理】 通过在创建 Api 客户端时添加凭证,我解决了这个问题。不要问我为什么 - 我本以为它应该从角色中获取这些:

this.ApiGatewayManagementApiClientFactory = (Func<string, AmazonApiGatewayManagementApiClient>)((endpoint) =>
    {
      AWSCredentials awsCredentials = new EnvironmentVariablesAWSCredentials();
      return new AmazonApiGatewayManagementApiClient(awsCredentials, new AmazonApiGatewayManagementApiConfig
      {
        ServiceURL = endpoint
      });
    });
profile picture
EXPERTE
beantwortet vor 5 Monaten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen