Websocket with API Gateway AWS | Websocket con API Gateway AWS
Ejemplo de implementación de Websocket con API Gateway de AWS.
Cloudformation:
AWSTemplateFormatVersion: '2010-09-09'
#Transform: AWS::Serverless-2016-10-31
Description: websockets to notify to the frontend.
Parameters:
WebSocketName:
Description: Websocket name
Type: String
Resources:
WebSocket:
Type: AWS::ApiGatewayV2::Api
Properties:
Name: !Sub ${WebSocketName}
ProtocolType: WEBSOCKET
RouteSelectionExpression: "$request.body.action"
Description: "Mock WebSocket API Gateway."
ConnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocket
RouteKey: $connect
#RouteResponseSelectionExpression: '$default'
AuthorizationType: NONE
OperationName: ConnectRoute
Target: !Join
- '/'
- - 'integrations'
- !Ref ConnectInteg
ConnectInteg:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocket
Description: Connect Integration
IntegrationType: AWS_PROXY
IntegrationUri:
Fn::Sub:
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:register-conection-websocket-http/invocations
DisconnectRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocket
RouteKey: $disconnect
AuthorizationType: NONE
OperationName: DisconnectRoute
Target: !Join
- '/'
- - 'integrations'
- !Ref DisconnectInteg
DisconnectInteg:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocket
Description: Disconnect Integration
IntegrationType: AWS_PROXY
IntegrationUri:
Fn::Sub:
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:register-conection-websocket-http/invocations
DefaultRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocket
RouteKey: $default
AuthorizationType: NONE
OperationName: DefaultRoute
Target: !Join
- '/'
- - 'integrations'
- !Ref DefaultInteg
DefaultInteg:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocket
Description: Default Integration
IntegrationType: AWS_PROXY
IntegrationUri:
Fn::Sub:
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:default-websocket-http/invocations
GetConnectionRoute:
Type: AWS::ApiGatewayV2::Route
Properties:
ApiId: !Ref WebSocket
RouteKey: getConnectionId
AuthorizationType: NONE
OperationName: GetConnectionRoute
Target: !Join
- '/'
- - 'integrations'
- !Ref GetConnectionInteg
GetConnectionInteg:
Type: AWS::ApiGatewayV2::Integration
Properties:
ApiId: !Ref WebSocket
Description: Get Connection Integration
IntegrationType: AWS_PROXY
IntegrationUri:
Fn::Sub:
arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:get-connection-websocket-http/invocations
Deployment:
Type: AWS::ApiGatewayV2::Deployment
DependsOn:
- ConnectRoute
- DefaultRoute
- DisconnectRoute
- GetConnectionRoute
Properties:
ApiId: !Ref WebSocket
Stage:
Type: AWS::ApiGatewayV2::Stage
Properties:
StageName: default
Description: None
DeploymentId: !Ref Deployment
ApiId: !Ref WebSocket
Lambdas:
lambda name: default-websocket-http
async function(event, context) {
return;
}
lambda name: get-connection-websocket-http
async function(event, context) {
const connectionId = event.requestContext.connectionId;
const domainName = event.requestContext.domainName;
const message = JSON.stringify({
statusCode: 200,
body: {
code: 'CONNECTION_ID',
connectionId: connectionId,
}
});
const apigwManagementApi = new AWS.ApiGatewayManagementApi({ apiVersion: "2018-11-29", endpoint: domainName });
const params = {
ConnectionId: connectionId,
Data: message,
};
await apigwManagementApi.postToConnection(params).promise();
}
lambda name: register-conection-websocket-http
async function(event, context) {
const connectionId = event.requestContext.connectionId;
const domainName = event.requestContext.domainName;
const eventType = event.requestContext.eventType;
if (eventType === 'CONNECT') {
// save connection in dynamodb
await putConnection(input.connectionId, domainName);
} else if (input.eventType === 'DISCONNECT') {
// delete connection in dynamodb
deleteConnection(input.connectionId);
}
}
lambda name: send-notification-http
async function(event, context) {
const connectionId = event.requestContext.connectionId;
const domainName = event.requestContext.domainName;
const eventType = event.requestContext.eventType;
//Buscar en Dynamodb
const connections = getConnectionsToNotify();
if (connections && connections.length > 0) {
for (const connection of connections) {
const message = JSON.stringify({
statusCode: 200,
body: {
code: 'CONNECTION_ID',
connectionId: connectionId,
}
});
const apigwManagementApi = new AWS.ApiGatewayManagementApi({ apiVersion: "2018-11-29", endpoint: domainName });
const params = {
ConnectionId: connectionId,
Data: message,
};
await apigwManagementApi.postToConnection(params).promise();
}
}
}
const socket = new WebSocket("wss://${ID_API}.execute-api.us-east-1.amazonaws.com/default");
socket.onopen = function (e) {
console.log("[open] Connection established", e);
socket.send(JSON.stringify({
action: "getConnectionId"
}))
};
socket.onmessage = function (event) {
console.log(`[message] Data received from server: ${event.data}`);
const data = JSON.parse(event.data);
};
Comentarios
Publicar un comentario