Communicate Realtime on Azure with Web PubSub

Published Mar 15 2022 07:45 PM 1,673 Views
Microsoft

Azure Web PubSub is a PaaS Service on Azure to send real-time messages and notifications between Web and Mobile applications using WebSockets. This uses a Publish/Subscribe model and allows sending notifications, updates, messages between various connected entities.

 

When to use it?

This Link lists down a set of use cases where it can be used; a quick glance:

  • Live Dashboard and Data Updates

  • Real-time Chats, Grouped Chat

  • Collaboration, Screen sharing Apps

  • Broadcasting Advertisements, Offers, Promotions

  • Supply Chain Control Tower - Notify Warehouses, Customers, Transporters - Real-time

  • Apps for People with Disability - Play Music or Videos for someone else

  • Remote Control Apps, Location Tracking Apps, Enterprise Automation Process

  • And many more...

 

What are we going to discuss here?

  • General Overview of Web PubSub components

  • Create Azure Web PubSub instance and configure

  • Connect multiple clients to the PubSub instance (Azure CLI); and then communicate with each other

  • Understand the concept of Upstream server; and how to build and use it

  • Understand programmatic ways of connecting to the PubSub instance (SDKs)

  • Extend these concepts to a Xamarin based Mobile application and build a simple chat app

  • Make the Chat app Intelligent with Azure Cognitive Service (Translator API) to have Multi-lingual Chat

 

Overview

Following are the main Components of the Azure Web PubSub service

  • Connection - An individual WebSocket connection connected to the Web PubSub service. A unique connection ID is assigned to this connection by the Web PubSub service after it is successfully established

  • Hub - A set of client connections. Multiple clients can connect to same Hub; and multiple Hub can be dded within same PubSub instance

  • Group - A subset of connections to the Hub. Thus making is perfect for Group based chat or communication apps. Each Group can be treated as a Chat room containing multiple client connections (Chat participants)

  • User - Connection belongs to one user. A user can have multiple connections

  • Upstream Server - This is Optional and can be used as Controlling element in the entire messaging system. All or designated Connected clients can get messages routed by Upstream server. This implements multiple Web PubSub Events viz. Connected, Disconnected, Login etc. and allow the messaging system to take appropriate decision while routing the messages to designated clients

  • Message - Can be sent to Upstream server which can then be routed to designated Connected clients Or can even be sent by one Connected client to another.

    So, think of a Supply Chain Control Tower scenario where each WareHouse can be a Connected client, each Transporter or even Customers, Upstream server can be the Control Tower itself - using Web PubSub, the entire system can create a messaging Mesh! So, WH1 can send messages to WH2 (WH1 -> WH2). Similarly WH1->WH2->C1->Trans2. This makes Intelligent Risk Analysis, Decision making, Optimised Routing etc. to be built faster and much easier!

 

Let us get into it....

Declare CLI variables

tenantId=""
subscriptionId=""
location=""
resourceGroup="pubsub-workshop-rg"
pubSubName="pubsub-connect-app"
hubName="testhub1"
group1="group1"
userId1="user1"
userId2="user2"

 

Prepare and Configure

# Login through Azure CLI
az login --tenant $tenantId

# Do you have the extension for Web PubSub? Check it!
az version

# If not Add the required extension
az extension add -n webpubsub

# Let us create a resource group for our work
az group create --name $resourceGroup -l $location
az group show --name $resourceGroup

 

Create Web PubSub instance

# Create the Web PubSub instance
az webpubsub create --name $pubSubName --resource-group $resourceGroup --location eastus --sku Free_F1

# Create the Hub which would host our groups, users etc.
az webpubsub hub create --hub-name $hubName --name $pubSubName --resource-group $resourceGroup \
--allow-anonymous true

 

Connect to Web PubSub

# Connect as user1
az webpubsub client start --name $pubSubName --resource-group $resourceGroup \
--hub-name $hubName --user-id $userId1

 

pubsub-connect-user1.png

 

# Connect as user2
az webpubsub client start --name $pubSubName --resource-group $resourceGroup \
--hub-name $hubName --user-id $userId2

 

pubsub-connect-user2.png

 

  • This returns a unique connectionId for the successful connection

  • Users can perform actions as described in usage section

  • Please note, these are options for clients connected through CLI. We will discuss how client connect through other ways can perform additional actions

 

joingroup
joingroup group1
{"type":"ack","ackId":1,"success":true}

 

pubsub-join-group1.png

 

sendtogroup
sendtogroup group1 "hello from user2"          
{"type":"ack","ackId":2,"success":true}

 

pubsub-group-message-user2.pngpubsub-group-message-user1.png

 

  • user1 joined group1

  • user2 joined group1

  • user2 sends message to the group group1; received by user1 as well since being connected to group1

 

leavegroup
leavegroup group1
{"type":"ack","ackId":2,"success":true}

 

Connect to a specific Connection

az webpubsub service connection send --connection-id "<connectionId>" \
--hub-name $hubName --name $pubSubName --resource-group $resourceGroup --payload "hello connect from server"

 

Broadcast Message to every Connected client

az webpubsub service broadcast --hub-name $hubName --name $pubSubName \
--resource-group $resourceGroup --payload "hello broadcast from server"

 

pubsub-broadcast-user1.pngpubsub-broadcast-user2.png

 

Send Message to a specific User

az webpubsub service user send --hub-name $hubName --name $pubSubName --resource-group $resourceGroup \
--user-id $userId1 --payload "hello from server for:$userId1"

 

Upstream Server

