Introduction
The data coming from the IoT devices must be shown (or used) in real-time. If we fail to do that, then there is no point in using IoT devices. Here in this article, we will see how we can show the real-time data from our IoT device in an Angular application using Azure SignalR Service and Azure Functions. Sound interesting?
The flow of data can be defined as
IoT device -> Azure IoT Hub -> Azure Function -> Azure SignalR Service -> Angular application.
Let’s start then. You can always read this article on my blog here.
Background
In our previous article, we have already created an Azure Function which pulls the data from our IoT Hub whenever there is any new message/event happening.
Source Code
Please feel free to fork/clone this project from GitHub here.
Real-time IoT Data Processing
We will be creating two solutions - one for Angular application and the other one for Azure Functions. We will also create a new Azure Signal R service in the Azure portal.
Azure SignalR Service
According to Microsoft, "Azure SignalR Service is an Azure managed PaaS service to simplify the development, deployment, and management of real-time web application using SignalR, with Azure supported SLA, scaling, performance, and security. The service provides API/SDK/CLI/UI, and the rich set of code samples, templates, and demo applications."
Core features for Azure SignalR Service,
- Native ASP.NET Core SignalR development support
- ASP.NET Core SignalR backend for improved performance and stability
- Redis based backplane scaling
- Web Socket, comet, and .NET Server-Sent-Event support
- REST API support for server broadcast scenarios
- Resource Provider support for ARM Template-based CLI
- Dashboard for performance and connection monitoring
- Token-based AUTH model
Let’s log in to our Azure portal and create a new Azure Signal R service. Click on the "+Create a resource" link and search for SignalR Service. Once you have created the service, go to the keys section and copy the connection string. We will be using the same in our Azure Function.
Azure Functions
As we discussed in my previous article, we will be creating an Azure Function with an IoTHubTrigger in it. You can refer to this article for the hints on how to create an Azure Function solution in Visual Studio. Please make sure that you had installed the required packages as mentioned in the image below.

Required Packages
Once you have created a new Function in the solution, it is time to add some code.
- using Microsoft.Azure.EventHubs;
- using Microsoft.Azure.WebJobs;
- using Microsoft.Azure.WebJobs.Extensions.SignalRService;
- using Microsoft.Extensions.Logging;
- using Newtonsoft.Json;
- using System;
- using System.Text;
- using System.Threading.Tasks;
- using IoTHubTrigger = Microsoft.Azure.WebJobs.EventHubTriggerAttribute;
- namespace AzureFunction {
- public static class SignalR {
- [FunctionName("SignalR")] public static async Task Run([IoTHubTrigger("messages/events", Connection = "IoTHubTriggerConnection", ConsumerGroup = "ml-iot-platform-func")] EventData message, [SignalR(HubName = "broadcast")] IAsyncCollector < SignalRMessage > signalRMessages, ILogger log) {
- var deviceData = JsonConvert.DeserializeObject < DeviceData > (Encoding.UTF8.GetString(message.Body.Array));
- deviceData.DeviceId = Convert.ToString(message.SystemProperties["iothub-connection-device-id"]);
- log.LogInformation($ "C# IoT Hub trigger function processed a message: {JsonConvert.SerializeObject(deviceData)}");
- await signalRMessages.AddAsync(new SignalRMessage() {
- Target = "notify", Arguments = new [] {
- JsonConvert.SerializeObject(deviceData)
- }
- });
- }
- }
- }
As you can see, we are using Microsoft.Azure.WebJobs.EventHubTriggerAttribute for pulling data from our IoT Hub. Here, “messages/events” is our Event Hub Name and "Connection" is the IoT Hub connections string which is defined in the local.settings.json file and the ConsumerGroup is the group I have created for the Azure Function solution.
If you have noticed, we are using the HubName as “broadcast” in the SignalR attribute and “notify” as the SignalR message Target property. If you change the Target property, you may get a warning in your browser console as “Warning: No client method with the name ‘notify’ found.”. The @aspnet/signalr package is checking for the Target property ‘notify’ by default.


So, I will keep the Target property as ‘notify’. By default, the message data doesn’t contain the device id value, so we will have to get the same from SystemProperties.
- var deviceData = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(message.Body.Array));
- deviceData.DeviceId = Convert.ToString(message.SystemProperties["iothub-connection-device-id"]);
Below is my DeviceData class.
- using Newtonsoft.Json;
- using System;
- namespace AzureFunction {
- public class DeviceData {
- [JsonProperty("messageId")] public string MessageId {
- get;
- set;
- } [JsonProperty("deviceId")] public string DeviceId {
- get;
- set;
- } [JsonProperty("temperature")] public string Temperature {
- get;
- set;
- } [JsonProperty("humidity")] public string Humidity {
- get;
- set;
- } [JsonProperty("pressure")] public string pressure {
- get;
- set;
- } [JsonProperty("pointInfo")] public string PointInfo {
- get;
- set;
- } [JsonProperty("ioTHub")] public string IoTHub {
- get;
- set;
- } [JsonProperty("eventEnqueuedUtcTime")] public DateTime EventEnqueuedUtcTime {
- get;
- set;
- } [JsonProperty("eventProcessedUtcTime")] public DateTime EventProcessedUtcTime {
- get;
- set;
- } [JsonProperty("partitionId")] public string PartitionId {
- get;
- set;
- }
- }
- }
When you work with any client like Angular application, it is important to get the token/connection from the server, so that the client can persist the connection with the server; hence the data can be pushed to the client from SignalR service. So, we will create a new Azure Function which will return the connection information with the URL and AccessToken.
- using Microsoft.AspNetCore.Http;
- using Microsoft.Azure.WebJobs;
- using Microsoft.Azure.WebJobs.Extensions.Http;
- using Microsoft.Azure.WebJobs.Extensions.SignalRService;
- using Microsoft.Extensions.Logging;
- namespace AzureFunction {
- public static class SignalRConnection {
- [FunctionName("SignalRConnection")] public static SignalRConnectionInfo Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, [SignalRConnectionInfo(HubName = "broadcast")] SignalRConnectionInfo info, ILogger log) => info;
- }
- }



Muthu KumarPosted Jan 2, 2019, 8:38 AM
Very informative Sibeesh Venu sir. Thanks for sharing.