【以下的问题经过翻译处理】 我使用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}"
};
}