pubsub-overview.png

 

  • Upstream server is built as Serverless Azure Function; as we need this to be active only when some Web PubSub event occurs viz. Login, Connected, Disconnected etc.

  • User1 can send message directly to User2 with out doing a roundtrip to the Upstream server

  • Both User1 and User2 connects to Azure Web PubSub with multiple SubProtocols; requesting permission for specific actions e.g. joingroup, leavegroup, sendtogroup etc.

 

Build Serverless Upstream
[FunctionName("validate")]
public static HttpResponseMessage Validate([HttpTrigger(AuthorizationLevel.Anonymous, "options")]
HttpRequest req, [WebPubSubContext] WebPubSubContext wpsReq)
{
return wpsReq.Response;
}

[FunctionName("connect")]
public static object Connect([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
[WebPubSubContext] WebPubSubContext wpsReq)
{
 if (wpsReq.Request is PreflightRequest || wpsReq.ErrorMessage != null)
{
   return wpsReq.Response;
}
 var request = wpsReq.Request as ConnectEventRequest;
 return request.CreateResponse(request.ConnectionContext.UserId, null, null, null);
}

[FunctionName("message")]
public static async Task<HttpResponseMessage> Broadcast([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req, [WebPubSubContext] WebPubSubContext wpsReq, [WebPubSub(Connection = "PubSubConn", Hub = "PubSubHub")] IAsyncCollector<WebPubSubAction> actions)
{
 if (wpsReq.Request is PreflightRequest || wpsReq.ErrorMessage != null)
{
   return wpsReq.Response;
}
 if (wpsReq.Request is UserEventRequest request)
{                
   await actions.AddAsync(WebPubSubAction.CreateSendToAllAction(request.Data, request.DataType));
}

 return null;
}

[FunctionName("connected")]
public static async Task Connected(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
[WebPubSubContext] WebPubSubContext wpsReq,
[WebPubSub(Connection = "PubSubConn", Hub = "PubSubHub")] IAsyncCollector<WebPubSubAction> actions)
{

 await actions.AddAsync(new SendToAllAction
{
Data = BinaryData.FromString($"{wpsReq.Request.ConnectionContext.UserId} connected."),
   DataType = WebPubSubDataType.Text
});
}

[FunctionName("disconnected")]
[return: WebPubSub(Connection = "PubSubConn", Hub = "PubSubHub")]
public static WebPubSubAction Disconnect([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
                                        [WebPubSubContext] WebPubSubContext wpsReq)
{
 Console.WriteLine("Disconnected.");
 return new SendToAllAction
{
   Data = BinaryData.FromString($"{wpsReq.Request.ConnectionContext.UserId} disconnect."),
   DataType = WebPubSubDataType.Text
};
}

 

Environment Variables
{
   "IsEncrypted": false,
   "Values": {
       "AzureWebJobsStorage": "<strogae account or Azure Function>",
       "FUNCTIONS_WORKER_RUNTIME": "dotnet",
       "PubSubConn": "<pubsub connection string",
       "PubSubHub":  "<Hub name>"
  }
}

 

Build PubSub Client

using Azure.Messaging.WebPubSub;
using System.Net.WebSockets;

// initialize PubSub client to conenct to Azure Web PubSub
WebPubSubServiceClient kWebPubSubServiceClient = new WebPubSubServiceClient(kConnectionString,
                                                                           kHubNameString,
                                                                           new string[]
                                                                        {"webpubsub.joinLeaveGroup.group1",
                                                                          "webpubsub.sendToGroup.group1" });

// Authentication: Get Client Access Uri with Access Token
// Please note: Token is created for a 5 minutes window
var uri = kWebPubSubServiceClient.GetClientAccessUri(new TimeSpan(0, 5, 0), kUser1NameString);

// initialize Websocket client created for User1 with above permissions
var clientWebSocket = new ClientWebSocket();

// This will ensure that clients can directly communicate with each other
clientWebSocket.Options.AddSubProtocol("json.webpubsub.azure.v1");

// Let us connect the Websocket client to the Azure Web PubSub
await clientWebSocket.ConnectAsync(uri, CancellationToken.None);

 

Sending Messages from Web PubSub

// Web PubSub service sending Message to User1
await kWebPubSubServiceClient.SendToUserAsync(kUser1NameString, kTestMessageString);

// Web PubSub service sending Message to all Users connected to Group1
await kWebPubSubServiceClient.SendToGroupAsync(kGroupNameString, kTestMessageString);

// Web PubSub service Adding User1 to Group1
var resp = await kWebPubSubServiceClient.AddUserToGroupAsync(kGroupNameString, kUser1NameString);

// Web PubSub service Removing User2 from Group1
var resp = await kWebPubSubServiceClient.RemoveUserFromGroupAsync(kGroupNameString, kUser2NameString);

// Web PubSub service Closing connection for User1
await kWebPubSubServiceClient.CloseUserConnectionsAsync(kUser1NameString);

 

Sending Messages P2P

var uri = kWebPubSubServiceClient.GetClientAccessUri(new TimeSpan(0, 5, 0), kUser1NameString);

// Create Websocket instance with SubProtocol
var clientWebSocket = new ClientWebSocket();
clientWebSocket.Options.AddSubProtocol("json.webpubsub.azure.v1");

// Connect Websocket instance to the User1 connection
await clientWebSocket.ConnectAsync(uri, CancellationToken.None);

// User1 joins Group1
var joinMessage = JsonSerializer.Serialize(new
{
type = "joinGroup",
group = kGroupNameString,
ackId = 1000
});
await clientWebSocket.SendAsync(Encoding.UTF8.GetBytes(joinMessage), WebSocketMessageType.Text, true,
                               CancellationToken.None);

// User1 sends message to all users of Group1
var groupMessage = JsonSerializer.Serialize(new
{
   type = "sendToGroup",
   group = kGroupNameString,
   data = kTestMessageString,
   ackId = 1001
});
await clientWebSocket.SendAsync(Encoding.UTF8.GetBytes(groupMessage), WebSocketMessageType.Text, true,
                               CancellationToken.None);

 

Receiving Messages


var message = new ArraySegment<byte>(new byte[4096]);
await clientWebSocket.ReceiveAsync(message, CancellationToken.None);
Console.WriteLine(Encoding.UTF8.GetString(message));

 

Examples...

Multi lingual Chat App

pubsub-translator.png

 

  • Each Mobile client creates a WebSocket connection to Azure Web PubSub

  • Each client can send chat messages directly through Azure Web PubSub

  • An Upstream server exists, built with Azure Function, to handle client events - Login, Connected, Disconnected,

  • Each Mobile client can call Azure Cognitive Service to Translate the received chat message in any language and update its own UI

 

Supply Chain Control Tower App

pubsub-control-tower.png

 

  • Multiple business entities act as Web PubSub client and Control Tower App as Upstream server

  • Each client can send chat messages directly through Azure Web PubSub e.g. Warehouse <-> WareHouse, Warehouse <-> Customer, Customers <-> Factories etc.

  • Each Business client can be made more intelligent using Azure Cognitive Services and can take important decisions and share with other clients; resulting in a vibrant Control Tower system

 

References

%3CLINGO-SUB%20id%3D%22lingo-sub-3256264%22%20slang%3D%22en-US%22%3ECommunicate%20Realtime%20on%20Azure%20with%20Web%20PubSub%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-3256264%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%20class%3D%22md-meta-i-c%20md-link%20md-expand%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Foverview%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%20is%20a%20PaaS%20Service%20on%20Azure%20to%20send%20real-time%20messages%20and%20notifications%20between%20Web%20and%20Mobile%20applications%20using%20WebSockets.%20This%20uses%20a%20Publish%2FSubscribe%20model%20and%20allows%20sending%20notifications%2C%20updates%2C%20messages%20between%20various%20connected%20entities.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-391968592%22%20id%3D%22toc-hId-415894551%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EWhen%20to%20use%20it%3F%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EThis%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Foverview%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3ELink%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20lists%20down%20a%20set%20of%20use%20cases%20where%20it%20can%20be%20used%3B%20a%20quick%20glance%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3ELive%20Dashboard%20and%20Data%20Updates%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EReal-time%20Chats%2C%20Grouped%20Chat%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3ECollaboration%2C%20Screen%20sharing%20Apps%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EBroadcasting%20Advertisements%2C%20Offers%2C%20Promotions%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3ESupply%20Chain%20Control%20Tower%20-%20Notify%20Warehouses%2C%20Customers%2C%20Transporters%20-%20Real-time%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EApps%20for%20People%20with%20Disability%20-%20Play%20Music%20or%20Videos%20for%20someone%20else%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3ERemote%20Control%20Apps%2C%20Location%20Tracking%20Apps%2C%20Enterprise%20Automation%20Process%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3EAnd%20many%20more...%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--1415485871%22%20id%3D%22toc-hId--1391559912%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EWhat%20are%20we%20going%20to%20discuss%20here%3F%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EGeneral%20Overview%20of%20Web%20PubSub%20components%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3ECreate%20Azure%20Web%20PubSub%20instance%20and%20configure%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EConnect%20multiple%20clients%20to%20the%20PubSub%20instance%20(%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20CLI%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E)%3B%20and%20then%20communicate%20with%20each%20other%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EUnderstand%20the%20concept%20of%20Upstream%20server%3B%20and%20how%20to%20build%20and%20use%20it%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EUnderstand%20programmatic%20ways%20of%20connecting%20to%20the%20PubSub%20instance%20(%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3ESDKs%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E)%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EExtend%20these%20concepts%20to%20a%20Xamarin%20based%20Mobile%20application%20and%20build%20a%20simple%20chat%20app%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3EMake%20the%20Chat%20app%20Intelligent%20with%20Azure%20Cognitive%20Service%20(%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3ETranslator%20API%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E)%20to%20have%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EMulti-lingual%20Chat%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FEM%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-1072026962%22%20id%3D%22toc-hId-1095952921%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EOverview%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EFollowing%20are%20the%20main%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Fkey-concepts%23terms%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EComponents%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20of%20the%20Azure%20Web%20PubSub%20service%3C%2FSPAN%3E%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EConnection%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20An%20individual%20WebSocket%20connection%20connected%20to%20the%20Web%20PubSub%20service.%20A%20unique%20connection%20ID%20is%20assigned%20to%20this%20connection%20by%20the%20Web%20PubSub%20service%20after%20it%20is%20successfully%20established%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EHub%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20A%20set%20of%20client%20connections.%20Multiple%20clients%20can%20connect%20to%20same%20Hub%3B%20and%20multiple%20Hub%20can%20be%20dded%20within%20same%20PubSub%20instance%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EGroup%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20A%20subset%20of%20connections%20to%20the%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EHub%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E.%20Thus%20making%20is%20perfect%20for%20Group%20based%20chat%20or%20communication%20apps.%20Each%20Group%20can%20be%20treated%20as%20a%20Chat%20room%20containing%20multiple%20client%20connections%20(%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EChat%20participants%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E)%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EUser%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20Connection%20belongs%20to%20one%20user.%20A%20user%20can%20have%20multiple%20connections%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EUpstream%20Server%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20This%20is%20Optional%20and%20can%20be%20used%20as%20Controlling%20element%20in%20the%20entire%20messaging%20system.%20All%20or%20designated%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EConnected%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20clients%20can%20get%20messages%20routed%20by%20Upstream%20server.%20This%20implements%20multiple%20Web%20PubSub%20Events%20viz.%20Connected%2C%20Disconnected%2C%20Login%20etc.%20and%20allow%20the%20messaging%20system%20to%20take%20appropriate%20decision%20while%20routing%20the%20messages%20to%20designated%20clients%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EMessage%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20-%20Can%20be%20sent%20to%20Upstream%20server%20which%20can%20then%20be%20routed%20to%20designated%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EConnected%20clients%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20Or%20can%20even%20be%20sent%20by%20one%20Connected%20client%20to%20another.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3ESo%2C%20think%20of%20a%20Supply%20Chain%20Control%20Tower%20scenario%20where%20each%20WareHouse%20can%20be%20a%20Connected%20client%2C%20each%20Transporter%20or%20even%20Customers%2C%20Upstream%20server%20can%20be%20the%20Control%20Tower%20itself%20-%20using%20Web%20PubSub%2C%20the%20entire%20system%20can%20create%20a%20messaging%20Mesh!%20So%2C%20WH1%20can%20send%20messages%20to%20WH2%20(WH1%20-%26gt%3B%20WH2).%20Similarly%20WH1-%26gt%3BWH2-%26gt%3BC1-%26gt%3BTrans2.%20This%20makes%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EIntelligent%20Risk%20Analysis%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%2C%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EDecision%20making%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%2C%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EOptimised%20Routing%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20etc.%20to%20be%20built%20faster%20and%20much%20easier!%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--735427501%22%20id%3D%22toc-hId--711501542%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3ELet%20us%20get%20into%20it....%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--1841817386%22%20id%3D%22toc-hId--1817891427%22%3E%3CSPAN%20class%3D%22md-plain%22%3EDeclare%20CLI%20variables%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EtenantId%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EsubscriptionId%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3Elocation%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EresourceGroup%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22pubsub-workshop-rg%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EpubSubName%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22pubsub-connect-app%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EhubName%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22testhub1%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3Egroup1%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22group1%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EuserId1%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22user1%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3EuserId2%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22user2%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-645695447%22%20id%3D%22toc-hId-669621406%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EPrepare%20and%20Configure%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Login%20through%20Azure%20CLI%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20login%20%3CSPAN%20class%3D%22cm-attribute%22%3E--tenant%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24tenantId%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Do%20you%20have%20the%20extension%20for%20Web%20PubSub%3F%20Check%20it!%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20version%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20If%20not%20Add%20the%20required%20extension%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20extension%20add%20%3CSPAN%20class%3D%22cm-attribute%22%3E-n%3C%2FSPAN%3E%20webpubsub%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Let%20us%20create%20a%20resource%20group%20for%20our%20work%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20group%20create%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E-l%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24location%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20group%20show%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--1161759016%22%20id%3D%22toc-hId--1137833057%22%3E%3CSPAN%20class%3D%22md-plain%22%3ECreate%20Web%20PubSub%20instance%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Create%20the%20Web%20PubSub%20instance%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20webpubsub%20create%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--location%3C%2FSPAN%3E%20eastus%20%3CSPAN%20class%3D%22cm-attribute%22%3E--sku%3C%2FSPAN%3E%20Free_F1%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Create%20the%20Hub%20which%20would%20host%20our%20groups%2C%20users%20etc.%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20webpubsub%20hub%20create%20%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--allow-anonymous%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-atom%22%3Etrue%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%20md-focus%22%20id%3D%22toc-hId-1325753817%22%20id%3D%22toc-hId-1349679776%22%3E%3CSPAN%20class%3D%22md-plain%22%3EConnect%20to%20Web%20PubSub%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Connect%20as%20user1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20webpubsub%20client%20%3CSPAN%20class%3D%22cm-builtin%22%3Estart%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--user-id%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24userId1%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-connect-user1.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356109i8A8475D724103831%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-connect-user1.png%22%20alt%3D%22pubsub-connect-user1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%23%20Connect%20as%20user2%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3Eaz%20webpubsub%20client%20%3CSPAN%20class%3D%22cm-builtin%22%3Estart%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--user-id%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24userId2%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-connect-user2.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356110iE002657F2B454F82%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-connect-user2.png%22%20alt%3D%22pubsub-connect-user2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EThis%20returns%20a%20unique%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CSTRONG%3E%3CSPAN%20class%3D%22md-plain%22%3EconnectionId%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20for%20the%20successful%20connection%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EUsers%20can%20perform%20actions%20as%20described%20in%20usage%20section%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EPlease%20note%2C%20these%20are%20options%20for%20clients%20connected%20through%20CLI.%20We%20will%20discuss%20how%20client%20connect%20through%20other%20ways%20can%20perform%20additional%20actions%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH5%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-2016315291%22%20id%3D%22toc-hId-2040241250%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3Ejoingroup%3C%2FSPAN%3E%3C%2FH5%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Ejoingroup%20group1%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3CSPAN%20class%3D%22cm-string%22%3E%22type%22%3C%2FSPAN%3E%3A%3CSPAN%20class%3D%22cm-string%22%3E%22ack%22%3C%2FSPAN%3E%2C%3CSPAN%20class%3D%22cm-string%22%3E%22ackId%22%3C%2FSPAN%3E%3A1%2C%3CSPAN%20class%3D%22cm-string%22%3E%22success%22%3C%2FSPAN%3E%3Atrue%7D%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-join-group1.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356111i14DE6C8C7A94E4E3%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-join-group1.png%22%20alt%3D%22pubsub-join-group1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH5%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-208860828%22%20id%3D%22toc-hId-232786787%22%3E%3CSPAN%20class%3D%22md-plain%22%3Esendtogroup%3C%2FSPAN%3E%3C%2FH5%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Esendtogroup%20group1%20%3CSPAN%20class%3D%22cm-string%22%3E%22hello%20from%20user2%22%3C%2FSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3CSPAN%20class%3D%22cm-string%22%3E%22type%22%3C%2FSPAN%3E%3A%3CSPAN%20class%3D%22cm-string%22%3E%22ack%22%3C%2FSPAN%3E%2C%3CSPAN%20class%3D%22cm-string%22%3E%22ackId%22%3C%2FSPAN%3E%3A2%2C%3CSPAN%20class%3D%22cm-string%22%3E%22success%22%3C%2FSPAN%3E%3Atrue%7D%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-group-message-user2.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356112i2B46D66DFE8FE9DE%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-group-message-user2.png%22%20alt%3D%22pubsub-group-message-user2.png%22%20%2F%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-group-message-user1.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356113iAD27BFCE65C378DA%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-group-message-user1.png%22%20alt%3D%22pubsub-group-message-user1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-pair-s%20md-expand%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Euser1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20joined%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Egroup1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Euser2%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20joined%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Egroup1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Euser2%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20sends%20message%20to%20the%20group%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Egroup1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%3B%20received%20by%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Euser1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20as%20well%20since%20being%20connected%20to%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20md-expand%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Egroup1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH5%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-1558311042%22%20id%3D%22toc-hId-1582237001%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3Eleavegroup%3C%2FSPAN%3E%3C%2FH5%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Eleavegroup%20group1%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3CSPAN%20class%3D%22cm-string%22%3E%22type%22%3C%2FSPAN%3E%3A%3CSPAN%20class%3D%22cm-string%22%3E%22ack%22%3C%2FSPAN%3E%2C%3CSPAN%20class%3D%22cm-string%22%3E%22ackId%22%3C%2FSPAN%3E%3A2%2C%3CSPAN%20class%3D%22cm-string%22%3E%22success%22%3C%2FSPAN%3E%3Atrue%7D%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--378226140%22%20id%3D%22toc-hId--354300181%22%3E%3CSPAN%20class%3D%22md-plain%22%3EConnect%20to%20a%20specific%20Connection%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Eaz%20webpubsub%20%3CSPAN%20class%3D%22cm-builtin%22%3Eservice%3C%2FSPAN%3E%20connection%20send%20%3CSPAN%20class%3D%22cm-attribute%22%3E--connection-id%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22%3CCONNECTIONID%3E%22%3C%2FCONNECTIONID%3E%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--payload%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22hello%20connect%20from%20server%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-2109286693%22%20id%3D%22toc-hId-2133212652%22%3E%3CSPAN%20class%3D%22md-plain%22%3EBroadcast%20Message%20to%20every%20Connected%20client%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Eaz%20webpubsub%20%3CSPAN%20class%3D%22cm-builtin%22%3Eservice%3C%2FSPAN%3E%20broadcast%20%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--payload%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22hello%20broadcast%20from%20server%22%3C%2FSPAN%3E%20%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-broadcast-user1.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356115i1B7DB467BCF709F5%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-broadcast-user1.png%22%20alt%3D%22pubsub-broadcast-user1.png%22%20%2F%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-broadcast-user2.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356114iF95DC1813B461B4F%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-broadcast-user2.png%22%20alt%3D%22pubsub-broadcast-user2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-301832230%22%20id%3D%22toc-hId-325758189%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3ESend%20Message%20to%20a%20specific%20User%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22bash%22%20spellcheck%3D%22false%22%3E%3CSPAN%3Eaz%20webpubsub%20%3CSPAN%20class%3D%22cm-builtin%22%3Eservice%3C%2FSPAN%3E%20user%20send%20%3CSPAN%20class%3D%22cm-attribute%22%3E--hub-name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24hubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--name%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24pubSubName%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--resource-group%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24resourceGroup%3C%2FSPAN%3E%20%5C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-attribute%22%3E--user-id%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3E%24userId1%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-attribute%22%3E--payload%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22hello%20from%20server%20for%3A%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-def%22%3E%24userId1%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%20md-focus%22%20id%3D%22toc-hId--1505622233%22%20id%3D%22toc-hId--1481696274%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EUpstream%20Server%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CP%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-overview.png%22%20style%3D%22width%3A%20456px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356116iDF57550C898EB0D1%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-overview.png%22%20alt%3D%22pubsub-overview.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EUpstream%20server%20is%20built%20as%20Serverless%20Azure%20Function%3B%20as%20we%20need%20this%20to%20be%20active%20only%20when%20some%20Web%20PubSub%20event%20occurs%20viz.%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3ELogin%2C%20Connected%2C%20Disconnected%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20etc.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EUser1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20can%20send%20message%20directly%20to%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EUser2%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20with%20out%20doing%20a%20roundtrip%20to%20the%20Upstream%20server%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3EBoth%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EUser1%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20and%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EUser2%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20connects%20to%20Azure%20Web%20PubSub%20with%20multiple%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Ftutorial-subprotocol%3Ftabs%3Dcsharp%23using-a-subprotocol%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3ESubProtocols%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%3B%20requesting%20permission%20for%20specific%20actions%20e.g.%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3Ejoingroup%2C%20leavegroup%2C%20sendtogroup%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%20etc.%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH5%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-1110973319%22%20id%3D%22toc-hId-1134899278%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EBuild%20Serverless%20Upstream%3C%2FSPAN%3E%3C%2FH5%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22c%23%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-variable%22%3EFunctionName%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22validate%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Epublic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Estatic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EHttpResponseMessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EValidate%3C%2FSPAN%3E(%5B%3CSPAN%20class%3D%22cm-variable%22%3EHttpTrigger%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EAuthorizationLevel%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAnonymous%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-string%22%3E%22options%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EHttpRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Ereq%3C%2FSPAN%3E%2C%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EResponse%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-variable%22%3EFunctionName%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22connect%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Epublic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Estatic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3Eobject%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EConnect%3C%2FSPAN%3E(%5B%3CSPAN%20class%3D%22cm-variable%22%3EHttpTrigger%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EAuthorizationLevel%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAnonymous%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-string%22%3E%22post%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EHttpRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Ereq%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Eif%3C%2FSPAN%3E%20(%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ERequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eis%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EPreflightRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%7C%7C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EErrorMessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E!%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EResponse%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Erequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ERequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eas%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EConnectEventRequest%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Erequest%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ECreateResponse%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Erequest%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EConnectionContext%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EUserId%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-variable%22%3EFunctionName%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22message%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Epublic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Estatic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3ETask%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26lt%3B%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EHttpResponseMessage%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EBroadcast%3C%2FSPAN%3E(%5B%3CSPAN%20class%3D%22cm-variable%22%3EHttpTrigger%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EAuthorizationLevel%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAnonymous%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-string%22%3E%22post%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EHttpRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Ereq%3C%2FSPAN%3E%2C%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E%2C%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSub%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EConnection%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubConn%22%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EHub%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubHub%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EIAsyncCollector%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26lt%3B%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubAction%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Eactions%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Eif%3C%2FSPAN%3E%20(%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ERequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eis%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EPreflightRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%7C%7C%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EErrorMessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E!%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EResponse%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Eif%3C%2FSPAN%3E%20(%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ERequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eis%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EUserEventRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Erequest%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Eactions%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAddAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubAction%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ECreateSendToAllAction%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Erequest%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EData%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3Erequest%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EDataType%3C%2FSPAN%3E))%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-atom%22%3Enull%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-variable%22%3EFunctionName%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22connected%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Epublic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Estatic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Easync%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3ETask%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EConnected%3C%2FSPAN%3E(%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EHttpTrigger%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EAuthorizationLevel%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAnonymous%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-string%22%3E%22post%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EHttpRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Ereq%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSub%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EConnection%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubConn%22%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EHub%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubHub%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EIAsyncCollector%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26lt%3B%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubAction%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26gt%3B%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Eactions%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Eactions%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAddAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3ESendToAllAction%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%20%20%3CSPAN%20class%3D%22cm-variable%22%3EData%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EBinaryData%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EFromString%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3E%24%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%7BwpsReq.Request.ConnectionContext.UserId%7D%20connected.%22%3C%2FSPAN%3E)%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EDataType%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubDataType%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EText%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7D)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-variable%22%3EFunctionName%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22disconnected%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%5B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%3A%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSub%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EConnection%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubConn%22%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EHub%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22PubSubHub%22%3C%2FSPAN%3E)%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Epublic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Estatic%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubAction%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EDisconnect%3C%2FSPAN%3E(%5B%3CSPAN%20class%3D%22cm-variable%22%3EHttpTrigger%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EAuthorizationLevel%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAnonymous%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-string%22%3E%22post%22%3C%2FSPAN%3E)%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EHttpRequest%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3Ereq%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%5B%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%5D%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubContext%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EwpsReq%3C%2FSPAN%3E)%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EConsole%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EWriteLine%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22Disconnected.%22%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Ereturn%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3ESendToAllAction%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EData%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EBinaryData%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EFromString%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3E%24%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-string%22%3E%22%7BwpsReq.Request.ConnectionContext.UserId%7D%20disconnect.%22%3C%2FSPAN%3E)%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EDataType%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubDataType%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EText%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%7D%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH5%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--696481144%22%20id%3D%22toc-hId--672555185%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EEnvironment%20Variables%3C%2FSPAN%3E%3C%2FH5%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22json%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22IsEncrypted%22%3C%2FSPAN%3E%3A%20%3CSPAN%20class%3D%22cm-atom%22%3Efalse%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22Values%22%3C%2FSPAN%3E%3A%20%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22AzureWebJobsStorage%22%3C%2FSPAN%3E%3A%20%3CSPAN%20class%3D%22cm-string%22%3E%22%3CSTROGAE%20account%3D%22%22%20or%3D%22%22%20azure%3D%22%22%20function%3D%22%22%3E%22%3C%2FSTROGAE%3E%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22FUNCTIONS_WORKER_RUNTIME%22%3C%2FSPAN%3E%3A%20%3CSPAN%20class%3D%22cm-string%22%3E%22dotnet%22%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22PubSubConn%22%3C%2FSPAN%3E%3A%20%3CSPAN%20class%3D%22cm-string%22%3E%22%3CPUBSUB%20connection%3D%22%22%20string%3D%22%22%3E%2C%3C%2FPUBSUB%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%20cm-property%22%3E%22PubSubHub%22%3C%2FSPAN%3E%3A%20%26nbsp%3B%3CSPAN%20class%3D%22cm-string%22%3E%22%3CHUB%20name%3D%22%22%3E%22%3C%2FHUB%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%20%7D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-1661948970%22%20id%3D%22toc-hId-1685874929%22%3E%3CSPAN%20class%3D%22md-plain%22%3EBuild%20PubSub%20Client%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22c%23%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eusing%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EAzure%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EMessaging%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSub%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eusing%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3ESystem%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENet%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EWebSockets%3C%2FSPAN%3E%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20initialize%20PubSub%20client%20to%20conenct%20to%20Azure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubServiceClient%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EWebPubSubServiceClient%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkConnectionString%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EkHubNameString%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3Estring%3C%2FSPAN%3E%5B%5D%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%20%7B%3CSPAN%20class%3D%22cm-string%22%3E%22webpubsub.joinLeaveGroup.group1%22%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%3CSPAN%20class%3D%22cm-string%22%3E%22webpubsub.sendToGroup.group1%22%3C%2FSPAN%3E%20%7D)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Authentication%3A%20Get%20Client%20Access%20Uri%20with%20Access%20Token%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Please%20note%3A%20Token%20is%20created%20for%20a%205%20minutes%20window%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Euri%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EGetClientAccessUri%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3ETimeSpan%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-number%22%3E0%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-number%22%3E5%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-number%22%3E0%3C%2FSPAN%3E)%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkUser1NameString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20initialize%20Websocket%20client%20created%20for%20User1%20with%20above%20permissions%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EclientWebSocket%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EClientWebSocket%3C%2FSPAN%3E()%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20This%20will%20ensure%20that%20clients%20can%20directly%20communicate%20with%20each%20other%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EOptions%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAddSubProtocol%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22json.webpubsub.azure.v1%22%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Let%20us%20connect%20the%20Websocket%20client%20to%20the%20Azure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EConnectAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Euri%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3ECancellationToken%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENone%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--145505493%22%20id%3D%22toc-hId--121579534%22%3E%3CSPAN%20class%3D%22md-plain%22%3ESending%20Messages%20from%20Web%20PubSub%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22C%23%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Web%20PubSub%20service%20sending%20Message%20to%20User1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESendToUserAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkUser1NameString%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkTestMessageString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Web%20PubSub%20service%20sending%20Message%20to%20all%20Users%20connected%20to%20Group1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESendToGroupAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkGroupNameString%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkTestMessageString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Web%20PubSub%20service%20Adding%20User1%20to%20Group1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Eresp%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAddUserToGroupAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkGroupNameString%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkUser1NameString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Web%20PubSub%20service%20Removing%20User2%20from%20Group1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Eresp%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ERemoveUserFromGroupAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkGroupNameString%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkUser2NameString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Web%20PubSub%20service%20Closing%20connection%20for%20User1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ECloseUserConnectionsAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EkUser1NameString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--1952959956%22%20id%3D%22toc-hId--1929033997%22%3E%3CSPAN%20class%3D%22md-plain%22%3ESending%20Messages%20P2P%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22c%23%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Euri%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkWebPubSubServiceClient%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EGetClientAccessUri%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3ETimeSpan%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-number%22%3E0%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-number%22%3E5%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-number%22%3E0%3C%2FSPAN%3E)%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EkUser1NameString%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Create%20Websocket%20instance%20with%20SubProtocol%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EclientWebSocket%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EClientWebSocket%3C%2FSPAN%3E()%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EOptions%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EAddSubProtocol%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-string%22%3E%22json.webpubsub.azure.v1%22%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20Connect%20Websocket%20instance%20to%20the%20User1%20connection%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EConnectAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Euri%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3ECancellationToken%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENone%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20User1%20joins%20Group1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EjoinMessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EJsonSerializer%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESerialize%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%20%20%3CSPAN%20class%3D%22cm-variable%22%3Etype%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22joinGroup%22%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%20%20%3CSPAN%20class%3D%22cm-keyword%22%3Egroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkGroupNameString%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%20%20%20%3CSPAN%20class%3D%22cm-variable%22%3EackId%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-number%22%3E1000%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESendAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EEncoding%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EUTF8%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EGetBytes%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EjoinMessage%3C%2FSPAN%3E)%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EWebSocketMessageType%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EText%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-atom%22%3Etrue%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3ECancellationToken%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENone%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-comment%22%3E%2F%2F%20User1%20sends%20message%20to%20all%20users%20of%20%20Group1%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3EgroupMessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EJsonSerializer%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESerialize%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3Etype%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-string%22%3E%22sendToGroup%22%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-keyword%22%3Egroup%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkGroupNameString%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3Edata%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EkTestMessageString%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3EackId%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-number%22%3E1001%3C%2FSPAN%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%7D)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ESendAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EEncoding%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EUTF8%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EGetBytes%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EgroupMessage%3C%2FSPAN%3E)%2C%20%3CSPAN%20class%3D%22cm-variable%22%3EWebSocketMessageType%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EText%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-atom%22%3Etrue%3C%2FSPAN%3E%2C%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%20%26nbsp%3B%3CSPAN%20class%3D%22cm-variable%22%3ECancellationToken%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENone%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-1232714818%22%20id%3D%22toc-hId-1256640777%22%3E%3CSPAN%20class%3D%22md-plain%22%3EReceiving%20Messages%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CPRE%20class%3D%22md-fences%20md-end-block%20ty-contain-cm%20modeLoaded%22%20lang%3D%22c%23%22%20spellcheck%3D%22false%22%3E%3CSPAN%3E%E2%80%8B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Evar%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-def%22%3Emessage%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-operator%22%3E%3D%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EArraySegment%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26lt%3B%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-variable-3%22%3Ebyte%3C%2FSPAN%3E%3CSPAN%20class%3D%22cm-operator%22%3E%26gt%3B%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-keyword%22%3Enew%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable-3%22%3Ebyte%3C%2FSPAN%3E%5B%3CSPAN%20class%3D%22cm-number%22%3E4096%3C%2FSPAN%3E%5D)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-keyword%22%3Eawait%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22cm-variable%22%3EclientWebSocket%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EReceiveAsync%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Emessage%3C%2FSPAN%3E%2C%20%3CSPAN%20class%3D%22cm-variable%22%3ECancellationToken%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3ENone%3C%2FSPAN%3E)%3B%3C%2FSPAN%3E%3CBR%20%2F%3E%3CSPAN%3E%3CSPAN%20class%3D%22cm-variable%22%3EConsole%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EWriteLine%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3EEncoding%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EUTF8%3C%2FSPAN%3E.%3CSPAN%20class%3D%22cm-variable%22%3EGetString%3C%2FSPAN%3E(%3CSPAN%20class%3D%22cm-variable%22%3Emessage%3C%2FSPAN%3E))%3B%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%20class%3D%22md-end-block%20md-p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--832905083%22%20id%3D%22toc-hId--808979124%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EExamples...%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%20md-focus%22%20id%3D%22toc-hId-1912773188%22%20id%3D%22toc-hId-1936699147%22%3E%3CSPAN%20class%3D%22md-plain%22%3EMulti%20lingual%20Chat%20App%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CP%3E%3CSPAN%20class%3D%22md-plain%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-translator.png%22%20style%3D%22width%3A%20958px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356117i0CF9C19ABDAD9B26%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-translator.png%22%20alt%3D%22pubsub-translator.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EEach%20Mobile%20client%20creates%20a%20WebSocket%20connection%20to%20Azure%20Web%20PubSub%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EEach%20client%20can%20send%20chat%20messages%20directly%20through%20Azure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EAn%20Upstream%20server%20exists%2C%20built%20with%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Function%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%2C%20to%20handle%20client%20events%20-%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3ELogin%2C%20Connected%2C%20Disconnected%2C%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3EEach%20Mobile%20client%20can%20call%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Cognitive%20Service%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20to%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%20%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3ETranslate%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%20the%20received%20chat%20message%20in%20any%20language%20and%20update%20its%20own%20UI%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH4%20class%3D%22md-end-block%20md-heading%20md-focus%22%20id%3D%22toc-hId-105318725%22%20id%3D%22toc-hId-129244684%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3ESupply%20Chain%20Control%20Tower%20App%3C%2FSPAN%3E%3C%2FH4%3E%0A%3CP%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-control-tower.png%22%20style%3D%22width%3A%20741px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356118iA1D311A386460D79%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-control-tower.png%22%20alt%3D%22pubsub-control-tower.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EMultiple%20business%20entities%20act%20as%20Web%20PubSub%20client%20and%20Control%20Tower%20App%20as%20Upstream%20server%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-plain%22%3EEach%20client%20can%20send%20chat%20messages%20directly%20through%20Azure%20Web%20PubSub%20e.g.%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EWarehouse%20%26lt%3B-%26gt%3B%20WareHouse%2C%20Warehouse%20%26lt%3B-%26gt%3B%20Customer%2C%20Customers%20%26lt%3B-%26gt%3B%20Factories%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%22%3E%20etc.%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%20md-focus-container%22%3E%3CP%20class%3D%22md-end-block%20md-p%20md-focus%22%3E%3CSPAN%20class%3D%22md-plain%22%3EEach%20Business%20client%20can%20be%20made%20more%20intelligent%20using%20%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-pair-s%22%3E%3CEM%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Cognitive%20Services%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%20and%20can%20take%20important%20decisions%20and%20share%20with%20other%20clients%3B%20resulting%20in%20a%20vibrant%20Control%20Tower%20system%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId--1960301176%22%20id%3D%22toc-hId--1936375217%22%3E%26nbsp%3B%3C%2FH2%3E%0A%3CH2%20class%3D%22md-end-block%20md-heading%22%20id%3D%22toc-hId-527211657%22%20id%3D%22toc-hId-551137616%22%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3EReferences%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CUL%20class%3D%22ul-list%22%20data-mark%3D%22-%22%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Foverview%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Fconcept-client-protocols%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EPubSub%20Client%20Protocol%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Freference-json-webpubsub-subprotocol%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EJSON%20WebSocket%20subprotocol%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Freference-server-sdk-csharp%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EServer%20SDKs%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fcognitive-services%2Ftranslator%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3ETranslator%20Cognitive%20API%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3CLI%20class%3D%22md-list-item%22%3E%3CP%20class%3D%22md-end-block%20md-p%22%3E%3CSPAN%20class%3D%22md-meta-i-c%20md-link%22%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fxamarin%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3E%3CSPAN%20class%3D%22md-plain%22%3EXamarin%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FLI%3E%0A%3C%2FUL%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-3256264%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%20class%3D%22md-meta-i-c%20md-link%20md-expand%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22pubsub-translator.png%22%20style%3D%22width%3A%20958px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F356119i967F4DC8BF50494E%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22pubsub-translator.png%22%20alt%3D%22pubsub-translator.png%22%20%2F%3E%3C%2FSPAN%3E%3CBR%20%2F%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fazure-web-pubsub%2Foverview%22%20rel%3D%22noopener%20noreferrer%22%20target%3D%22_blank%22%3E%3CSPAN%20class%3D%22md-plain%22%3EAzure%20Web%20PubSub%3C%2FSPAN%3E%3C%2FA%3E%3C%2FSPAN%3E%3CSPAN%20class%3D%22md-plain%20md-expand%22%3E%20is%20a%20PaaS%20Service%20on%20Azure%20to%20send%20real-time%20messages%20and%20notifications%20between%20Web%20and%20Mobile%20applications%20using%20WebSockets.%20This%20uses%20a%20Publish%2FSubscribe%20model%20and%20allows%20sending%20notifications%2C%20updates%2C%20messages%20between%20various%20connected%20entities.%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-3256264%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3E.NET%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Cognitive%20Services%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Functions%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Web%20PubSub%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EMobile%20Apps%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EWeb%20Apps%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Co-Authors
Version history
Last update:
‎Mar 15 2022 07:48 PM
Updated by: