You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As an engineer with Tailwind Traders, you've learned your company is planning to launch a new website that provides stock price information to customers. Recently, an intern created a website prototype for the new application and the Lead Architect has now asked you to step in and improve the solution. Your objective is to update the app to implement automatic updates of the stock price information, but ensure communication between the client and server happens only when data changes on the server.
2
+
As an engineer with Tailwind Traders, you learned that your company is planning to launch a new website that provides stock price information to customers. Recently, an intern created a website prototype for the new application and the Lead Architect is asking you to step in and improve the solution. Your objective is to update the app to implement automatic updates of the stock price information, but ensure communication between the client and server happens only when data changes on the server.
3
3
4
4
## Prototype architecture
5
5
6
-
The server prototype has 2 functions:
6
+
The server prototype has two functions:
7
7
8
8
|Function name|Trigger type|Description|
9
9
|--|--|--|
10
10
|**getStocks**|Azure Cosmos DB|The server is responsible for reading all data from the stocks table in the database and returning that data in an HTTP response whenever the client requests it.|
11
-
|**setPrice**|Timer|A function to change the data in the database runs on a timer trigger. This simulates receiving changes from a backend system.|
11
+
|**setPrice**|Timer|A function to change the data in the database runs on a timer trigger. This function simulates receiving changes from a backend system.|
12
12
13
13
As a prototype, the intern simulated the stock feed with a timer function, which updates every minute. The client website requests all the stocks from the `/api/getStocks` API endpoint every 5 seconds in an attempt to display near real time data. This client request isn't efficient. Instead of pulling the data from the server, it's more efficient for the server to push any new stock information.
14
14
15
15
## Tasks to be done
16
16
17
17
In this module, you will:
18
18
19
-
- Run the prototype: View the client application, which polls the server for all stocks on a regular interval
19
+
- Run the prototype: View the client application, which polls the server for all stocks at a regular interval.
20
20
- Improve the application: Implement a serverless Azure Functions app to broadcast changes to connected clients using SignalR Service to product near real-time updates.
21
21
- Update the client JavaScript web application to connect to SignalR to get and display the messages.
Copy file name to clipboardExpand all lines: learn-pr/advocates/automatic-update-of-a-webapp-using-azure-functions-and-signalr/includes/2-analyze-limitations-of-polling-in-a-web-app.md
+11-13Lines changed: 11 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,15 @@
1
1

2
2
3
-
The application's current architecture reports stock information by fetching _all_ stock price information from the server based on a timer. This design is often called a polling-based design.
3
+
The application's current architecture reports stock information by fetching *all* stock price information from the server based on a timer. This design is often called a polling-based design.
4
4
5
5
### Server
6
6
7
7
The stock price information is stored in an Azure Cosmos DB database. When triggered by an HTTP request, the function `getStocks` returns all rows from the database.
***Get data**: The first section of code, **cosmosInput**, gets all the items in the `stocks` table, with the query `SELECT * from c`, in the `stocksdb` database in Cosmos DB.
13
-
***Return data**: The second section of code, **app.http**, receives that data into the function as an input in `context.extraInputs` then returns it as the response body back to the client.
14
-
11
+
-**Get data**: The first section of code, **cosmosInput**, gets all the items in the `stocks` table, with the query `SELECT * from c`, in the `stocksdb` database in Cosmos DB.
12
+
-**Return data**: The second section of code, **app.http**, receives that data into the function as an input in `context.extraInputs` then returns it as the response body back to the client.
15
13
16
14
### Client
17
15
@@ -29,17 +27,17 @@ The server and client code is relatively straightforward: get all data, display
29
27
30
28
## Analysis of prototype solution
31
29
32
-
As a Tailwind Traders engineer, you've identified some of the drawbacks of this timer-based polling approach.
30
+
As a Tailwind Traders engineer, you identified some of the drawbacks in this timer-based polling approach.
33
31
34
-
***Unnecessary API requests**: In the timer-based polling prototype, the client application contacts the server whether or not changes exist to the underlying data.
35
-
***Unnecessary page refreshes**: Once data is returned from the server, the entire list of stocks is updated on the web page, even if no data has changed. This polling mechanism is an inefficient solution.
36
-
***Polling intervals**: Selecting the best polling interval for your scenario is also a challenge. Polling forces you to make a choice between how much each call to the backend costs and how quickly you want your app to respond to new data. Delays often exist between the time that new data becomes available and the time that the app detects it. The following illustration shows the issue.
32
+
-**Unnecessary API requests**: In the timer-based polling prototype, the client application contacts the server whether or not changes exist to the underlying data.
33
+
-**Unnecessary page refreshes**: Once data is returned from the server, the entire list of stocks is updated on the web page, even if no data changes. This polling mechanism is an inefficient solution.
34
+
-**Polling intervals**: Selecting the best polling interval for your scenario is also a challenge. Polling forces you to make a choice between how much each call to the backend costs and how quickly you want your app to respond to new data. Delays often exist between the time that new data becomes available and the time that the app detects it. The following illustration shows the issue.
37
35
38
36

