WebSocket v2
FabrCore 2.0 · Release and package availability
These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes
Authenticated real-time agent connectivity
WebSocket v2 is FabrCore's live principal transport. It carries typed agent operations and durable agent-to-principal deliveries, while HTTP remains responsible for provisioning agents and applying blueprints.
Raw AgentMessage frames, query/header principal selection, MessageType: "command", and createagent are removed. Migrate to FabrCore.Client.WebSocket or implement the v2 ticket, handshake, envelope, delivery, and acknowledgement protocol.
Install the typed client
dotnet add package FabrCore.Client.WebSocket --version 2.0.0
Connection flow
- Authenticate the client's
HttpClientthrough the application's ASP.NET Core authentication. POST /fabrcoreapi/ws/ticket. The Host resolves the authenticated principal and returns a single-use ticket valid for 30 seconds by default.- Open
/wsofferingfabrcore.v2andfabrcore.ticket.<token>as subprotocols. - Send
hellofirst with a stableclientIdand the last persisted checkpoint. - Process ordered
deliveryframes and acknowledge committed sequence numbers.
The Host overwrites sender/source fields with the authenticated principal. Bare agent targets are scoped to that principal; qualified targets pass through normal ACL enforcement. The System principal cannot connect.
Typed .NET client
Use a stable client id for the same logical browser profile, service instance, or device. Replace the in-memory checkpoint store when checkpoints must survive application restarts.
using FabrCore.Client.WebSocket;
var client = new FabrCoreWebSocketClient(
authenticatedHttpClient,
new FabrCoreWebSocketClientOptions
{
HostUri = new Uri("https://agents.example.com"),
ClientId = "ops-console-browser-42"
},
checkpointStore);
client.ResyncRequired += (_, gap) =>
{
// Rebuild application state through HTTP queries.
};
await client.ConnectAsync(cancellationToken);
await foreach (var delivery in client.ReadDeliveriesAsync(cancellationToken))
{
await ApplyToLocalState(delivery.Message, cancellationToken);
await client.AcknowledgeAsync(delivery.Sequence, cancellationToken);
}
Send a request/response message
var response = await client.SendMessageAndReceiveAsync(
new AgentMessage
{
ToHandle = "assistant",
Message = "Summarize today's incidents."
},
cancellationToken);
Supported operations
| Operation | Typed method | Purpose |
|---|---|---|
message.send | SendMessageAsync / SendMessageAndReceiveAsync | Explicit asynchronous or request/response message delivery. |
event.send | SendEventAsync | Publish an event. |
agent.reset | ResetAgentAsync | Soft-reset an existing agent. |
agent.health.get | GetAgentHealthAsync | Read agent health at the requested detail level. |
agents.tracked.list | GetTrackedAgentsAsync | List agents tracked for the connected principal. |
agent.tracked.check | IsAgentTrackedAsync | Check one tracked handle. |
agents.shared.list | GetSharedAgentsAsync | List ACL-visible shared agents. |
Creation, reconfiguration, hard eviction, blueprint application, and arbitrary provisioning are deliberately excluded. Use the Host REST APIs for those lifecycle operations.
Durable delivery, replay, and gaps
- Agent-to-principal messages are persisted before the v2 client is notified.
- Delivery is ordered and at-least-once for each stable
clientId. - A reconnect resumes after the lower of the server acknowledgement and client checkpoint. Duplicates are possible; silent skips are not.
- A new client id starts at the current tail rather than replaying another client's backlog.
- If retention removed a required record, the server emits
gap; rebuild application state through HTTP before continuing. - Queue saturation closes the socket with status 1013 instead of silently dropping durable deliveries.
- Mutating client requests are not automatically retried after an indeterminate disconnect.
Host configuration
{
"FabrCore": {
"Host": {
"AllowedWebSocketOrigins": ["https://app.example.com"]
},
"WebSocket": {
"TicketLifetime": "00:00:30",
"MaxConcurrentRequests": 8,
"RequestTimeout": "00:05:00",
"DeliveryRetention": "1.00:00:00",
"MaxDeliveriesPerPrincipal": 10000,
"MaxClientsPerPrincipal": 16,
"InactiveClientExpiration": "1.00:00:00",
"AllowDevelopmentPrincipalSelection": false
}
}
}
Production browser origins must be explicitly allowed. Headless clients may omit the Origin header. Keep development principal selection disabled outside local development.
v1 migration checklist
- Provision agents through HTTP or blueprints before connecting.
- Replace raw WebSocket construction with the typed client or the documented v2 handshake.
- Remove
x-fabrcore-userhandle,userhandle, and query-string identity selection. - Choose asynchronous versus request/response behavior explicitly.
- Persist checkpoints and make delivery handling idempotent.
- Implement HTTP resynchronization for
ResyncRequired.
Cloud administration uses HTTP polling
This WebSocket transport serves normal agent applications. The 2.0 cloud management connection continues to use outbound HTTP long polling and pollable operation receipts. There is no cloud WebSocket migration or diagnostic token stream in this release. Reserved _admin/_debug traffic is rejected through ordinary WebSocket chat; use privileged administration sessions.