Sunteți pe pagina 1din 23

Build a real-time serverless chat app with

Azure Functions
Introduction

Technologies used

 Azure Storage - Host the static website for the chat client UI
 Azure Functions - Backend API for creating and retrieving chat messages
 Azure Cosmos DB - Store chat messages
 Azure SignalR Service - Broadcast new messages to connected chat clients

Prerequisites
The following software is required to build this tutorial.

 Git
 Node.js (Version 10.x)
 .NET SDK (Version 2.x, required for Functions extensions)
 Azure Functions Core Tools (Version 2)
 Visual Studio Code (VS Code) with the following extensions
o Azure Functions
o Live Server
 Postman (optional, for testing Azure Functions)

===

Create Azure resources


You will build and test the Azure Functions app locally. The app will access some services in Azure
that need to be created ahead of time.

Log into the Azure portal

1. Go to the Azure portal and log in with your credentials.

Create an Azure Cosmos DB account


1. Click on the Create a resource (+) button for creating a new Azure resource.

2. Under Databases, select Azure Cosmos DB.


3. Enter the following information.

Name Value

ID A unique name for the Cosmos DB account

API SQL

Resource group New - enter a new resource group name

Location Select a location close to you

4.

5. Click Create.

Create an Azure SignalR Service instance


1. Click on the Create a resource (+) button for creating a new Azure resource.

2. Search for SignalR Service and select it. Click Create.

3. Enter the following information.

Name Value

Resource name A unique name for the SignalR Service instance


Name Value

Resource group Select the same resource group as the Cosmos DB account

Location Select a location close to you

Pricing Tier Free

4.

5. Click Create.

===

Initialize a function app

Create a new Azure Functions project


1. In a new VS Code window, use File > Open Folder in the menu to create and open an empty
folder in an appropriate location. This will be the main project folder for the application that
you will build.
2. Using the Azure Functions extension in VS Code, initialize a Function app in the main
project folder.

i. Open the Command Palette in VS Code by selecting View > Command Palette from the
menu (shortcut Ctrl-Shift-P, macOS: Cmd-Shift-P).
ii. Search for the "Azure Functions: Create New Project" command and select it.
iii. The main project folder should appear. Select it (or use "Browse" to locate it).
iv. In the prompt to choose a language, select JavaScript.
Install function app extensions
This tutorial uses Azure Functions bindings to interact with Azure Cosmos DB and Azure SignalR
Service. These bindings are available as extensions that need to be installed using the Azure
Functions Core Tools CLI before they can be used.

1. Open a terminal in VS Code by selecting View > Integrated Terminal from the menu (Ctrl-`).

2. Ensure the main project folder is the current directory.

3. Install the Cosmos DB function app extension.

4. func extensions install -p Microsoft.Azure.WebJobs.Extensions.CosmosDB -v 3.0.1

5. Install the SignalR Service function app extension.

6. func extensions install -p Microsoft.Azure.WebJobs.Extensions.SignalRService -v 1.0.0-


preview1-10002
Configure application settings
When running and debugging the Azure Functions runtime locally, application settings are read
from local.settings.json. Update this file with the connection strings of the Cosmos DB account
and the SignalR Service instance that you created earlier.

1. In VS Code, select local.settings.json in the Explorer pane to open it.

2. Replace the file's contents with the following.

3. {
4. "IsEncrypted": false,
5. "Values": {
6. "AzureSignalRConnectionString": "<signalr-connection-string>",
7. "CosmosDBConnectionString": "<cosmosdb-connection-string>",
8. "WEBSITE_NODE_DEFAULT_VERSION": "10.6.0",
9. "FUNCTIONS_WORKER_RUNTIME": "node"
10. },
11. "Host": {
12. "LocalHttpPort": 7071,
13. "CORS": "*"
14. }
15. }
o Enter the Azure SignalR Service connection string into a setting
named AzureSignalRConnectionString. Obtain the value from the Keys page in the
Azure SignalR Service resource in the Azure portal; either than primary or secondary
connection string can be used.
o Enter the Azure Cosmos DB connection string into a setting
named CosmosDBConnectionString. Obtain the value from the Keys page in the
Cosmos DB account in the Azure portal; either than primary or secondary connection
string can be used.
o The WEBSITE_NODE_DEFAULT_VERSION setting is not used locally, but is required when
deployed to Azure.
o The Host section configures the port and CORS settings for the local Functions host.

16. Save the file.

===

Create Azure Functions to save and retrieve chat messages

CreateMessage function

Create the function

1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Create Function command.

3. When prompted, provide the following information.

Name Value

Function app folder select the main project folder

Template HTTP Trigger


Name Value

Name CreateMessage

Authorization level Anonymous

4. A folder named CreateMessage is created that contains the new function.

5. Open CreateMessage/function.json to configure bindings for the function. Modify the


content of the file to the following.

6. {
7. "disabled": false,
8. "bindings": [
9. {
10. "authLevel": "anonymous",
11. "type": "httpTrigger",
12. "direction": "in",
13. "name": "req",
14. "route": "messages",
15. "methods": [
16. "post"
17. ]
18. },
19. {
20. "type": "http",
21. "direction": "out",
22. "name": "res"
23. },
24. {
25. "name": "cosmosDBMessage",
26. "type": "cosmosDB",
27. "databaseName": "chat",
28. "collectionName": "messages",
29. "createIfNotExists": true,
30. "connectionStringSetting": "CosmosDBConnectionString",
31. "direction": "out"
32. }
33. ]
34. }

This makes two changes to the function:

o Changes the route to messages and restricts the HTTP trigger to the POST HTTP
method.
o Adds a Cosmos DB output binding that saves documents to a collection
named messages in a database named chat.

35. Save the file.

36. Open CreateMessage/index.js to view the body of the function. Modify the content of the
file to the following.

37. module.exports = function (context, req) {


38. context.bindings.cosmosDBMessage = req.body;
39. context.done();
40. };
This function takes the body from the HTTP request and saves it as a document in Azure
Cosmos DB.

41. Save the file.

(Optional) Test the function

1. To run the function app locally, press F5 in VS Code. If this is the first time, the Azure
Functions host will start in the VS Code integrated terminal.

2. When the functions runtime is successfully started, the terminal output will display a URL for
the local CreateMessage endpoint (by default, it is http://localhost:7071/api/messages).

3. Open Postman. Postman is an application to send HTTP requests.

4. Select File > Import from the menu.

5. Choose Import from link and paste in

6. https://raw.githubusercontent.com/Azure-Samples/functions-serverless-chat-app-
tutorial/master/requests/SignalRChat.postman_collection.json

This loads a collection of HTTP requests for testing the function app locally. Click on
the Collections tab in Postman to see it.

7. In the SignalR Chat collection, select the Create a message request.

8. Confirm the URL matches the one outputted by the function host and there is JSON
message in the request body.

9. Click Send. The function app should return an HTTP status of 200.
10. In the Azure portal, open the Cosmos DB account resource you created earlier.

11. Using the Cosmos DB Data Explorer, locate the messages collection in the chat database.
The message sent from Postman should appear as a document in the collection.

12. Click the Disconnect button to disconnect the debugger from the function host.
GetMessages function

Create the function

1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Create Function command.

3. When prompted, provide the following information.

Name Value

Function app folder select the main project folder

Template HTTP Trigger

Name GetMessages

Authorization level Anonymous

4. A folder named GetMessages is created that contains the new function.

5. Open GetMessages/function.json to configure bindings for the function. Modify the


content of the file to the following.

6. {
7. "disabled": false,
8. "bindings": [
9. {
10. "authLevel": "anonymous",
11. "type": "httpTrigger",
12. "direction": "in",
13. "name": "req",
14. "route": "messages",
15. "methods": [
16. "get"
17. ]
18. },
19. {
20. "type": "http",
21. "direction": "out",
22. "name": "res"
23. },
24. {
25. "name": "messages",
26. "type": "cosmosDB",
27. "databaseName": "chat",
28. "collectionName": "messages",
29. "sqlQuery": "select * from c order by c._ts desc",
30. "connectionStringSetting": "CosmosDBConnectionString",
31. "direction": "in"
32. }
33. ]
34. }

This makes two changes to the function:

o Changes the route to messages and restricts the HTTP trigger to the GET HTTP
method.
o Adds a Cosmos DB input binding that retrieves documents (in reverse chronological
order) from a collection named messages in a database named chat.

35. Save the file.

36. Open GetMessages/index.js to view the body of the function. Modify the content of the
file to the following.

37. module.exports = function (context, req, messages) {


38. context.res.body = messages;
39. context.done();
40. };

This function takes the documents retrieved from Cosmos DB (chat messages in reverse
chronological order) and returns them in the HTTP response body.

41. Save the file.

(Optional) Test the function

1. To run the function app locally, press F5 in VS Code. If this is the first time, the Azure
Functions host will start in the VS Code integrated terminal.

2. When the functions runtime is successfully started, the terminal output will display URLs for
the local CreateMessage and GetMessages endpoints (by default, they
are http://localhost:7071/api/messages).
3. (See above to open Postman and import a collection) In Postman, in the SignalR
Chat collection, select the Get messages request.

4. Confirm the URL matches the one outputted by the function host and the HTTP method
is GET.

5. Click Send. The function app should return the messages from Cosmos DB.

6. Press the Disconnect button to disconnect the debugger from the function host.

===

Create and run the chat client web user interface


The chat application's UI is a simple single page application (SPA) created with Vue JavaScript
framework. It will be hosted separately from the function app. Locally, you will run the web
interface using the Live Server VS Code extension.

1. In VS Code, create a new folder named content at the root of the main project folder.

2. In the content folder, create a new file named index.html.

3. Copy and paste the content of index.html.

4. Save the file.

5. Press F5 to run the function app locally (it may already be running) and attach a debugger.
6. With index.html open, start Live Server by opening the VS Code command palette (Ctrl-
Shift-P, macOS: Cmd-Shift-P) and selecting Live Server: Open with Live Server. Live Server
will open the application in a browser.

7. When the application prompts for a username, enter one. If you tested the function earlier,
messages from your testing session will appear.

8. Enter a message in the chat box and press enter. Refresh the application to see new
messages.

Next, you will integrate Azure SignalR Service into your application to allow messages to appear in
real-time.

===

Display real-time messages with Azure SignalR Service


Azure SignalR Service provides real-time messaging capabilities to supported clients, including
web browsers. You will use Azure Functions to integrate with SignalR Service to broadcast new
chat messages in real-time to connected browsers.

SignalRInfo function

Create the function

1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Create Function command.

3. When prompted, provide the following information.

Name Value

Function app folder select the main project folder

Template HTTP Trigger

Name SignalRInfo

Authorization level Anonymous

4. A folder named SignalRInfo is created that contains the new function.

5. Open SignalRInfo/function.json to configure bindings for the function. Modify the


content of the file to the following. This adds an input binding that generates valid
credentials for a client to connect to an Azure SignalR Service hub named chat.
6. {
7. "disabled": false,
8. "bindings": [
9. {
10. "authLevel": "anonymous",
11. "type": "httpTrigger",
12. "direction": "in",
13. "name": "req"
14. },
15. {
16. "type": "http",
17. "direction": "out",
18. "name": "res"
19. },
20. {
21. "type": "signalRConnectionInfo",
22. "name": "connectionInfo",
23. "hubName": "chat",
24. "direction": "in"
25. }
26. ]
27. }

28. Open SignalRInfo/index.js to view the body of the function. Modify the content of the file
to the following.

29. module.exports = function (context, req, connectionInfo) {


30. context.res = { body: connectionInfo };
31. context.done();
32. };

This function takes the SignalR connection information from the input binding and returns it
to the client in the HTTP response body.

(Optional) Test the function

1. To run the function app locally, press F5 in VS Code. If this is the first time, the Azure
Functions host will start in the VS Code integrated terminal.

2. When the functions runtime is successfully started, the terminal output will display URLs for
the local endpoints, including SignalRInfo (by default, they
are http://localhost:7071/api/SignalRInfo).

3. (See above to open Postman and import a collection) In Postman, in the SignalR
Chat collection, select the Get SignalR info request.

4. Confirm the URL matches the one outputted by the function host and the HTTP method
is GET.

5. Click Send. The function app should return connection information for SignalR Service.

6. Press the Disconnect button to disconnect the debugger from the function host.

Broadcast new messages to all clients

Update the CreateMessage function


1. Open CreateMessage/function.json to configure bindings for the function. Add
a signalR output binding by replacing the file's contents with the following.
2. {
3. "disabled": false,
4. "bindings": [
5. {
6. "authLevel": "anonymous",
7. "type": "httpTrigger",
8. "direction": "in",
9. "name": "req",
10. "route": "messages",
11. "methods": [
12. "post"
13. ]
14. },
15. {
16. "type": "http",
17. "direction": "out",
18. "name": "res"
19. },
20. {
21. "name": "cosmosDBMessage",
22. "type": "cosmosDB",
23. "databaseName": "chat",
24. "collectionName": "messages",
25. "createIfNotExists": true,
26. "connectionStringSetting": "CosmosDBConnectionString",
27. "direction": "out"
28. },
29. {
30. "type": "signalR",
31. "name": "signalRMessages",
32. "hubName": "chat",
33. "direction": "out"
34. }
35. ]
36. }

37. Open CreateMessage/index.js to view the body of the function. Modify the content of the
file to the following. This adds a line to output new chat messages to all clients connected
to the SignalR Service hub.

38. module.exports = function (context, req) {


39. context.bindings.cosmosDBMessage = req.body;
40. context.bindings.signalRMessages = [{
41. "target": "newMessage",
42. "arguments": [req.body]
43. }];
44. context.done();
45. };

Test the app

1. Press F5 to run the function app locally (it may already be running) and attach a debugger.

2. With index.html open, start Live Server by opening the VS Code command palette (Ctrl-
Shift-P, macOS: Cmd-Shift-P) and selecting Live Server: Open with Live Server. Live Server
will open the application in a browser.
3. Now, new messages will appear as soon as they are sent. Open the app in more than one
browser to see the real-time capabilities in action.

===

Deploy to Azure
You have been running the function app and chat application locally. You will now deploy them to
Azure.

Log into Azure with VS Code


1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure: Sign in command.

3. Follow the instructions to complete the sign in process in your browser.

Deploy function app


1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Deploy to Function App command.

3. When prompted, provide the following information.

Name Value

Folder to deploy Select the main project folder

Subscription Select your subscription

Function app Select Create New Function App

Function app name Enter a unique name

Select the same resource group as the Cosmos DB account and SignalR
Resource group
Service instance

Storage account Select Create new storage account

Storage account
Enter a unique name (3-24 characters, alphanumeric only)
name

Location Select a location close to you


4. A new function app is created in Azure and the deployment begins. The Azure Functions VS
Code extension will first create the Azure resources; then it will deploy the function app.
Wait for deployment to complete.

Upload function app local settings


1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Upload local settings command.

3. When prompted, provide the following information.

Name Value

Local settings file local.settings.json

Subscription Select your subscription

Function app Select the previously deployed function app

Function app name Enter a unique name

Local settings are uploaded to the function app in Azure. If prompted to overwrite existing
settings, select Yes to all.
Enable function app cross origin resource sharing (CORS)
Although there is a CORS setting in local.settings.json, it is not propagated to the function app in
Azure. You need to set it separately.

1. Open the VS Code command palette (Ctrl-Shift-P, macOS: Cmd-Shift-P).

2. Search for and select the Azure Functions: Open in portal command.

3. Select the subscription and function app name to open the function app in the Azure portal.

4. Under the Platform features tab, select CORS.

5. Add an entry with the value *.

6. Remove all other existing entries.

7. Click Save to persist the CORS settings.


In a real-world application, instead of allowing CORS on all domains (*), a more secure approach is
to enter specific CORS entries for each domains that requires it.

Update function app URL in chat UI


1. In the Azure portal, navigate to the function app's overview page.

2. Copy the function app's URL.

3. In VS Code, open index.html and replace the value of window.apiBaseUrl with the function
app's URL.

4. Save the file.


Deploy web UI to blob storage
The web UI will be hosted using Azure Blob Storage's static websites feature.

1. Click on the New (+) button for creating a new Azure resource.

2. Under Storage, select Storage account.

3. Enter the following information.

Name Value

Resource group Select the same resource group as the Cosmos DB account

Storage account name A unique name for the blob storage account

Location Select the same region as your other resources

Performance Standard

Account kind StorageV2 (general purpose V2)

Replication Locally-redundant storage (LRS)

Access tier Hot


4.

5. Click Create.

6. When the storage account is created, open it in the Azure portal.

7. Select Static website (preview) in the left navigation.

8. Select Enable.

9. Enter index.html as the Index document name.

10. Click Save.

11. Click on the $web link on the page to open the blob container.
12. Click Upload and upload all the files in the content folder.

13. Go back to the Static website page. Copy the Primary endpoint address and open it in a
browser.

The chat application will appear. Congratulations on creating and deploying a serverless chat
application to Azure!

S-ar putea să vă placă și