This post is updated on 07/03/2019

AWS announced the launch of a widely-requested feature: WebSockets for Amazon API Gateway few days ago. To test out this new feature, I spent a couple of hours building a realtime chat App using WebSockets with custom lambda authorizer.

Before You Start

Please read below articles to understand WebSocket APIs in Amazon API Gateway and Cognito User Pool

Now, Let’s Start

You can find all complete project in my GitHub repo.

Main Libraries in Backend

Amazon API Gateway WebSockets

Amazon DynamoDB

Amazon Cognito User Pool

Serverless ≥1.38

Node.js 8.10

Main Libraries in Frontend

Structure

The structure has a root folder that contains frontend and backend folders:

Backend

API Gateway WebSockets and lambda functions to manage WebSockets routes ($connect, $disconnect, sendMessage) and create DynamoDb to store WebSockets connectionIds.

Frontend

React online app with live chat functionality.

Building API, the Serverless Framework, and AWS Lambda

Serverless Framework v1.38.0 now includes built-in support for Websockets, go to backend directory, update your serverless.yml to look like the following:

Add Lambda function

Now, let’s update our handler.js to create the lambda functions for WebSockets routes :$connect with custom authorizer, $disconnect, sendMessage:

Deployment

Let’s deploy the service!

sls deploy --stage dev

You will get the WebSockets endpoints after deployment finished, copy the endpoints and paste to Websockets client in next step

React Frontend

AWS Amplify (1.1.17) pubsub module doesn’t support API Gateway WebSockets yet. I decide to use sockette as WebSockets client. It is a tiny library and truly simple to use.

here is and example of declaring events listeners on initialization and sending messages:

import Sockette from "sockette"; //Init WebSockets with Cognito Access Token

ws = new Sockette(

"wss://APP_CLIENT_ID.execute-api.ap-southeast-2.amazonaws.com/dev?token=" +

props.authData.signInUserSession.accessToken.jwtToken,

{

timeout: 5e3,

maxAttempts: 1,

onopen: e => console.log("connected:", e),

onmessage: e => console.log("Message Received:", e),

onreconnect: e => console.log("Reconnecting...", e),

onmaximum: e => console.log("Stop Attempting!", e),

onclose: e => console.log("Closed!", e),

onerror: e => console.log("Error:", e)

}

); //Send Message

ws.json({

action: "sendMessage",

data: "Hello World"

});

React Hooks

In Frontend project, I have no Class components by integrating React Hook, Hooks make it possible to take a React function component and add state to it, or hook into lifecycle methods like componentDidMount and componentDidUpdate.

All set to go, Try it out!

Go to frontend directory, run

$ npm install

$ npm start

Preview