Skip to content

Commit 8a9c683

Browse files
committed
Adding
1 parent be12cef commit 8a9c683

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

articles/azure-web-pubsub/tutorial-build-chat.md

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ms.author: lianwei
66
ms.service: azure-web-pubsub
77
ms.custom: devx-track-azurecli
88
ms.topic: tutorial
9-
ms.date: 12/21/2023
9+
ms.date: 04/11/2024
1010
---
1111

1212
# Tutorial: Create a chat app with Azure Web PubSub service
@@ -369,7 +369,6 @@ const { WebPubSubServiceClient } = require('@azure/web-pubsub');
369369
370370
const app = express();
371371
const hubName = 'Sample_ChatApp';
372-
const port = 8080;
373372
374373
let serviceClient = new WebPubSubServiceClient(process.env.WebPubSubConnectionString, hubName);
375374
@@ -397,7 +396,7 @@ Rerun the server by running `node server`.
397396
398397
# [Java](#tab/java)
399398
400-
First add Azure Web PubSub SDK dependency into the `dependencies` node of `pom.xml`:
399+
First add Azure Web PubSub SDK dependency and gson into the `dependencies` node of `pom.xml`:
401400
402401
```xml
403402
<!-- https://mvnrepository.com/artifact/com.azure/azure-messaging-webpubsub -->
@@ -406,6 +405,12 @@ First add Azure Web PubSub SDK dependency into the `dependencies` node of `pom.x
406405
<artifactId>azure-messaging-webpubsub</artifactId>
407406
<version>1.2.12</version>
408407
</dependency>
408+
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
409+
<dependency>
410+
<groupId>com.google.code.gson</groupId>
411+
<artifactId>gson</artifactId>
412+
<version>2.10.1</version>
413+
</dependency>
409414
```
410415
411416
Now let's add a `/negotiate` API to the `App.java` file to generate the token:
@@ -418,6 +423,8 @@ import com.azure.messaging.webpubsub.WebPubSubServiceClientBuilder;
418423
import com.azure.messaging.webpubsub.models.GetClientAccessTokenOptions;
419424
import com.azure.messaging.webpubsub.models.WebPubSubClientAccessToken;
420425
import com.azure.messaging.webpubsub.models.WebPubSubContentType;
426+
import com.google.gson.Gson;
427+
import com.google.gson.JsonObject;
421428
import io.javalin.Javalin;
422429
423430
public class App {
@@ -452,7 +459,10 @@ public class App {
452459
option.setUserId(id);
453460
WebPubSubClientAccessToken token = service.getClientAccessToken(option);
454461
ctx.contentType("application/json");
455-
String response = String.format("{\"url\":\"%s\"}", token.getUrl());
462+
Gson gson = new Gson();
463+
JsonObject jsonObject = new JsonObject();
464+
jsonObject.addProperty("url", token.getUrl());
465+
String response = gson.toJson(jsonObject);
456466
ctx.result(response);
457467
return;
458468
});
@@ -647,20 +657,20 @@ For now, you need to implement the event handler by your own in Java. The steps
647657
2. First we'd like to handle the abuse protection OPTIONS requests, we check if the header contains `WebHook-Request-Origin` header, and we return the header `WebHook-Allowed-Origin`. For simplicity for demo purpose, we return `*` to allow all the origins.
648658
```java
649659
650-
// validation: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#validation
660+
// validation: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#protection
651661
app.options("/eventhandler", ctx -> {
652662
ctx.header("WebHook-Allowed-Origin", "*");
653663
});
654664
```
655665
656666
3. Then we'd like to check if the incoming requests are the events we expect. Let's say we now care about the system `connected` event, which should contain the header `ce-type` as `azure.webpubsub.sys.connected`. We add the logic after abuse protection to broadcast the connected event to all clients so they can see who joined the chat room.
657667
```java
658-
// validation: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#validation
668+
// validation: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#protection
659669
app.options("/eventhandler", ctx -> {
660670
ctx.header("WebHook-Allowed-Origin", "*");
661671
});
662672
663-
// handle events: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#events
673+
// handle events: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#events
664674
app.post("/eventhandler", ctx -> {
665675
String event = ctx.header("ce-type");
666676
if ("azure.webpubsub.sys.connected".equals(event)) {
@@ -677,7 +687,7 @@ For now, you need to implement the event handler by your own in Java. The steps
677687
4. The `ce-type` of `message` event is always `azure.webpubsub.user.message`. Details see [Event message](./reference-cloud-events.md#message). We update the logic to handle messages that when a message comes in we broadcast the message in JSON format to all the connected clients.
678688
679689
```java
680-
// handle events: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#events
690+
// handle events: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#events
681691
app.post("/eventhandler", ctx -> {
682692
String event = ctx.header("ce-type");
683693
if ("azure.webpubsub.sys.connected".equals(event)) {
@@ -700,7 +710,7 @@ For now, you need to implement the event handler by your own in Python. The step
700710
701711
2. First we'd like to handle the abuse protection OPTIONS requests, we check if the header contains `WebHook-Request-Origin` header, and we return the header `WebHook-Allowed-Origin`. For simplicity for demo purpose, we return `*` to allow all the origins.
702712
```python
703-
# validation: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#validation
713+
# validation: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#protection
704714
@app.route('/eventhandler', methods=['OPTIONS'])
705715
def handle_event():
706716
if request.method == 'OPTIONS':
@@ -713,8 +723,8 @@ For now, you need to implement the event handler by your own in Python. The step
713723
714724
3. Then we'd like to check if the incoming requests are the events we expect. Let's say we now care about the system `connected` event, which should contain the header `ce-type` as `azure.webpubsub.sys.connected`. We add the logic after abuse protection:
715725
```python
716-
# validation: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#validation
717-
# handle events: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#events
726+
# validation: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#protection
727+
# handle events: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#events
718728
@app.route('/eventhandler', methods=['POST', 'OPTIONS'])
719729
def handle_event():
720730
if request.method == 'OPTIONS':
@@ -886,7 +896,9 @@ Open `http://localhost:8080/index.html`. You can input your user name and start
886896
887897
## Lazy Auth with `connect` event handler
888898
889-
In previous sections, we demonstrate how to use [negotiate](#add-negotiate-endpoint) endpoint to return the Web PubSub service URL and the JWT access token for the clients to connect to Web PubSub service. In some cases, for example, edge devices that have limited resources, clients might prefer direct connect to Web PubSub resources. In such cases, you can configure `connect` event handler to lazy auth the clients, assign user ID to the clients, specify the groups the clients join once they connect, configure the permissions the clients have and WebSocket subprotocol as the WebSocket response to the client, etc. Details please refer to [connect event handler spec](./reference-client-events.md#connect). Now let's use `connect` event handler to acheive the similar as what the [negotiate](#negotiate) section does.
899+
In previous sections, we demonstrate how to use [negotiate](#add-negotiate-endpoint) endpoint to return the Web PubSub service URL and the JWT access token for the clients to connect to Web PubSub service. In some cases, for example, edge devices that have limited resources, clients might prefer direct connect to Web PubSub resources. In such cases, you can configure `connect` event handler to lazy auth the clients, assign user ID to the clients, specify the groups the clients join once they connect, configure the permissions the clients have and WebSocket subprotocol as the WebSocket response to the client, etc. Details please refer to [connect event handler spec](./reference-client-events.md#connect).
900+
901+
Now let's use `connect` event handler to acheive the similar as what the [negotiate](#negotiate) section does.
890902
891903
### Update hub settings
892904
@@ -903,7 +915,9 @@ az webpubsub hub update -n "<your-unique-resource-name>" -g "myResourceGroup" --
903915
904916
### Update upstream logic to handle connect event
905917
906-
Now let's update upstream logic to handle connect event. We could also remove the negotiate endpoint now. As similar to what we do in negotiate endpoint as demo purpose, we also read id from the query parameters. In connect event, the original client query is preserved in connect event requet body.
918+
Now let's update upstream logic to handle connect event. We could also remove the negotiate endpoint now.
919+
920+
As similar to what we do in negotiate endpoint as demo purpose, we also read id from the query parameters. In connect event, the original client query is preserved in connect event requet body.
907921
908922
# [C#](#tab/csharp)
909923
@@ -994,24 +1008,35 @@ app.listen(8080, () => console.log("server started"));
9941008
# [Java](#tab/java)
9951009
Now let's add the logic to handle the connect event `azure.webpubsub.sys.connect`:
9961010
```java
997-
// validation: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#validation
1011+
import com.google.gson.Gson;
1012+
import com.google.gson.JsonElement;
1013+
import com.google.gson.JsonObject;
1014+
1015+
// validation: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#protection
9981016
app.options("/eventhandler", ctx -> {
9991017
ctx.header("WebHook-Allowed-Origin", "*");
10001018
});
10011019
1002-
// handle events: https://azure.github.io/azure-webpubsub/references/protocol-cloudevents#events
1020+
// handle events: https://learn.microsoft.com/azure/azure-web-pubsub/reference-cloud-events#connect
10031021
app.post("/eventhandler", ctx -> {
10041022
String event = ctx.header("ce-type");
10051023
if ("azure.webpubsub.sys.connect".equals(event)) {
10061024
System.out.println("Connecting.");
1007-
if (){
1008-
ctx.status(200);
1025+
Gson gson = new Gson();
1026+
JsonObject requestBody = gson.fromJson(ctx.body(), JsonObject.class); // Parse JSON request body
1027+
if (requestBody.has("query")) {
1028+
JsonElement queryElement = requestBody.get("query");
1029+
if (queryObject.has("id")) {
1030+
ctx.status(200);
1031+
String id = queryObject.get("id").getAsString();
10091032
1033+
}
1034+
1035+
return;
10101036
} else {
10111037
ctx.status(401).text("missing user id");
10121038
10131039
}
1014-
String id = ctx.header("ce-userId");
10151040
} else if ("azure.webpubsub.sys.connected".equals(event)) {
10161041
String id = ctx.header("ce-userId");
10171042
System.out.println(id + " connected.");
@@ -1105,7 +1130,7 @@ Now let's update the web page to direct connect to Web PubSub service. One thing
11051130
11061131
### Rerun the server
11071132
1108-
Now [rerun the server](#run-the-web-server) and visit the web page following the instructions before. If you've stopped `awps-tunnel`, please also rerun the tunnel tool.
1133+
Now [rerun the server](#run-the-web-server) and visit the web page following the instructions before. If you've stopped `awps-tunnel`, please also [rerun the tunnel tool](#run-awps-tunnel-locally).
11091134
11101135
## Next steps
11111136

0 commit comments

Comments
 (0)