Azure SignalR Service With Azure Functions And Service Bus

Introduction

 
In this article, I will walk you through an "Azure SignalR Service" using a Buyer-Supplier sample application. Azure SignalR service provides a real time communication between your application/pages.
  • We will cover  a couple more Azure Services like Azure Functions, Azure Service Bus & Azure SQL Database.
  • We will have one Buyer application in Asp.net core Razor Forms and ONE Supplier application in Asp.net core MVC. 
 
Prerequisites
  • Azure Account for setting up Azure Services (SignalR, Functions, Service Bus etc)
  • Visual Studio 2019 (For buyer and supplier application)

Application Flow

  •  Buyer Application - Buyer will create an order for an item with quantity.
  • Supplier Application - Supplier will get notified (A prompt message on his screen) that a buyer has added a new order.
  • Supplier Application - Supplier will accept or reject the buyer orders.
  • Buyer Application - Buyer will get notified on his screen that supplier has accepted/rejected his order.
The notification(Buyer/Supplier) will get triggered by Azure SignalR Service. It means, we will be registering our application/pages to the SignalR service.
 

Project Structure

.
Azure SignalR Service With Azure Functions And Service Bus
    • 1. Entities - Contains a class "ActiveOrder" which is used for storing the active orders object from UI and Database
    • 2. Common - Here we have AppSettings.cs class, it used for storing the appSettings values from app.config files in #5 UI projects 
    • 3. DB - DB Schema and Stored Procedures used in application
    • 4. OrderProcessingFunctionApp - Azure Function application
    • 5. UI - Buyer and Supplier - Client applications, one is for buyer and one is for supplier

Design/Flow

  • Buyer
Azure SignalR Service With Azure Functions And Service Bus
  •  Supplier:
Azure SignalR Service With Azure Functions And Service Bus

Create Azure Services

 
Azure SignalR Service
  • Login to "portal.azure.com"
  • Click on "Create a resource" link
Azure SignalR Service With Azure Functions And Service Bus
  • Search for "SignalR Service" in Azure market place:
Azure SignalR Service With Azure Functions And Service Bus
  • Click on "Create"
  • Provide the details as shown below and click on "Next Networking"
Azure SignalR Service With Azure Functions And Service Bus
  • Keep the end-point public for our demo:
Azure SignalR Service With Azure Functions And Service Bus
  • Click on "Review and Create" and then "Create". Once your "SignalR Service" deployment is done, then verify it in your Resource Group that it is added there. 
Azure Service Bus  
  • Go to Azure market place and search for Service Bus Or you can get it under "Integration" section on left:
Azure SignalR Service With Azure Functions And Service Bus
  • Fill the details like Resource Group, Service bus name etc:
Azure SignalR Service With Azure Functions And Service Bus
  • Click on "review + create" and "create".

Create Queues under the created Service bus

 
Once your deployment is done, then go to your "Resource Group" and click on your newly created "Service Bus" resource.
 
In this service bus, we will create 2 queues, which will get the data/message from Buyer web application and Supplier web application.
  • Click on "Queue":
Azure SignalR Service With Azure Functions And Service Bus
  • Click on "+ Queue", It will open a "add new queue" wizard:
Azure SignalR Service With Azure Functions And Service Bus
  • Create a queue "buyerOrders" as below (It will receieve message/data/object related to buyer order details):
Azure SignalR Service With Azure Functions And Service Bus
  • Create a queue "supplierResponses" as below (It will used to recieve the supplier response against buyer order):
Azure SignalR Service With Azure Functions And Service Bus
  • You can see that both queues are created under service bus:
Azure SignalR Service With Azure Functions And Service Bus
 

Create Azure SQL database

  • Go to Azure market place and select "SQL Database" under "Databases" section:
Azure SignalR Service With Azure Functions And Service Bus
 
  • Fill the database details and click on "Create New" server:
Azure SignalR Service With Azure Functions And Service Bus
Azure SignalR Service With Azure Functions And Service Bus 
  • On Networking tab, make selections as below, to connect db from your local machine and so other Azure service could connect DB:
Azure SignalR Service With Azure Functions And Service Bus
  • Click on Create.
  • Create a table in the database as "Orders" (Script is available attached code in DB Folder, Execute the stored procedures also)) :
Azure SignalR Service With Azure Functions And Service Bus
 
In this table, The "ItemName", "Quantity" and "BuyerName" will get inserted when buyer creates an order and the "status" will be saved as "Draft".
 
When supplier provides a  response, we just update the status field with either "Accepted" or "Rejected", based on the supplier input.
 
Create Azure Function App in Visual Studio and name it as "OrderProcessingFunctionApp" (Already available in source code, just covering so if anyone wants to know),
 
Azure SignalR Service With Azure Functions And Service Bus
  • Select "Service Bus Queue Trigger" and click on "create":
Azure SignalR Service With Azure Functions And Service Bus
  • It will create an Azure function project in your solution  (I renamed function.cs to ProcessOrder.cs)
Azure SignalR Service With Azure Functions And Service Bus
  • Open ProcessOrder.cs file, you can see that we have implemented 3 functions,
Azure SignalR Service With Azure Functions And Service Bus
    • NewOrderSubmitted - This function will get called whenever a buyer submits a new order using buyer web application. So, it recieves the order details and we save it in the database and pass it to SignalR. Here is our function
Azure SignalR Service With Azure Functions And Service Bus
      • Here the function name is "NewOrderSubmitted" set it in attribute "FunctionName("NewOrderSubmitted")"
      • "ServiceBusTrigger" - This function will get triggered when we send any data/message to Service bus queue named "buyerOrders", service bus connection string key is "ServiceBusConnectionString" and the buyer order data comes in parameter order of dataType "ActiveOrder". 
      • SignalR hub name is "notifications", we will use it in buyer application (In startup.cs file) later.
      • SaveToDatabase - Function which saves the new order details into database
      • SignalRMessage - Message which we will be sending to signalR

        • Target - It is the name of the client action, which is registerted to SignalR, in our case its a Supplier application page. All these clients will get notified that a new order has been added into system
        • Arguments - The data which we need to send to signal R, in our case it's order details
    •  SupplierResponse - This function will get triggered when Supplier accepts/rejects buyer order. So we will notify to buyer that your order is accepted or rejected.
Azure SignalR Service With Azure Functions And Service Bus
      •  Here the function name is "SupplierResponse" set it in attribute "FunctionName("SupplierResponse")"
      • "ServiceBusTrigger" - This function will get triggered when we send any data/message to Service bus queue name "supplierResponse", service bus connection string key is "ServiceBusConnectionString" and the message comes in parameter of dataType "string".
      • SignalR hub name is notifications
      • SignalRMessage - Message which we will be sending to signalR

        • Target - It is the name of the client action, which is registerted to SignalR, in our case its a Buyer application page. Buyer will get notified that supplier either accepted or rejected his order.
        • Arguments - The data which we need to send to signal R, in our case its a string message containing Accepted/Rejected detail 
    •  Negotiate : This will talk to Azure SignalR service and provide a API key that will be used in further communication in sending messages.
Azure SignalR Service With Azure Functions And Service Bus
        • Here the function name is "negotiate" set it in attribute "FunctionName("negotiate")"
        • "HttpTrigger" - This function will get called when call it directly using URL
        • It  has ahandshake with Azure SignalR service and sends us the connection information that we will use in further communications.
        • It will get called when we load the Buyer or Supplier application - On document.ready event.
  • Deploy Azure function application on Azure:
    • Right click on function app project and click on Publish
Azure SignalR Service With Azure Functions And Service Bus
    • It will open a publish wizard, Click on New
Azure SignalR Service With Azure Functions And Service Bus
    • Select target as Azure
Azure SignalR Service With Azure Functions And Service Bus
    • Specific Target as Azure Function App (Windows)
Azure SignalR Service With Azure Functions And Service Bus
    •  Click on "Create a new azure function":
Azure SignalR Service With Azure Functions And Service Bus 
    • Provide Name, Resource Group, Location etc and click on Create
    • Click on Finish on parent window.
    • Click on Publish to deploy it on Azure :
Azure SignalR Service With Azure Functions And Service Bus
    • After Deployment, your Function app will be available on Azure in your resource group:
Azure SignalR Service With Azure Functions And Service Bus
    • Click on your function app, Check the URL, we will use it in our buyer and supplier applications (in document.ready() event on UI)
Azure SignalR Service With Azure Functions And Service Bus
    • Click on the Functions on left to get all three functions we created in function app: 
Azure SignalR Service With Azure Functions And Service Bus
  • Setting Connection String in Function App for ServiceBus, SignalR and SQL database
    • Open portal.azure.com and go to your Resource Group. We need to get the connection information of the below marked resources:
Azure SignalR Service With Azure Functions And Service Bus
    •  Get the connection string of SignalR Service. Copy the below Connection String and copy it in one notepad file (We will use it later):
Azure SignalR Service With Azure Functions And Service Bus
    • Get the connection string of Service Bus. Copy the value og Primary connection string(right), and keep it in notepad 
Azure SignalR Service With Azure Functions And Service Bus
    • Get the SQL connection string and keept it in notepad: 
Azure SignalR Service With Azure Functions And Service Bus
    •  Go to your Azure function and add new application settings as below (Set the respecticve values for these settings you copied from previous 3 steps):
Azure SignalR Service With Azure Functions And Service Bus
    • Go to your Azure function and add connection string for Service Bus (In previous step we added it as application setting), as below:
Azure SignalR Service With Azure Functions And Service Bus
 
Web application (Buyer and Supplier)
  • Setup Buyer application (Razor Forms)

    • UI of buyer application. We have three fields, Buyer Name, Item and Quanity, on Click of submit this information will be going to Service Bus. The Service bus will trigger the Azure function, where we are saving it into database and sending the message to SignalR hub, so signal hub will send out the notification to all the connected clients (Supplier application):
 Azure SignalR Service With Azure Functions And Service Bus
    • UI and code behind file,
