Description
Azure Event Grid with Topics is a enterprise grade notification engine which mimics Azure Service Bus in many ways, Where it differes from Service Bus is that it is a serverless component, and has no physical storage of messages, so cannot, in the event of a incident, gaurentee delivery. What id does however offer in a normal operating environment is a fast, low latency delivery of messages that can be consumed easily.
The following description shows a particular implementation of event grid messaging, which is used in conjunction with Azure SignalR so that a web GUI can receive notifications.

- The Web page gets the SignalR connection from the Azure Function.
- The Event Source publishes a message to a Event Grid Topic.
- The Azure Function subscribes to a particular topic, the Event Grid can have many topics.
- The Azure Function publishes the message to SignalR
- The Web page receive the message from the signalR WebSocket.
Appendix
Azure Function
    public static class CloudEventSubscription
    {
        // Azure Function for handling negotation protocol for SignalR. It returns a connection info
        // that will be used by Client applications to connect to the SignalR service.
        // It is recommended to authenticate this Function in production environments.
        [FunctionName("negotiate")]
        public static SignalRConnectionInfo GetSignalRInfo(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
            [SignalRConnectionInfo(HubName = "cloudEventSchemaHub")] SignalRConnectionInfo connectionInfo,
            ILogger log)
        {
            log.LogInformation("negotiate");
            return connectionInfo;
        }
        // Azure Function for handling Event Grid events using CloudEventSchema v1.0 
        // (see CloudEvents Specification: https://github.com/cloudevents/spec)
        [FunctionName("EventSubscription")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "POST", "OPTIONS", Route = null)] HttpRequest req,
            [SignalR(HubName = "cloudEventSchemaHub")] IAsyncCollector<SignalRMessage> signalRMessages,
            ILogger log)
        {
            log.LogInformation("CloudEventSubscription");
            // Handle EventGrid subscription validation for CloudEventSchema v1.0.
            // It sets the header response `Webhook-Allowed-Origin` with the value from 
            // the header request `Webhook-Request-Origin` 
            // (see: https://docs.microsoft.com/en-us/azure/event-grid/cloudevents-schema#use-with-azure-functions)
            if (HttpMethods.IsOptions(req.Method))
            {
                log.LogInformation("CloudEventSubscription - Options");
                if (req.Headers.TryGetValue("Webhook-Request-Origin", out var headerValues))
                {
                    log.LogInformation("CloudEventSubscription - Webhook-Request-Origin");
                    var originValue = headerValues.FirstOrDefault();
                    if(!string.IsNullOrEmpty(originValue))
                    {
                        req.HttpContext.Response.Headers.Add("Webhook-Allowed-Origin", originValue);
                        return new OkResult();
                    }
                    log.LogInformation("CloudEventSubscription - Missing Webhook-Request-Origin");
                    return new BadRequestObjectResult("Missing 'Webhook-Request-Origin' header when validating");
                }
            }
            
            // Handle an event received from EventGrid. It reads the event from the request payload and send 
            // it to the SignalR serverless service using the Azure Function output binding
            if(HttpMethods.IsPost(req.Method)) 
            {
                string @event = await new StreamReader(req.Body).ReadToEndAsync();
                await signalRMessages.AddAsync(new SignalRMessage
                {
                    Target = "newEvent",
                    Arguments = new[] { @event }
                });
            }
            log.LogInformation("CloudEventSubscription - SignalR Post");
            return new OkResult();
        }
    }Angular
import { Component } from '@angular/core';
import * as SignalR from '@microsoft/signalr';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'viewer-app';
  events: string[] = [];
  private hubConnection: SignalR.HubConnection;
  constructor() {
    // Create connection
    this.hubConnection = new SignalR.HubConnectionBuilder()
      .withUrl("https://func-pocegsr-vse-ne.azurewebsites.net/api/")
      .build();
    // Start connection. This will call negotiate endpoint
    this.hubConnection
      .start();
    // Handle incoming events for the specific target
    this.hubConnection.on("newEvent", (event) => {
      this.events.push(event);
    });
  }
}Arm Template
    {
      "type": "Microsoft.SignalRService/SignalR",
      "apiVersion": "2022-02-01",
      "name": "[variables('var_sr_name')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "name": "Standard_S1",
        "tier": "Standard",
        "size": "S1",
        "capacity": 1
      },
      "kind": "SignalR",
      "properties": {
        "tls": {
          "clientCertEnabled": false
        },
        "features": [
          {
            "flag": "ServiceMode",
            "value": "Serverless",
            "properties": {}
          },
          {
            "flag": "EnableConnectivityLogs",
            "value": "True",
            "properties": {}
          }
        ],
        "cors": {
          "allowedOrigins": [
            "*"
          ]
        },
        "upstream": {},
        "networkACLs": {
          "defaultAction": "Deny",
          "publicNetwork": {
            "allow": [
              "ServerConnection",
              "ClientConnection",
              "RESTAPI",
              "Trace"
            ]
          },
          "privateEndpoints": []
        },
        "publicNetworkAccess": "Enabled",
        "disableLocalAuth": false,
        "disableAadAuth": false
      },
      "tags": {
        "displayName": "SignalR"
      }
    },
    {
      "type": "Microsoft.EventGrid/topics",
      "apiVersion": "2021-12-01",
      "name": "[variables('var_egt_name')]",
      "location": "[resourceGroup().location]",
      "identity": {
        "type": "None"
      },
      "properties": {
        "inputSchema": "CloudEventSchemaV1_0",
        "publicNetworkAccess": "Enabled",
        "inboundIpRules": [],
        "disableLocalAuth": false
      },
      "tags": {
        "displayName": "Event Grid Topic"
      }
    },