Grote.Daas.LiveFeed
1.0.3
dotnet add package Grote.Daas.LiveFeed --version 1.0.3
NuGet\Install-Package Grote.Daas.LiveFeed -Version 1.0.3
<PackageReference Include="Grote.Daas.LiveFeed" Version="1.0.3" />
<PackageVersion Include="Grote.Daas.LiveFeed" Version="1.0.3" />
<PackageReference Include="Grote.Daas.LiveFeed" />
paket add Grote.Daas.LiveFeed --version 1.0.3
#r "nuget: Grote.Daas.LiveFeed, 1.0.3"
#:package Grote.Daas.LiveFeed@1.0.3
#addin nuget:?package=Grote.Daas.LiveFeed&version=1.0.3
#tool nuget:?package=Grote.Daas.LiveFeed&version=1.0.3
Grote.Daas.LiveFeed
Real-time gRPC live-feed client for the 4SEE Integrations DaaS API.
Subscribe once and fan out streaming trailer/telemetry updates to as many handlers as you like.
Authentication, heartbeat filtering, and automatic reconnect are handled for you. This is a
separate package from the REST client (Grote.Daas.Client) so REST-only consumers don't pull in
gRPC/protobuf, and it shares the same API key and auth server.
Install
dotnet add package Grote.Daas.LiveFeed
The main event: register and add handlers
Register the feed once, then chain on as many handlers as you want. No connection code, no stream loop, no auth in your app.
using Grote.Daas.LiveFeed;
builder.Services
.AddDaasLiveFeed(options =>
{
options.ApiKey = builder.Configuration["DAAS_API_KEY"]!;
options.Audience = DaasAudience.Customer;
})
.AddHandler<TrailerFaultAlerter>()
.AddHandler<TelemetryArchiver>()
.OnUpdate((update, services, ct) =>
{
Console.WriteLine($"{update.Trailer.UnitId} @ {update.Ts}");
return Task.CompletedTask;
});
A handler is a plain class, constructor-injected like any service:
public sealed class TrailerFaultAlerter : ILiveFeedHandler
{
private readonly ILogger<TrailerFaultAlerter> _log;
public TrailerFaultAlerter(ILogger<TrailerFaultAlerter> log) => _log = log;
public Task HandleAsync(LiveUpdate update, CancellationToken ct)
{
if (update.Trailer.Status?.IsFault == true)
_log.LogWarning("Trailer {Unit} faulted", update.Trailer.UnitId);
return Task.CompletedTask;
}
}
Each update is dispatched to every registered handler inside a fresh DI scope, so handlers can
depend on scoped services (e.g. an EF DbContext). If one handler throws, it's logged and the
others still run, the stream keeps going.
What happens under the hood
- A hosted background service starts with your app, authenticates, and opens the stream.
- Heartbeats are filtered out — handlers only see real updates.
- Reconnect with exponential backoff on any drop, re-authenticating each time.
- HTTP/2 keep-alive is tuned to match the server.
Connection lifecycle & reconnect control
Observe connect/disconnect/reconnect events, inline or as classes:
builder.Services
.AddDaasLiveFeed(o => o.ApiKey = apiKey)
.AddConnectionObserver<HealthObserver>() // implements ILiveFeedConnectionObserver
.OnConnected((ctx, sp, ct) => { /* stream up */ return Task.CompletedTask; })
.OnDisconnected((ctx, sp, ct) => // ctx: Error, Attempt, WillRetry, NextDelay
{
// e.g. flip a health flag, or reconcile via the REST client
return Task.CompletedTask;
})
.OnReconnecting((ctx, sp, ct) => Task.CompletedTask); // ctx: Attempt, Delay, LastError
The listener always reconnects after a drop, that's not optional, so a live feed can't silently die on you. What you can tune is the backoff:
builder.Services.AddDaasLiveFeed(o =>
{
o.ApiKey = apiKey;
o.InitialReconnectDelay = TimeSpan.FromSeconds(2); // first retry delay / backoff start
o.ReconnectBackoffFactor = 2.0; // grow the delay by this each failure
o.MaxReconnectDelay = TimeSpan.FromSeconds(60); // cap
});
A hard internal floor keeps the effective delay from ever hammering the server, even if you misconfigure the values.
Dispatch middleware
Wrap the handler fan-out for cross-cutting concerns (logging, timing, correlation IDs, metrics). Middleware run in registration order, outermost first:
builder.Services
.AddDaasLiveFeed(o => o.ApiKey = apiKey)
.Use(async (update, services, next, ct) =>
{
var sw = Stopwatch.StartNew();
await next(); // runs the remaining middleware + all handlers
services.GetRequiredService<IMetrics>().Record(sw.Elapsed);
})
.AddHandler<TrailerFaultAlerter>();
Escape hatches
Don't want the hosted model? Use the low-level client and own the loop yourself:
using var client = new DaasLiveFeedClient(new DaasLiveFeedOptions { ApiKey = "..." });
await foreach (var update in client.SubscribeAsync(ct))
{
// your logic; heartbeats already filtered. No auto-reconnect at this level.
}
Or inject IDaasLiveFeedClient if you registered via DI.
Configuration
DaasLiveFeedOptions:
| Option | Default | Notes |
|---|---|---|
ApiKey |
DAAS_API_KEY env var |
|
BaseUrl |
https://4see.groteintegrations.com/ |
gRPC live-feed host |
AuthUrl |
https://auth.groteintegrations.com/ |
auth server |
Audience |
Customer |
or Partner |
DispatchMode |
Sequential |
or Parallel (concurrent handlers) |
InitialReconnectDelay |
2s | first retry delay / backoff starting point |
ReconnectBackoffFactor |
2.0 | delay multiplier per consecutive failure (min 1) |
MaxReconnectDelay |
60s | backoff cap |
AuthTimeout |
30s | auth call timeout |
KeepAlivePingDelay / KeepAlivePingTimeout |
25s / 20s | HTTP/2 keep-alive |
Relationship to the REST SDK
Same API key, same auth server, same audience model. The difference: the live feed authenticates once per connection (no token refresh), where the REST client caches and refreshes. Use the REST package for request/response queries and this package for the real-time push stream.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Google.Protobuf (>= 3.35.1)
- Grpc.Net.Client (>= 2.83.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Http (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.3 | 101 | 9/14/2026 |