AWS API Gateway offers a WebSocket API feature that can simplify the process of setting up real-time, two-way communication between clients and servers.
With this feature, developers don't need to manage the underlying infrastructure or handle WebSocket connections directly.
This sequence diagram shows the following steps:
- The client sends an HTTP request with an "Upgrade: websocket" header to AWS API Gateway.
- API Gateway responds with a "101 Switching Protocols" response, establishing a WebSocket connection with the client.
- The client sends a WebSocket message to API Gateway.
- API Gateway invokes the appropriate AWS Lambda function based on the route key defined in the message.
- The Lambda function processes the message and returns the response to API Gateway.
- API Gateway forwards the response back to the client.
- To close the connection, the client sends a close frame, and API Gateway acknowledges it by sending a close frame back to the client, which closes the WebSocket connection.
Practical Use Cases for WebSockets
- Real-Time Dashboards: Allows live streaming of data for stock updates, sports scores, and IoT sensor data.
- Collaborative Applications: Supports synchronized interactions and real-time collaboration.
- Chat and Messaging Applications: Assures instant message delivery and real-time conversations.
Let's Build a Messaging App with WebSockets
By the end of this tutorial, you'll have a functioning WebSocket server that you can use as a foundation for more advanced applications.
We'll start by importing our resources websocket
and collection
.
import { websocket, collection } from "@nitric/sdk";
We'll use a collection to keep track of the client's connection info. This is essentially a document DB holding onto all of the connection ids.
You'll notice that we're granting permissions here for read, write, and delete. These will translate to IAM roles and permissions at deploy time to make sure we have access to the db.
const connections = collection("connections").for(
"reading",
"writing",
"deleting"
);
Next, initialize the WebSocket server and implement our connect, disconnect, and message event handlers.
const socket = websocket("socket");
You can learn a little more about the types of events that AWS Websockets supports by visiting their docs.
Here's a snippet which describes what events are supported
There are three predefined routes that can be used: $connect, $disconnect, and $default. In addition, you can create custom routes.
API Gateway calls the $connect route when a persistent connection between the client and a WebSocket API is being initiated.
API Gateway calls the $disconnect route when the client or the server disconnects from the API.
Handle new client connections:
socket.on("connect", async (ctx) => {
// Store the new connection in the collection
await connections.doc(ctx.req.connectionId).set({});
});
Handle client disconnections:
socket.on("disconnect", async (ctx) => {
// Remove the disconnected client from the collection
await connections.doc(ctx.req.connectionId).delete();
});
Handle incoming messages from clients, here the server will broadcast messages sent from one client to all other connected clients.
socket.on("message", async (ctx) => {
// Get all connections from the collection
const allConnections = await connections.query().stream();
// Create a promise that resolves when the stream ends
const streamEnd = new Promise<any>((res) => allConnections.on("end", res));
//Broadcast the incoming message to all connected clients except the sender
allConnections.on("data", async (connection) => {
if (connection.id !== ctx.req.connectionId) {
await socket.send(ctx.req.connectionId, ctx.req.data);
}
});
// Wait for the stream to end
await streamEnd;
});
Follow the readme to get it up and running. You can test it using a WebSocket client like Postman to connect to your server. Each client will connect with a unique connection id, allowing you to send messages between multiple clients connected to your server.
That's pretty much it, you should have the fundamentals to build upon to make a more comprehensive application, which communicates in real-time and runs on AWS.
Top comments (0)