39
-
37
+
40
38
In the worst case, the potential delay for detecting new data is equal to the polling interval. So why not use a smaller interval?
41
39
42
-
***Amount of data**: As the application scales, the amount of data exchanged between the client and server becomes a problem. Each HTTP request header includes hundreds of bytes of data along with the session's cookie. All this overhead, especially when under heavy load, creates wasted resources and unnecessarily taxes the server.
40
+
-**Amount of data**: As the application scales, the amount of data exchanged between the client and server becomes a problem. Each HTTP request header includes hundreds of bytes of data along with the session's cookie. All this overhead, especially when under heavy load, creates wasted resources and unnecessarily taxes the server.
43
41
44
42
Now that you're more familiar with the prototype, it's time to get the application running on your machine.
45
43
@@ -52,6 +50,6 @@ In the *local.settings.json* file of the Functions App, the `Host` section inclu
52
50
53
51
This configuration allows a web application running at *localhost:3000* to make requests to the function app running at *localhost:7071*. The property `CORSCredentials` tells the function app to accept credential cookies from the request.
54
52
55
-
Cross-origin resource sharing (CORS) is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
53
+
Cross-origin resource sharing (CORS) is an HTTP feature that enables a web application running under one domain to access resources in another domain. Web browsers implement a security restriction known as same-origin policy that prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain (the origin domain) to call APIs in another domain.
56
54
57
-
When running locally, CORS is configured for you in the sample's local.settings.json file, which is never published. When you deploy the client app (unit 7), you have to also update the CORS settings in the function app to allow access from the client app.
55
+
When you run locally, CORS is configured for you in the sample's local.settings.json file, which is never published. When you deploy the client app (unit 7), you have to also update the CORS settings in the function app to allow access from the client app.
Copy file name to clipboardExpand all lines: learn-pr/advocates/automatic-update-of-a-webapp-using-azure-functions-and-signalr/includes/3-exercise-analyze-limitations-of-polling-in-a-web-app.md
+7-10Lines changed: 7 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@ Before you change the prototype, you need to run it to validate the assumptions.
2
2
3
3
## Create Azure resources
4
4
5
-
1. In a separate browser tab or window, fork the sample repository on GitHub with the following link: [mslearn-advocates.azure-functions-and-signalr](https://github.com/MicrosoftDocs/mslearn-advocates.azure-functions-and-signalr/fork). This allows you to push your changes to your own version of the source code. This is a required step in order to deploy the source code to Azure later in the module.
5
+
1. In a separate browser tab or window, fork the sample repository on GitHub with the following link: [mslearn-advocates.azure-functions-and-signalr](https://github.com/MicrosoftDocs/mslearn-advocates.azure-functions-and-signalr/fork). This fork allows you to push your changes to your own version of the source code. This step is required in order to deploy the source code to Azure later in the module.
6
6
7
7
1. In the terminal, clone your forked repository. In the following command, replace `MicrosoftDocs` with your account:
8
8
@@ -40,7 +40,7 @@ Before you change the prototype, you need to run it to validate the assumptions.
40
40
41
41
This default subscription is used to create the Azure resources.
42
42
43
-
1. Create the Azure resources and upload the sample data to the database. The process may take a few minutes to complete.
43
+
1. Create the Azure resources and upload the sample data to the database. The process can take a few minutes to complete.
@@ -69,7 +69,6 @@ Before you change the prototype, you need to run it to validate the assumptions.
69
69
Seed data added. Symbol DEF
70
70
Seed data added. Symbol GHI
71
71
```
72
-
73
72
74
73
1. In the terminal, navigate to the **root** folder.
75
74
@@ -86,26 +85,24 @@ Before you change the prototype, you need to run it to validate the assumptions.
86
85
cd start/server && npm install && cd ../..
87
86
```
88
87
89
-
1. If the notification asks you to select an Azure functions app for the workspace, select `start/server`. This is the function app that you'll use to run the server-side code.
88
+
1. If the notification asks you to select an Azure functions app for the workspace, select `start/server`. This is the function app that you'll use to run the server-side code.
90
89
91
90
1. If you receive a notification about installing the latest Azure Functions Core Tools, select**Install**.
92
91
93
92
## Get the client and server URLs
94
93
95
-
When running locally, the client and server applications need to know where to find each other. The URLs are:
94
+
When you're running locally, the client and server applications need to know where to find each other. The URLs are:
96
95
97
96
- **Client**: http://localhost:3000
98
97
- **Server**: http://localhost:7071
99
98
100
-
101
99
## Update local settings for the Azure Functions app
102
100
103
101
Add the connection strings to the prototype's Azure Functions app.
104
102
105
103
1. Create the **./start/server/local.settings.json** file and paste in the following. This file has the configuration settings for the local functions project.
1. Arrange your browser windows so you can see the terminal and the prototype of the stock prices at the same time.
159
156
1. In the prototype browser window, open the browser's developer tools. Notice the browser is making a request to the API every 5 seconds for all the data, even though the data hasn't changed.
160
-
1. In the browser window, watch the output forthe Azure Functions app. A single stock price changes every minute. When the pricein the API changes, the next client fetch of all data includes that change.
157
+
1. In the browser window, watch the output for the Azure Functions app. A single stock price changes every minute. When the price in the API changes, the next client fetch of all data includes that change.
161
158
162
159
:::image type="content" source="../media/visual-studio-code-terminal-output-stock-change.png" alt-text="Screenshot of Visual Studio Code terminal showing console output of the stock price change.":::
163
160
164
161
1. In both the terminals for client and server, stop the applications with <kbd>Ctrl</kbd> + <kbd>C</kbd> or kill the terminal by selecting the trashcan icon.
165
162
166
-
In this unit, you ran the prototype. While the client does run successfully, it isn't efficient. While each individual client may not notice this with such a small number of stocks, that will change as the number of stocks grows and the number of clients pull from the server. The prototype can be improved. Let's learn how in the next unit.
163
+
In this unit, you ran the prototype. While the client does run successfully, it isn't efficient. While each individual client might not notice this with such a small number of stocks, that will change as the number of stocks grows and the number of clients pull from the server. The prototype can be improved. Let's learn how in the next unit.
0 commit comments