Repository navigation
Releases: cirreum/Cirreum.Runtime.RemoteConnections.SignalR
Release list
Release v2.0.2
Full Changelog: v2.0.1...v2.0.2
Release v2.0.1
Release v2.0.0
Cirreum.Runtime.RemoteConnections.SignalR 2.0.0 — the registration names the connection
Why this release exists
The credential seam beneath this package changed. A credential source used to take no parameters, so
one registration answered identically for every connection an application opened — and where the
host could not infer an audience it supplied its own defaults, which on WebAssembly are Microsoft
Graph scopes. The framework's out-of-box credential could not authenticate a hub on the
application's own backend.
The fix is that a source is told which connection it is supplying for. This package is where that
information exists: it holds TConnection, and the transport beneath it does not.
What's new
A connection names its audience:
builder.AddRemoteConnection<ChatConnection>(options => {
options.EndpointUri = new Uri("https://api.example.com/hubs/chat");
options.Scopes = ["api://contoso/access_as_user"];
});The scopes reach the host's credential source, which mints for them rather than for its own
defaults. No per-application source to write.
The registration stamps the connection type, and a source registered keyed to that type is
preferred over the unkeyed one:
services.AddKeyedScoped<IRemoteConnectionCredentialSource, PartnerCredentialSource>(typeof(PartnerConnection));So a connection to a partner service can use a different mechanism, or a different identity
provider, than one to your own API — without either connection knowing about the other.
Fixed
A factory-created connection carries the registered scopes. The factory copies the registered
options per instance, and that copy is the only path a per-session connection's options travel. It
omitted Scopes, which would have left every per-session connection's credential source with no
audience to mint for — silently, since a forgotten property looks exactly like one that was never
set. Caught by a test written for the copy rather than for the feature.
Compatibility
- The registration verbs are unchanged, including their overloads, the
one-registration-per-connection-type rule, registration-time validation, and options-equality
dedup. - One
usingchanges where an application writes a connection type: the connection types moved
toCirreum.RemoteServices.Connections. - Declare
Scopeson every connection before upgrading. Paired withCirreum.Runtime.Wasm
4.0.0, a connection that declares none receives no credential and fails at connect. See
MIGRATION-v2.md.
See also
Cirreum.RemoteConnections.SignalR2.0.0 — the transport that resolves the source.Cirreum.Contracts5.0.0 — the credential contract and the reasoning behind its shape.Cirreum.Runtime.Wasm4.0.0 — the browser credential source that mints for the declared scopes.
Release v1.0.0
Cirreum.Runtime.RemoteConnections.SignalR 1.0.0
First release of the app-facing registration surface for Cirreum SignalR remote connections.
What this is for
Cirreum.RemoteConnections.SignalR supplies the connection; this package supplies the line that
registers it. Without it an application composes the singleton itself — build the context from the
provider, construct the connection, forward it as IRemoteConnection, and remember to do all three
the same way for the next connection. That composition is identical in every application, which
makes it exactly the kind of thing that drifts.
What it provides
AddRemoteConnection<TConnection>() registers a connection that lives as long as the
application:
builder.AddRemoteConnection<ChatConnection>(options => {
options.EndpointUri = new Uri("https://api.example.com/hubs/chat");
});It resolves as ChatConnection and as IRemoteConnection, so a status surface can inject
IEnumerable<IRemoteConnection> and render every connection's state without knowing the concrete
types. The container disposes it with the host; an application never disposes an injected
connection.
Registration does not connect. The application connects when the caller is ready — typically after
sign-in rather than at startup.
AddRemoteConnectionFactory<TConnection>() serves the other lifetime: a connection belonging to
a session rather than to the application, one per call or per bridge. It registers
IRemoteConnectionFactory<TConnection> and no connection instance, so a status surface enumerating
standing connections never sees per-session ones. Ownership inverts with the lifetime — the caller
creates, connects, and disposes what the factory returns.
Registration rules
One registration per connection type, in either shape. Registering the same type twice with
equal options is a no-op; with different options, or under both verbs, it throws. Subclass the
connection to reach a second endpoint — the client-side analogue of the server's one-instance-per-hub-type
rule.
The registry is keyed by service collection rather than held process-wide. A registry shared across
a process would make a second container — a test host, a second builder — silently skip registrations
the first container had already claimed.
Options are validated as they are registered. A missing or relative endpoint surfaces while the
application is composing, not when something first resolves the connection.
Host neutrality
Both verbs are extension members on IDomainApplicationBuilder, which a Blazor WebAssembly builder
and a server-side builder both implement. There is no per-host variant, and no .Wasm package.
Requirements
Cirreum.RemoteConnections.SignalR1.0.0 or later, which carries the transport and
SignalRRemoteConnection. It flows in transitively, along withCirreum.Domain,
Cirreum.ContractsandCirreum.Kernel.- A host registering
IRemoteConnectionTokenSourceif connections are to present the session
credential without configuring one —Cirreum.Runtime.Wasm3.0.0 does.