Real-time stream with SignalR
In all examples, the variables token and workspaceId 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
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 8
Nedap Harmony uses the .NET Core / .NET 8 version of SignalR. Please ensure you install the proper client for this:
- JavaScript:
@microsoft/signalr
- C# / dotnet:
Microsoft.AspNetCore.SignalR.Client
Make sure to fix the transport and skipNegotiation parameter
In the configuration of SignalR, please define the transport to be WebSockets and set skipNegotiation to true. This is necessary for reliable connections.
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 = "...";
let connection = new signalR.HubConnectionBuilder()
.withUrl(`https://nedap-harmony.com/api/hub/external/v1?workspaceId=${workspaceId}`, {
accessTokenFactory: () => token,
transport: signalR.HttpTransportType.WebSockets,
skipNegotiation: true,
})
.build();
connection.onclose(() => console.log('Connection closed'))
connection.start()
.then(() => {
connection
.stream('ActionStream')
.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 = "...";
public static void Main()
{
var uri = "https://nedap-harmony.com/api/hub/external/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);
options.Transports = HttpTransportType.WebSockets;
options.SkipNegotiation = true;
})
.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", 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");
}
}
Updated about 1 year ago