How To Build Real Time Chat Application Using WebSockets with AWS API Gateway
Today I was stuck finding a solution on a very specific problem: find a way to create a real time chat application using WebSockets in APIGateway.
As you probably already know that, WebSocket is a computer communications protocol,used for the communication between the client and the server in bi-directional way. With these native WebSockets in API Gateway, you establish a single WebSocket connection to API Gateway from the device. Using these AWS services Let’s find a solution…!!!
- Sign in to the aws console and at Services click on API Gateway.
- Create an API
- Select Websocket Protocol and give your API name and create.
Route Selection Expression:$request.body.message
- Your API is created.
- Click on Routes your routes will be displayed.
- Go to Services and select DynamoDB.
- Create a table.
- Give your table name and primary key. And then create the table.
- DynamoDB table is created.
- Go to Services and select Lambda.
- Create a lambda function.
- Give your Lambda function name and IAM role and create function.
- This lambda function code is for connecting to DynamoDB. And to store the connection id,username.
Code:
import json
import boto3def lambda_handler(event, context):
print("event:::")
print(event)
connection_id=event['requestContext']['connectionId']
username=event['queryStringParameters']['username']
dynamodb = boto3.resource('dynamodb')
table1 = dynamodb.Table('table')
table1.put_item(
Item={
'connection_id': connection_id,
'username':username
# 'message':message
}
)return {
'statusCode': 200
}
- Go to API Gateway and at click on Integration Request.
- Integrate your lambda function here and save.
- Click on Actions and select Deploy API.
- Create a Deployment stage and Deploy.
- It generates a Websocket URL. Copy this url.
- To call through WebSockets we can use the wscat tool.Use this command “npm install -g wscat” in your command prompt.
- Use this commnad wscat -c “ your websocket url”?username=your username for being connected to websockets.
- So your username and connection_id will be stored in DynamoDB table.
- Create another Lambda function for disconnecting the websocket connection.
Code:
import json
import boto3def lambda_handler(event, context):
print("event:::")
print(event)
connection_id=event['requestContext']['connectionId']
dynamodb = boto3.resource('dynamodb')
table1 = dynamodb.Table('table')
response = table1.delete_item(
Key={
'connection_id': event['requestContext']['connectionId']
})return {
'statusCode': 200
}
- Go to API Gateway and at $disconnect route click on Integration Request.
- Integrate your lambda function here and save.
- Click on Actions and select Deploy API.
- Select your Deployment stage and Deploy.
- It generates a Websocket URL. Copy this url.
- In your command prompt if you press CTRL + C your data will be deleted.Your connetion_id and username will be disconnected from DynamoDB table. Also when the websocket connection becomes idle the connection will be lost and deletes the data from the table.
- Go to PyCharm Editor or any other Editors and create a python file. This code is used for query on DynamoDB to get all the connection ids, and send messages to them. Get a message from the device and send the message to all the devices that are connected to the WebSocket API.
Code:
import boto3
import ast
import hmac
import base64
import json
import uuid
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Key, Attr
import logging
import urllib3logger = logging.getLogger('dev')
logger.setLevel(logging.DEBUG)client = boto3.client('apigatewaymanagementapi')dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
# table = dynamodb.Table('chatp')
def _send_to_connection(connection_id, data, event):
gatewayapi = boto3.client("apigatewaymanagementapi",
endpoint_url = "https://" + event["requestContext"]["domainName"] +
"/" + event["requestContext"]["stage"])
response = gatewayapi.post_to_connection(ConnectionId=connection_id,
Data=json.dumps(data).encode('utf-8'))
print(response)
print("response>>>>>>>")
return responsedef lambda_handler(event, context):
print(event)
table = dynamodb.Table("table")
response = table.scan()
data1 = response['Items']
length = data1.__len__()
print("data1:::")
print(data1)
# items = response.get("Items", [])
# connections = [x["Connectionid "] for x in items if "Connectionid " in x]
# print(connections)
# Send the message data to all connections
# playersTable = dynamodb.Table('PLAYER_DETAILS')
connectionId = event['requestContext']['connectionId']
playerDetailsObj = table.scan(
FilterExpression=Attr('connection_id').eq(connectionId)
)
playerDetails = playerDetailsObj['Items']
username = ""
print("playerDetails:::")
print(playerDetails)
for x in range(length):
if data1[x]['connection_id'] == connectionId:
username = data1[x]['username'] message1 = event['body']
message2 = ast.literal_eval(message1)
message = message2['message']
print(message)
logger.debug("Broadcasting message: {}".format(message))
data = {username: message}
valresp = ""
for x in range(length):
connectionID = data1[x]['connection_id']
valresp = _send_to_connection(connectionID, data, event)
print(valresp)
return {'statusCode':200}
- Install the latest versions of boto3, boto3–1.9.128.dist-info, botocore, botocore-1.12.128.dist-info, urllib3, urllib3–1.24.1.dist-info. Zip all these modules along with your python file.
- Create another lambda for getting a message from the device and send the message to all the devices that are connected to the WebSocket API. Upload your zip file and save.
- Give your custom route name and save in API Gateway.
- Integrate your lambda here and save.
- Click on Actions and select Deploy API.
- Select your Deployment stage and Deploy.
- It generates a Websocket URL. Copy this url.
- Take another command prompt and install wscat “npm install -g wscat” . Use this command wscat -c “your websocket url”?username=your username for connecting to multiple devices.
Message Format:
{"action" : "onMessage" , "message" : "Hey Hi....."}
- Two users connected to this web socket url and started their conversation. If you want you can send this web socket url to others install the wscat an enter your webscocket url. And start doing conversations with them from multiple devices.
Using this solution, we can connect to multiple devices and start conversations with multiple users using web sockets.
Ok, that’s it. I hope you found this case useful! See you next time.