Azure SignalR Service With Azure Functions And Service Bus
    • If you look the Buyer.cshtml page, you will find code block below:
Azure SignalR Service With Azure Functions And Service Bus
        • withUrl - We are creating SignalR connection using your function app URL. This is your function app URL.
        • signalRHubConnection.start() - It will execute when SignalR connection is created
        • signeRHubConnection.on('supplierResponses', - It is the target which we setup in out function app functions, So, when supplier provide response, the SignalR gets the message and looks for clients registered with 'supplierResponses' as target. So, all these clients will get notified. In our logic, buyer will get notified.
    • If you look at  the Buyer.cshtml.cs file, here is what we are doing on submit button click:
Azure SignalR Service With Azure Functions And Service Bus
        • 1. We are reading Service Bus Connection String and Queue Name from apsettings.json (It is copied from Azure Service bus):
Azure SignalR Service With Azure Functions And Service Bus
        • 2. Creating a queue client, using the Service bus connection string and Queue name.
        • 3. Creating a message for Service bus with buyer order details
        • 4. Sending data to Service Bus 

          • Service bus queue will trigger our NewOrderSubmitted Azure Function
          • That function will save the data on to database and pass the object to Signal R service
    • Startup.cs file. We have configured the SignalR and the default page as Buyer: 
Azure SignalR Service With Azure Functions And Service Bus
  •  Setup supplier application (MVC)

    •  UI of supplier application. We have a table, where we will show all the buyer orders, and supplier can either accept or reject the order. There is a refresh button which supplier will click, when he will get notification for new orders added in the system,
Azure SignalR Service With Azure Functions And Service Bus
    • If you look in Views/Supplier/index.cshtml file, you can see that if has bound a couple of events:
Azure SignalR Service With Azure Functions And Service Bus
    • In document.ready event on client side, we are setting the signalR hub connection by passing the url of azure function app.
    • When signalR hub connection initializes, we log that in browser console.
    • signalRHubConnection.on('newOrderSubmitted', function (orderDetails) - This will execute when we pass message to signalR and the target is set to newOrderSubmitted. In our code, it is used at azure function app [FunctionName("NewOrderSubmitted")]
    • #btnRefresh click event - It just reloads the current page so we can load other new orders
    • #btnAccept and #btnReject click event - It calls one method specified in "Controll/SupplierController.cs", which updates the status of the order and passes a message to service bus queue "supplierresponses", which triggers the Azure function [FunctionName("SupplierResponse")], and from this function we send a message to SiganlR service, which will notify all the buyers as the taget is set to "supplierresponse"
    • If you look into Controllers/SupplierController.cs, you can see how we are loading the data and how we are updating the buyers order status: 
Azure SignalR Service With Azure Functions And Service Bus
      • Supplier Controller - Supplier page controller
      • Action -Index -  It will get called as default page and it will fetch all the active orders and pass that to UI
      • Method - SupplierResponse - It will get called on click of Accept/Reject buttons and it updates the status of order in database
      • Contructs Message for Service Bus - For queue "supplierresponses". The service bus connection string, queue name and SQL connection string, we are reading from appsettings.json file
      • Send the message to the queue. So buyer will get notified that order has been accepted or rejected
  • These two applications run on https locally on port 44343 and 44322 , So, we need to allow these URLs in the CORS (Cross Origin Requests) settings of your function app,

    • Go to buyer and supplier application, right click and select properties, then go to Debug
Azure SignalR Service With Azure Functions And Service Bus
Azure SignalR Service With Azure Functions And Service Bus 
        • So, the URLs, mapped with enable SSL on both the applications, we need to add these to the CORS list in Azure function app as: 
Azure SignalR Service With Azure Functions And Service Bus
  • Note: If you get an error, while connecting SQL databse from local, then make sure that your local ip is allowed to connect with SQL database on Azure. Go to the SQL database on Azure and click on Set firewall rule:
Azure SignalR Service With Azure Functions And Service Bus
    • Click on Add client IP and Save: 
Azure SignalR Service With Azure Functions And Service Bus
  • To debug, make both the buyer and supplier application as startup applications. Go to project solution (left), right click and select properties, then make the changes as shown below: 
Azure SignalR Service With Azure Functions And Service Bus
  • Run the application in visual studio, and you will see that it will open two browsers, one is for buyer view, and one is for supplier view: 
Azure SignalR Service With Azure Functions And Service Bus
  • When buyer fills a form and clicks on submit, you will see that supplier will get notification as below: 
Azure SignalR Service With Azure Functions And Service Bus
  • When supplier provides the response, by clicking on Accept /Reject, you can see that the buyer will get notified that the supplier has accepted/rejected his order: 
Azure SignalR Service With Azure Functions And Service Bus
 

Conclusion

 
We have seen how we can use Azure SignalR service and how we can integrate it with other Azure services like Service Bus and Azure Functions. It is very a simple detailed example where we have two fixed clients but we can explore more from here to send the notification to single users when we have multi tenant applications.