Skip to content

Use SignalR to subscribe to events

Subscription to events is based on SignalR. It is possible to subscribe to single tenant or multitenant events.

Single tenant events

To subscribe to single tenant events SAS token is required. For SAS token use platform generated SAS tokens. Please read about that more here.

Events will be filtered by customer id in the SAS token in this case.

The following endpoint is to be used subscribing to single tenant events: /v1/subscribe

Below are examples for creating websocket connection for single tenant event subscription using C#, JS and python. Examples are based on the following packages/libraries for each language:

var _connection = new HubConnectionBuilder()
    .WithUrl(_hubUrl + "/v1/subscribe",
        options => {
            options.Headers.Add("dhi-sas-token", {sasToken});
            options.Transports = HttpTransportType.WebSockets;
        })
    .WithAutomaticReconnect()
    .Build();
OnPropertyChanged("Connection");
_connection.Closed += _connection_Closed;
_connection.Reconnected += _connection_Reconnected;
_connection.Reconnecting += _connection_Reconnecting;

_connection.On<string>("Update", (data) =>
{
    OnPropertyChanged("Connection");
    action(data);
});

await _connection.StartAsync();
var connection = new signalR.HubConnectionBuilder()
    .withUrl(_hubUrl + "/v1/subscribe", {
        headers: {"dhi-sas-token": dhi_sas_token}
    })
    .withAutomaticReconnect([0, 0, 10000])
    .build();

connection.on("Update", (message) => {
    console.log(`Message ${message}`);
});

connection.start();
hub_connection = HubConnectionBuilder()\
    .with_url(hubUrl + "/v1/subscribe",
        options={
            "headers": {
                "dhi-sas-token": dhi_sas_token
            }
        })\
    .configure_logging(logging.ERROR)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,
        "reconnect_interval": 5,
        "max_attempts": 5
    }).build()

hub_connection.on_open(lambda: print("connection opened and handshake received ready to send messages"))
hub_connection.on_close(lambda: print("connection closed"))

hub_connection.on("Update", print)

hub_connection.start()

Invoking subscription will require SubscriptionId and Condition to be defined. Filter is optional. SubscriptionId is any string of max length 1024. Filter has the following optional parameters:

- `Sources` - list of strings
- `EventTypes` - list of strings
- `DataSchemas` - list of strings
- `ResourceIdentifiers` - list of strings
- `ProjectExact` - bool

Parameter Condition has the following parameters:

- `Offset` - is required parameter and can have the following values:
    - Beginning: 100
    - Point: 300
    - End: 200
- `OffsetPoint` - is string and relevant only with Offset.Point

Below are examples of invoking subscription:

var subs = new Subscription
{
    SubscriptionId = {subscriptionId},
    Filter = new Filter() { Sources = new List<string>() { "/someservice/someoperation/v1/" } },
    Condition = new Condition(Offset.Point, {offsetPoint})
};
await _connection.InvokeAsync("Subscribe", subs);
var sub = {
  SubscriptionId: subscriptionId,
  Filter: {
      Sources: ["/someservice/someoperation/v1/"]
  },  
  Condition: {
      Offset : 300,
      OffsetPoint: "1057"
  }
}

connection.invoke("Subscribe", sub);
sub = {
  "SubscriptionId": subscriptionId,
  "Filter": {
      "Sources": ["/someservice/someoperation/v1/"]
  },
  "Condition": {
      "Offset" : 300,
      "OffsetPoint": "1057"
  }
}

hub_connection.send("Subscribe", [sub])

Filter events hierarchically by project

To receive only events related to specified project, set Filter option ProjectExact to true. Otherwise you will recieve events for specified project and its subprojects. For example, consider following project structure:

A
| \ 
B  [C] 
|  |  \
D  E   F
|  |
H  G
If you subscribe for events for project C and leave the default value for Filter.ProjectExact (false), you will recieve events for projects C,E,G and F.

Multi tenant events

To subscribe to multi tenant events only Jwt tokens is required. Jwt token must be generated using application registration in the internal tenant. Application must have permission to access eventing application. Events for all customer will be available in this case.

The following endpoint to be used subscribing to multi tenant events: /v1/subscribeall

Below are examples for creating websocket connection for multi tenant event subscription using C#, JS and python. Examples are based on the following packages/libraries for each language:

var _connection = new HubConnectionBuilder()
    .WithUrl(_hubUrl + "/v1/subscribeall",
        options => {
            options.Headers.Add("Authorization", $"Bearer {token}");
            options.Transports = HttpTransportType.WebSockets;
        })
    WithAutomaticReconnect()
    .Build();
OnPropertyChanged("Connection");
_connection.Closed += _connection_Closed;
_connection.Reconnected += _connection_Reconnected;
_connection.Reconnecting += _connection_Reconnecting;

_connection.On<string>("Update", (data) =>
{
    OnPropertyChanged("Connection");
    action(data);
});

await _connection.StartAsync();
var connection = new signalR.HubConnectionBuilder()
    .withUrl(_hubUrl + "/v1/subscribeall", {
        headers: {"Authorization": token}
    })
    .withAutomaticReconnect([0, 0, 10000])
    .build();

connection.on("Update", (message) => {
    console.log(`Message ${message}`);
});

connection.start();
hub_connection = HubConnectionBuilder()\
    .with_url(hubUrl + "/v1/subscribeall",
        options={
            "headers": {
                "Authorization": token
            }
        })\
    .configure_logging(logging.ERROR)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,
        "reconnect_interval": 5,
        "max_attempts": 5
    }).build()

hub_connection.on_open(lambda: print("connection opened and handshake received ready to send messages"))
hub_connection.on_close(lambda: print("connection closed"))

hub_connection.on("Update", print)

hub_connection.start()

Invoking subscription will require SubscriptionId and Condition to be defined. Filter is optional. SubscriptionId is any string of max length 1024. Filter has the following optional parameters:

- `Sources` - list of strings
- `EventTypes` - list of strings
- `DataSchemas` - list of strings
- `ResourceIdentifiers` - list of strings
- `ProjectExact` - bool

Parameter Condition has the following parameters:

- `Offset` - is required parameter and can have the following values:
    - Beginning: 100
    - Point: 300
    - End: 200
- `OffsetPoint` - is string and relevant only with Offset.Point

Below are example of invoking subscription:

var subs = new SubscriptionAll
{
    SubscriptionId = {subscriptionId},
    Filter = new Filter() { Sources = new List<string>() { "/someservice/someoperation/v1/" } },
    Condition = new Condition(Offset.Beginning)
};
await _connection.InvokeAsync("SubscribeAll", subs);
var sub = {
  SubscriptionId: subscriptionId,
  Filter: {
      Sources: ["/someservice/someoperation/v1/"]
  },  
  Condition: {
      Offset : 300,
      OffsetPoint: "1057"
  }
};

connection.invoke("SubscribeAll", sub);
sub = {
  "SubscriptionId": subscriptionId,
  "Filter": {
      "Sources": ["/someservice/someoperation/v1/"]
  },
  "Condition": {
      "Offset" : 300,
      "OffsetPoint": "1057"
  }
}

hub_connection.send("SubscribeAll", [sub])