Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mboulin committed Jul 28, 2020
1 parent 3f8b585 commit 2eaa031
Show file tree
Hide file tree
Showing 30 changed files with 27,098 additions and 19 deletions.
23 changes: 11 additions & 12 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2 changes: 2 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Amazon IVS Simple Chat Demo
Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
39 changes: 32 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
## My Project
# Amazon IVS Simple Chat demo

TODO: Fill this README out!
A demo web application intended as an educational tool for demonstrating how Amazon IVS, in conjunction with other AWS services, can be used to build a compelling customer experience for live video with chat use-cases.

Be sure to:
**This project is intended for education purposes only and not for production usage.**

* Change the title in this README
* Edit your repository description on GitHub
This is a serverless web application, leveraging [Amazon IVS](https://aws.amazon.com/ivs/), [AWS Lambda](https://aws.amazon.com/lambda/), and WebSockets. The web user interface is a [single page application](https://en.wikipedia.org/wiki/Single-page_application) built using [responsive web design](https://en.wikipedia.org/wiki/Responsive_web_design) frameworks and techniques, producing a native app-like experience tailored to the user's device.
The demo showcases how you can implement a simple chat client next to an Amazon IVS stream. Users are asked to enter their name the first time they begin chatting. Messages are sent in the format `<Username>` `<Message>` as part of each chat "bubble". Users can send plain text messages, text links, and emojis. Chat messages have a character limit of 510 characters.

## Getting Started

***IMPORTANT NOTE:** Deploying this demo application in your AWS account will create and consume AWS resources, which will cost money.*

To get the demo running in your own AWS account, follow these instructions.

1. If you do not have an AWS account, please see [How do I create and activate a new Amazon Web Services account?](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)
2. Log into the [AWS console](https://console.aws.amazon.com/) if you are not already. Note: If you are logged in as an IAM user, ensure your account has permissions to create and manage the necessary resources and components for this application.
3. Follow the instructions for deploying to AWS or running locally.

### Deploying to AWS or running locally
* This demo is comprised of two parts: `serverless` (the demo backend) and `web-ui` (the demo frontend)
* To run the demo's backend services locally or on your AWS account, follow the [detailed instructions](./serverless/README.md) to get started.

## Known issues and limitations
* The application was written for demonstration purposes and not for production use.
* Currently only tested in the us-west-2 (Oregon) region. Additional regions may be supported depending on service availability.

## About Amazon IVS
Amazon Interactive Video Service (Amazon IVS) is a managed live streaming solution that is quick and easy to set up, and ideal for creating interactive video experiences. [Learn more](https://aws.amazon.com/ivs/).

* [Amazon IVS docs](https://docs.aws.amazon.com/ivs/)
* [User Guide](https://docs.aws.amazon.com/ivs/latest/userguide/)
* [API Reference](https://docs.aws.amazon.com/ivs/latest/APIReference/)
* [Setting Up for Streaming with Amazon Interactive Video Service](https://aws.amazon.com/blogs/media/setting-up-for-streaming-with-amazon-ivs/)

## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.

## License

This library is licensed under the MIT-0 License. See the LICENSE file.

This library is licensed under the MIT-0 License. See the LICENSE file.
23 changes: 23 additions & 0 deletions THIRD-PARTY-LICENSES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
** React; version 16.13.1 -- https://github.com/facebook/react

MIT License

Copyright (c) Facebook, Inc. and its affiliates.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
105 changes: 105 additions & 0 deletions serverless/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Local Deployment Instructions for Simple Chat Backend

Deploy a simple chat back-end with AWS Lambda and WebSockets.

## Prerequisites

* Access to AWS Account with permission to create IAM role, and Lambda.
* [AWS CLI Version 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
* [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)

## Deploy from your local machine

Before you start, run below command to make sure you're in the correct AWS account and configured.
```
aws configure
```
For additional help on configuring, please see https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html

### 1. Create an S3 bucket

* Replace `<my-bucket-name>` with your bucket name.
* Replace `<my-region>` with your region name.

```
aws s3api create-bucket --bucket <my-bucket-name> --region <my-region> \
--create-bucket-configuration LocationConstraint=<my-region>
```

### 2. Pack template with SAM

```
sam package \
--template-file template.yaml \
--output-template-file packaged.yaml \
--s3-bucket <my-bucket-name>
```
DO NOT run the output from above command, proceed to next step.

### 3. Deploy Cloudformation with SAM

Replace `<my-stack-name>` with your stack name.

```
sam deploy \
--template-file packaged.yaml \
--stack-name <my-stack-name> \
--capabilities CAPABILITY_IAM
```
On completion, copy the value of `WebSocketURI` as you will need it later for your client.

To retrieve Cloudformation stack outputs again, run below command:
```
aws cloudformation describe-stacks --stack-name <my-stack-name>
aws cloudformation describe-stacks \
--stack-name <my-stack-name> --query 'Stacks[].Outputs'
```

### 4. Testing the chat API

To test the WebSocket API, you can use [wscat](https://github.com/websockets/wscat), an open-source command line tool.

1. [Install NPM](https://www.npmjs.com/get-npm).
2. Install wscat:
``` bash
$ npm install -g wscat
```
3. On the console, connect to your published API endpoint by executing the following command:

Replace `<WebSocketURI>` with your WebSocketServer URL created when deploying with cloudformation.

``` bash
$ wscat -c <WebSocketURI>
```
4. To test the sendMessage function, send a JSON message like the following example. The Lambda function sends it back using the callback URL:

Replace `<WebSocketURI>` with your WebSocketServer URL created when deploying with cloudformation.

``` bash
$ wscat -c <WebSocketURI>
connected (press CTRL+C to quit)
> {"action":"sendmessage", "data":"hello world"}
< hello world
```

### 5. Deploy Simple Chat Web UI Demo

Follow these [detailed instructions](../web-ui) on how to get the UI running.

## Clean Up

1. Delete Cloudformation stack:
```
aws cloudformation delete-stack --stack-name <my-stack-name>
```

3. Remove files in S3 bucket
```
aws s3 rm s3://<my-bucket-name> --recursive
```

2. Delete S3 bucket
```
aws s3api delete-bucket --bucket <my-bucket-name> --region <my-region>
```
79 changes: 79 additions & 0 deletions serverless/lambda/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: process.env.AWS_REGION });
const { TABLE_NAME } = process.env;

exports.onConnect = async event => {
const putParams = {
TableName: TABLE_NAME,
Item: {
connectionId: event.requestContext.connectionId
}
};

try {
await ddb.put(putParams).promise();
} catch (err) {
return { statusCode: 500, body: 'Failed to connect: ' + JSON.stringify(err) };
}

return { statusCode: 200, body: 'Connected.' };
};

exports.sendMessage = async event => {
let connectionData;

try {
connectionData = await ddb.scan({ TableName: TABLE_NAME, ProjectionExpression: 'connectionId' }).promise();
} catch (e) {
return { statusCode: 500, body: e.stack };
}

const apigwManagementApi = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: event.requestContext.domainName + '/' + event.requestContext.stage
});

const postData = JSON.parse(event.body).data;

const postCalls = connectionData.Items.map(async ({ connectionId }) => {
try {
await apigwManagementApi.postToConnection({ ConnectionId: connectionId, Data: postData }).promise();
} catch (e) {
if (e.statusCode === 410) {
console.log(`Found stale connection, deleting ${connectionId}`);
await ddb.delete({ TableName: TABLE_NAME, Key: { connectionId } }).promise();
} else {
throw e;
}
}
});

try {
await Promise.all(postCalls);
} catch (e) {
return { statusCode: 500, body: e.stack };
}

return { statusCode: 200, body: 'Data sent.' };
};

exports.onDisconnect = async event => {
const deleteParams = {
TableName: TABLE_NAME,
Key: {
connectionId: event.requestContext.connectionId
}
};

try {
await ddb.delete(deleteParams).promise();
} catch (err) {
return { statusCode: 500, body: 'Failed to disconnect: ' + JSON.stringify(err) };
}

return { statusCode: 200, body: 'Disconnected.' };
};

11 changes: 11 additions & 0 deletions serverless/lambda/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "simple-chat",
"version": "1.0.0",
"description": "onConnect, sendMessage and onDisconnect example for WebSockets on API Gateway",
"main": "src/app.js",
"author": " ",
"license": " ",
"dependencies": {
"aws-sdk": "^2.690.0"
}
}
Loading

0 comments on commit 2eaa031

Please sign in to comment.