¿Alguna vez has querido que tu app hable con tus usuarios en tiempo real, como por arte de magia? Pues bien, ¡hoy es tu día de suerte! En este post vamos a meternos de lleno en cómo darle súper poderes a tus proyectos usando WebSockets con AWS. Vamos a usar dos herramientas muy conocidas dentro del Cloud de AWS: API Gateway y Lambda. Te voy a llevar paso a paso para que crees tu propio websocket en menos de 10 minutos.
Crear el proyecto con cdk
Vamos a crear el proyecto con cdk y vamos a implementarlo con python, para ello vamos a crear nuestro directorio del proyecto y crearemos el proyecto con cdk
shell
mkdir websocket-poc
cd websocket-poc
cdk init app --language python
Ahora activamos el entorno virtual
shell
source .venv/bin/activate
Y por último instalamos las dependencias necesarias:
shell
pip install -r requirements.txt
Este sería el contenido de nuestro requirements.txt
aws-cdk-lib==2.114.1
constructs>=10.0.0,<11.0.0
Creación de lambda
Usaremos una lambda para enviar un mensaje a través de nuestro websocket, para ello en nuestro proyecto cdk, y dentro de nuestro stack creamos la lambda con el siguiente código:
python
lambda_function = lambda_.Function(
self, 'WebSocketHandler',
runtime=lambda_.Runtime.PYTHON_3_8,
handler='ws_function.handler',
code=lambda_.Code.from_asset('./lambda'),
timeout=core.Duration.seconds(10)
)
lambda_function.add_to_role_policy(iam.PolicyStatement(
actions=["execute-api:ManageConnections"],
resources=["arn:aws:execute-api:REGION:ACCOUNT-ID:API-ID/STAGE-NAME/*"],
effect=iam.Effect.ALLOW
))
execute-api:ManageConnections permite a funciones autorizadas gestionar conexiones de clientes en API Gateway WebSockets.
Y este sería el código de la lambda, bastante sencillo, simplemente recibimos los parámetros de conexión y la url del websocket, esto podría ser fijo, pero en caso que tengamos mas de un websocket podríamos re-utilzar el código de la lambda, y por último, enviamos el mensaje "Hello, WebSocket!"
python
import boto3
def handler(event, context):
connection_id = event['requestContext']['connectionId']
gatewayapi = boto3.client("apigatewaymanagementapi",
endpoint_url = "https://" + event["requestContext"]["domainName"] + "/" + event["requestContext"]["stage"])
post_data = "Hello, WebSocket!"
gatewayapi.post_to_connection(ConnectionId=connection_id, Data=post_data.encode('utf-8'))
return {
'statusCode': 200,
'body': 'Message sent'
}
Creación de la API
Ahora vamos a crear nuestra API que permitirá el envío de mensajes por websocket.
python
api = apigw.WebSocketApi(self, "WebsocketApi")
Luego creamos un stage dentro de nuestra api:
python
stage = apigw.WebSocketStage(
self, 'DevStage',
web_socket_api=api,
stage_name='dev',
auto_deploy=True
)
Y por último añadimos una ruta específica (sendMessage" al websocket de la api y lo vinculamos a la función lambda que hemos creado previamente.
python
api.add_route("sendMessage",
integration=WebSocketLambdaIntegration("SendMessageIntegration", lambda_function)
)
Outputs
Necesitamos conocer la url de nuestro websocket para poder establecer una comunicación con el, por lo que hacemos que nos la muestre en el terminal cuando complete el despliegue de la api
core.CfnOutput(self, "WebSocketURL", value=stage.url)
WebScocket client
Ahora vamos a usar una herramienta para simular nuestro cliente de websocket, podríamos crear una web o una app para probarlo, pero esta herramienta nos permite probar nuestro websocket mucho mas rápido y de una forma mas sencilla.
La herramienta es websocketking (https://websocketking.com/) y es muy fácil de usar.
Lo primero que debemos hacer es añadir la url de nuestro websocket que nos ha devuelto el deploy de nuestro proyecto cdk. En nuestro caso sería wss://kiyi70kcll.execute-api.eu-west-1.amazonaws.com/dev
y le damos a conectar
una vez conectados enviaremos un mensaje (puede estar vacio),simplemente es la forma mas sencilla de conocer nuestro connectionId que lo necesitaremos luego en el test de la lambda para poder enviar un mensaje a través del websocket.
{
"message": "Forbidden",
"connectionId": "WbqM9csoDoECF9w=",
"requestId": "WbqUVE-OjoEFwjw="
}
ahora copiamos nuestro connectionId y creamos un test en la lambda
y ahora enviaremos un mensaje a nuestro websocket con este JSON
{
"requestContext": {
"connectionId": "WbqM9csoDoECF9w=",
"domainName": "kiyi70kcll.execute-api.eu-west-1.amazonaws.com",
"stage": "dev"
}
}
donde tenemos:
connectionId: obtenido previamente
domainName: url de nuestro websocket
stage: stage de nuestra api
y realizamos nuestro test ....
comprobamos que nuestra lambda se ha ejecutado correctamente
y comprobamos nuestra aplicación cliente de websocket
Como se puede comprobar en la imagen, nuestra comunicación a través de websocket a funcionado perfectamente :)
Precios
Ahora viene el dato delicado, si, muy bonito, pero cuanto me va a costar. Ya sabemos que el coste en AWS (y en el resto de Clouds) es de pago por uso, por lo que antes de implementar te aconsejo que vayas a la web de AWS para consultar los precios:
O bien también puedes ir a la calculadora de AWS y calcularlo en función de tus métricas
Te pongo un ejemplo de costes calculados con la calculadora:
- 800 Messages/minutes
- 80 (kb) Average message size
- 20 (seconds) Average connection duration)
- 300 Average connection rate / minute
Y esto hace un total de 121,11 UDS / Mes
Cabe destacar que existe una capa gratuita los 12 primeros meses:
En el caso de las API WebSocket, la capa gratuita de API Gateway incluye un millón de mensajes (enviados o recibidos) y 750 000 minutos de conexión durante un máximo de doce meses.
Dependiendo de cada proyecto puede compensar o no pagar este tipo de soluciones frente a otras que necesiten mas desarrollo.
Github
El proyecto lo podéis encontrar en mi repositorio de Github
Top comments (0)