Real-time stream with SignalR

In all examples, the variables token, workspaceId and readPointId are needed.

  • Variable token can be obtained by creating a new API Token in Nedap Harmony
  • Variable workspaceId is shown on the API Tokens page in Nedap Harmony
  • Variable readPointId is shown on the ReadPoint page in Nedap Harmony, in the table for each ReadPoint

❗️

Examples do not handle connection issues

Please note that all examples are bare minimums, and do not handle connection issues, both during set-up and when the connection is active. Please refer to the documentation on the Microsoft website for more details. Note that automatic reconnect has finite retries by default.

📘

.NET Core / .NET 5

Nedap Harmony uses the .NET Core / .NET 5 version of SignalR. Please ensure you install the proper client for this:

  • JavaScript: @aspnet/signalr
  • C# / dotnet: Microsoft.AspNetCore.SignalR.Client

JavaScript example

The following example shows a simple implementation in JavaScript. It can be ran using node.js.

const signalR = require("@microsoft/signalr");

const token = "...";
const workspaceId = "...";
const readPointId = "...";

let connection = new signalR.HubConnectionBuilder()
    .withUrl(`https://nedap-harmony.com/api/hub/read-point/v1?workspaceId=${workspaceId}`, {
        accessTokenFactory: () => token,
      })
    .build();

connection.onclose(() => console.log('Connection closed'))

connection.start()
    .then(() => {
        connection
          .stream('ActionStream', readPointId)
          .subscribe({
            next: (item) => {
              console.log(item)
            },
            complete: () => {
              console.warn('Server closed the connection unexpectedly, retrying...')
              this.onConnected()
            },
            error: (err) => {
              console.error(err)
            },
          });
    })

❗️

JavaScript in the browser

It is not possible to directly consume the Nedap Harmony APIs and streams from in-browser JavaScript application. This is for security purposes; the access token would be open and exposed to all the users of your JavaScript application. This is why you always need a backend to 'hide' the Nedap Harmony API Token.

C# / dotnet Example

The following example shows a simple implementation in C# / dotnet.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.AspNetCore.WebUtilities;

public class Program
{
    static HubConnection connection;
    static string token = "...";
    static string workspaceId = "...";
    static string readPointId = "...";
    
    public static void Main()
    {
        var uri = "https://nedap-harmony.com/api/hub/read-point/v1";

        var queryString = new Dictionary<string, string>
        {
            {"workspaceId", workspaceId},
        };

        var uriWithQueryString = QueryHelpers.AddQueryString(uri, queryString);
        
        connection = new HubConnectionBuilder()
            .WithUrl(uriWithQueryString, options =>
                     {
                         options.AccessTokenProvider = () => Task.FromResult(token);
                     })
      .Build();

        connection.Closed += (error) =>
        {
            Console.WriteLine($"Connection closed: {error}");
            return Task.CompletedTask;
        };
        
        Run().Wait();
    }
    
    static async Task Run()
    {
        await connection.StartAsync();
        
        var cancellationTokenSource = new CancellationTokenSource();
        var channel = await connection.StreamAsChannelAsync<object>("ActionStream", readPointId, cancellationTokenSource.Token);

        // Wait asynchronously for data to become available
        while (await channel.WaitToReadAsync())
        {
            // Read all currently available data synchronously, before waiting for more data
            while (channel.TryRead(out var readPointAction))
            {
                Console.WriteLine(readPointAction);
            }
        }

        Console.WriteLine("Streaming completed");
    }
}

Did this page help you?