Amazon web services 在$connect路由中使用apigwManagementApi.postToConnection失败
我想在客户端连接到aws websocket之后将connectionId返回到客户端 我正在使用apigwManagementApi.postToConnection向客户端发送响应,但我总是收到一条荒谬的错误消息 我已经尝试在谷歌上调试和搜索,但我找不到解决方案 patch.jsAmazon web services 在$connect路由中使用apigwManagementApi.postToConnection失败,amazon-web-services,websocket,aws-lambda,aws-api-gateway,Amazon Web Services,Websocket,Aws Lambda,Aws Api Gateway,我想在客户端连接到aws websocket之后将connectionId返回到客户端 我正在使用apigwManagementApi.postToConnection向客户端发送响应,但我总是收到一条荒谬的错误消息 我已经尝试在谷歌上调试和搜索,但我找不到解决方案 patch.js require('aws-sdk/lib/node_loader'); var AWS = require('aws-sdk/lib/core'); var Service = AWS.Service; var a
require('aws-sdk/lib/node_loader');
var AWS = require('aws-sdk/lib/core');
var Service = AWS.Service;
var apiLoader = AWS.apiLoader;
apiLoader.services['apigatewaymanagementapi'] = {};
AWS.ApiGatewayManagementApi = Service.defineService('apigatewaymanagementapi', ['2018-11-29']);
Object.defineProperty(apiLoader.services['apigatewaymanagementapi'], '2018-11-29', {
get: function get() {
var model = {
"metadata": {
"apiVersion": "2018-11-29",
"endpointPrefix": "execute-api",
"signingName": "execute-api",
"serviceFullName": "AmazonApiGatewayManagementApi",
"serviceId": "ApiGatewayManagementApi",
"protocol": "rest-json",
"jsonVersion": "1.1",
"uid": "apigatewaymanagementapi-2018-11-29",
"signatureVersion": "v4"
},
"operations": {
"PostToConnection": {
"http": {
"requestUri": "/@connections/{connectionId}",
"responseCode": 200
},
"input": {
"type": "structure",
"members": {
"Data": {
"type": "blob"
},
"ConnectionId": {
"location": "uri",
"locationName": "connectionId"
}
},
"required": [
"ConnectionId",
"Data"
],
"payload": "Data"
}
}
},
"shapes": {}
}
model.paginators = {
"pagination": {}
}
return model;
},
enumerable: true,
configurable: true
});
module.exports = AWS.ApiGatewayManagementApi;
index.js
const AWS = require('aws-sdk');
require('./patch.js');
exports.handler = async(event) => {
const connectionId = event.requestContext.connectionId;
const apigwManagementApi = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: event.requestContext.domainName + '/' + event.requestContext.stage
});
await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: connectionId }).promise();
return {};
};
client.js
const WebSocket = require('ws');
const ws = new WebSocket('wss://****');
ws.on('open', () => {
console.log('connected ===================>')
ws.on('message', data => console.warn(`From server: ${data}`));
});
cloudwatch中的错误
{
"errorMessage": "410",
"errorType": "UnknownError",
"stackTrace": [
"Object.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:48:27)",
"Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/rest_json.js:52:8)",
"Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)",
"Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)",
"Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)",
"Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
"AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
"/var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
"Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
"Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)"
]
}
{
“errorMessage”:“410”,
“errorType”:“未知错误”,
“stackTrace”:[
“Object.extractError(/var/runtime/node_modules/aws sdk/lib/protocol/json.js:48:27)”,
“Request.extractError(/var/runtime/node_modules/aws sdk/lib/protocol/rest_json.js:52:8)”,
“Request.callListeners(/var/runtime/node_modules/aws sdk/lib/sequential_executor.js:105:20)”,
“Request.emit(/var/runtime/node_modules/aws sdk/lib/sequential_executor.js:77:10)”,
“Request.emit(/var/runtime/node_modules/aws sdk/lib/Request.js:683:14)”,
“Request.transition(/var/runtime/node_modules/aws sdk/lib/Request.js:22:10)”,
“AcceptorStateMachine.runTo(/var/runtime/node_modules/aws sdk/lib/state_machine.js:14:12)”,
“/var/runtime/node_modules/aws sdk/lib/state_machine.js:26:10”,
“请求。(/var/runtime/node_modules/aws sdk/lib/Request.js:38:9)”,
“请求。(/var/runtime/node_modules/aws sdk/lib/Request.js:685:12)”
]
}
我不知道为什么,但如果我尝试在一个自定义的路线,这段代码可以工作。
有人知道如何解决这个问题吗?我发现实现这一点的唯一方法是使用DynamoDB表存储连接,然后设置一个从该表返回Lambda函数的触发器 不过也有一些陷阱。这个Lambda函数不会像上面的index.js文件那样工作。您必须使用NPM安装——将aws sdk与index.js文件保存在一个文件夹中,将其压缩并上载到lambda函数,以便sdk本地化 您还需要设置一个具有正确访问权限的用户,并将凭据放入您的Lambda函数中 注意,如果您看到410错误,这意味着连接不再存在,因此您在该点上的方向是正确的
const AWS = require('aws-sdk');
require('./patch.js');
var log = console.log;
AWS.config.update({
accessKeyId: "YOURDATAHERE",
secretAccessKey: "YOURDATAHERE"
});
let send = undefined;
function init() {
const apigwManagementApi = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: "HARDCODEYOURENDPOINTHERE"
});
send = async (connectionId, data) => {
await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: `${data}` }).promise();
}
}
exports.handler = async (event, context) => {
init();
console.log('Received event:', JSON.stringify(event, null, 2));
for (const record of event.Records) {
//console.log(record.eventID);
console.log(record.eventName);
console.log('DynamoDB Record: %j', record.dynamodb);
if(record.eventName == "INSERT"){
var connectionId = record.dynamodb.NewImage.connectionId.S;
try{
await send(connectionId, connectionId);
}catch(err){
log("Error", err);
}
log("sent");
}
}
return `Successfully processed ${event.Records.length} records.`;
};
我建议查看AWS中的示例,有用于子策略确认的on connect响应,但我认为可以提供任何有效负载。
最重要的一点是模板中的管线集成设置,基本上是管线集成属性中的以下两行:
IntegrationMethod: POST
ConnectionType: INTERNET
然后将响应发送到连接的客户端。哇,我确实在尝试做同样的事情。我的直觉是$connect路由在实际连接完全建立之前可用,这意味着任何向该连接发送邮件的尝试都将失败。你有没有想过解决这个错误的方法?