Creating a Monitoring Application with AWS WebSockets API, Lambda and EventBridge
By: Janitha Tennakoon
Tags: AWS, AWS Lambda, Websocket, Events

As said in the aim of this article is to create a serverless monitoring application using AWS WebSockets API, Lambda functions and EventBridge. In this simple application we are only going to perform a simple status check for facebook.com, but in reality this can be extended for much more other use cases with added features. This will be only an introduction to how to utilize these AWS services in a use case like monitoring. And while we are at it we will also try to extend this application to serve not only one client but for multiple clients using Web Sockets as well.

Below is the summary of AWS services we are going to use in our real-time monitoring application and the reason for using them in our application.

Amazon API Gateway

Source — Amazon Web Services

Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the “front door” for applications to access data, business logic, or functionality from your backend services. (AWS API Gateway Documentation)

Amazon API Gateway mainly offers two types of API types.

RESTful APIs

WebSocket APIs

RESTful APIs are an API type that is used for serverless workloads and HTTP backends using HTTP APIs while WebSocket APIs build real-time two-way communication applications. In our application, we are going to use WebSocket APIs since we need real-time communication for our application.

In Amazon API Gateway Webscokets API there are 3 predefined routes that we can use. Other than that we can also create custom routes as well. Below are the 3 pre-defined routes available for us.

$connect — API Gateway calls this route when a persistent connection between the client and a WebSocket API is being started.

— API Gateway calls this route when a persistent connection between the client and a WebSocket API is being started. $disconnect — API Gateway calls this route when the client or the server disconnects from the API.

— API Gateway calls this route when the client or the server disconnects from the API. $default — API Gateway calls this route if the route selection expression cannot be evaluated or if no matching route is found in the API.

In our application, we are going to use only $connect and $disconnect route. In both $connect and $disconnect routes we are going to invoke two Lambda functions.

AWS Lambda

Source — Amazon Web Services

AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers, creating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes. (AWS Lambda Documentation)

In our application, we are going to create only three Lambda functions.

connect — handle WebSocket client’s $connect event with storing the client’s connection id.

— handle WebSocket client’s event with storing the client’s connection id. disconnect — handle WebSocket client’s $disconnect event with removing connection id.

— handle WebSocket client’s event with removing connection id. monitoring — functional logic for checking server status and sending status to all WebSocket clients connected at the time.

We are going to create connect and disconnect Lambda functions when we create the API Gateway and the monitoring function when all of the other services are configured properly.

Amazon DynamoDB

Source — Amazon Web Services

Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It’s a fully managed, multi-region, multi-active, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. (AWS DynamoDB Documentation)

In our application, we are going to use DynamoDB to store the connection ids of the WebSocket clients. Rather than using DynamoDB, we can use any other persistent storages (Redis, Memcache, RDS, etc) as well.

Amazon EventBridge

Source — Amazon Web Services

Amazon EventBridge is a serverless event bus that makes it easy to connect applications together using data from your own applications, integrated Software-as-a-Service (SaaS) applications, and AWS services. (AWS EventBridge Documentation)

EventBridge mainly supports two types of patterns.

Event pattern — event drive patterns where we can invoke functions/resources based on when the event is produced.

— event drive patterns where we can invoke functions/resources based on when the event is produced. Schedule — schedule functions periodically to be invoked.

We are going to use EventBridge as a scheduler for our Lambda monitoring function since we want to check the status periodically.

WebSocket Client

And lastly, we need a web-socket client who will be listening to our web-socket API. In this article, I am going to create this application using Node.js with npm package ws to create the client.

Now that we know what are the service and technologies we are going to use let’s jump on to the implementation. Below is the architecture diagram for the application we are going to create.

Monitoring Service Architecture

In our application as mentioned, we are going to have 3 Lambda functions. DynamoDB is used to store connection ids of the connected clients. EventBridge is used as a scheduler which will trigger our monitoring Lambda function which we will communicate to our clients using the Web Sockets API.

DynamoDB Table Creation

The first thing we are going to do is create a table in DynamoDB to store the connection ids of the connected clients. As mentioned earlier we can use any other persistent storage other than DynamoDB for this.

Let’s name our table as monitoring-connections and make our Primary key as connectionid.

Creating Lambda functions for $connect and $disconnect

The next step is to start creating our two Lambda functions needed for $connect and $disconnect routes. Before creating the Lambda functions let’s first create an IAM role which we are going to be using for our all three Lambda functions.

Our Lambda functions need access to read and write for DynamoDB and API Gateway invoke permissions.

Next, let’s create two Lambda functions we need for Web Sockets API. Below is the Lambda function code for $connect route. Make sure to attach the newly created IAM role when creating the new function.

$connect route function

Above we are doing a simple thing which is to add the connection id of the client to our DynamoDB table when the client is connected. For $disconnect route we are going to remove the connection id of the disconnected client.

$disconnect route function

Creating Web Socket API

Now since we have created Lambda functions for our defined routes we can move in to creating the Web Socket API. Go to API Gateway HomePage and select WebScoket API.

Provide a name for our API and next we will be prompted to give route selection expression. This field is used when we have custom routes in our API. Leave the expression as request.body.action

Next we need to create routes for our API. As mentioned we are only going to create two routes which are $connect and $disconnect .

Now for the routes we created, we need to attach integrations, which are in our solution the created Lambda functions. For the two routes we have, attach two Lambda functions we created respectively.

Next, add stages and create our Web Socket API.

Now the last step is to deploy our API. Select Actions and select Deploy API

Now we have created our WebSocket API. After the deployment, we will be provided two URLs, WebSocket URL and Connection URL. Make sure to get these values as we need these values in the future.

Creating Node.Js WebSocket Client

Now let’s try to test our newly created WebSocket API. For that, we need to create a WebSocket Client which will be the application where we will be also listening for the server status.

Make sure to install the npm package ws before running the application. And also for the URL make sure to change to WebSocket URL we got from the API deploy. Now when you run the Node.JS application if everything is working we will see connected message on the terminal. And also in our DynamoDB table, a new entry should be there with the connection id of the client.

Now if you stop the application the DyanamoDB item should also be removed.

Creating a Lambda function for monitoring

Ok, now the next step would be to create the Lambda function which will check the status of a server and send the status to connected clients. Below is the function code.

First, we have initiated the ApiGatewayManagementApi instance with the endpoint we got from after the API deployment. Here the endpoint should have the below format.

https://<api-id>.execute-api.<region>.amazonaws.com/<stage>

Next, the first thing we are doing is getting all the connected client's connection ids. After that, we are checking the status of the server. In here as an example, I am checking whether https://facebook.com/ is up or not. Then based on the response we will be sending the status to every client who is connected to our WebSocket API.

Creating EventBridge Scheduler

Now although we have our Lambda function to check the server status we have no way of triggering it periodically. That’s why we need EventBridge to create a new rule to invoke this Lambda function periodically.

Go to the Amazon EventBridge home page and select Create rule.

Here we can provide a name for our rule and select the pattern. In our application the pattern is Schedule.

We can either have a fixed rate or define scheduling time using the Cron expression format. For now, let’s configure it to run every 5 minutes.

Next, select the target as Lambda function and the function that we have created. That is it, and now after creating the rule EventBridge will start to execute the rule.

Let’s open up two clients and observe the response given by our WebSocket API. If everything is working accordingly, every 5 minutes a message should be pop up in both terminals with the server status.

That is it for this article now. As you can see now this is not the most usable use case we can do with these services. So make sure to try out different use cases using these services by yourself.

Thank you.