Я пытаюсь реализовать обмен сообщениями между пользователями на своем веб-сайте, используя шлюз API веб-сокета AWS.В каждом руководстве / документации, на которые я смотрю, говорится, что для проверки соединения со шлюзом используется wscat.Я нахожусь в точке, где я могу подключиться к шлюзу API и отправлять сообщения между клиентами, используя wscat, но изо всех сил пытаюсь заставить его работать программно из моего кода TS.
Что я хочу сделать, это сделать вызов API длякак только пользователь входит в систему, веб-сокет API-шлюза может отправлять сообщения в любой момент.Я использую серверные для моего бэкэнда и Angular 6 для внешнего интерфейса.Я прочитал, что мне нужно сделать POST
запрос на https://{api-id}.execute-api.us-east-1.amazonaws.com/{stage}/@connections/{connection_id}
для отправки сообщений через соединение через веб-сокет, но у меня возникают проблемы с использованием машинописи в сервисе, который я создал для соединения / получения идентификатора соединения.
Я делаю второй вызов API после того, как пользователь успешно вошел в систему, чтобы открыть соединение со шлюзом websocket api.Я попытался вызвать функцию, которая отправляет пост-запрос без тела (не уверен, что я отправлю в теле запроса, так как я подключился к нему только с помощью инструмента wscat) по URL-адресу, который я получаю после развертывания моего бессерверного кода.Я также попытался сделать запрос POST к URL-адресу https: //, который я вижу в консоли AWS после развертывания шлюза API вручную.
base.service.ts
protected getBaseSocketEndpoint(): string {
// 'wss://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev' <-- tried this too
return 'https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/@connections';
}
authentication.service.ts
this.authService.login(username, password).pipe(first()).subscribe(
(response) => {
console.log(response);
this.authService.setCookie('userId', response.idToken.payload.sub);
this.authService.setCookie('jwtToken', response.idToken.jwtToken);
this.authService.setCookie('userEmail', response.idToken.payload.email);
this.authService.setCookie('refreshToken', response.refreshToken.token);
this.toastr.success('Login successful. Redirecting to your dashboard.', 'Success!', {
timeOut: 1500
});
this.authService.connectToWebSocket(response.idToken.payload.sub).pipe(first()).subscribe(
response => {
console.log(response);
}
);
this.routerService.routeToUserDashboard();
},
(error) => {
// const errorMessage = JSON.parse(error._body).message;
this.toastr.error("Incorrect username and password combination.", 'Error!', {
timeOut: 1500
});
}
);
authentication.service.ts extends BaseService
public connectToWebSocket(userId: string): Observable<any> {
const body = {
userId: userId
};
console.log('calling connectToWebSocket()..');
return this.http.post(this.getBaseSocketEndpoint(), body).pipe(map(response => {
console.log(response);
}));
}
serverless.yaml
functions:
connectionHandler:
handler: connectionHandler.connectionHandler
events:
- websocket:
route: $connect
cors: true
- websocket:
route: $disconnect
cors: true
defaultHandler:
handler: connectionHandler.defaultHandler
events:
- websocket:
route: $default
cors: true
sendMessageHandler:
handler: messageHandler.sendMessageHandler
events:
- websocket:
route: sendMessage
cors: true
connectionHandler.js (лямбда)
const success = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: "everything is alright"
};
module.exports.connectionHandler = (event, context, callback) => {
var connectionId = event.requestContext.connectionId;
if (event.requestContext.eventType === "CONNECT") {
addConnection(
connectionId,
"b72656eb-db8e-4f32-a6b5-bde4943109ef",
callback
)
.then(() => {
console.log("Connected!");
callback(null, success);
})
.catch(err => {
callback(null, JSON.stringify(err));
});
} else if (event.requestContext.eventType === "DISCONNECT") {
deleteConnection(
connectionId,
"b72656eb-db8e-4f32-a6b5-bde4943109ef",
callback
)
.then(() => {
console.log("Disconnected!");
callback(null, success);
})
.catch(err => {
callback(null, {
statusCode: 500,
body: "Failed to connect: " + JSON.stringify(err)
});
});
}
};
// THIS ONE DOESNT DO ANYHTING
module.exports.defaultHandler = (event, context, callback) => {
callback(null, {
statusCode: 200,
body: "default handler was called."
});
};
const addConnection = (connectionId, userId, callback) => {
const params = {
TableName: CHATCONNECTION_TABLE,
Item: {
connectionId: connectionId,
userId: userId
}
};
var response;
return dynamo
.put(params, function(err, data) {
if (err) {
errorHandler.respond(err, callback);
return;
} else {
response = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify(data)
};
callback(null, response);
}
})
.promise();
};
const deleteConnection = (connectionId, userId, callback) => {
const params = {
TableName: CHATCONNECTION_TABLE,
Key: {
connectionId: connectionId,
userId: userId
}
};
var response;
return dynamo
.delete(params, function(err, data) {
if (err) {
errorHandler.respond(err, callback);
return;
} else {
response = {
statusCode: 200,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify(data)
};
callback(null, response);
}
})
.promise();
};
Ожидается: вызов API POST и открытие постоянного соединения с шлюзом Websocket API.
Фактически: невозможно подключиться через вызов API выше.Я получаю 403 в консоли с сообщением:
Доступ к XMLHttpRequest по адресу https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/@connections 'изorigin 'http://localhost:4200' было заблокировано политикой CORS: Ответ на запрос предварительной проверки не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок' Access-Control-Allow-Origin '.
Не уверен, почему я получаю ошибку CORS, когда у меня включен CORS в моем файле без сервера.