SignalR & Real-time
The Frontend API uses SignalR (backed by Azure SignalR Service) to provide real-time updates to connected clients. The CameraHub groups clients by camera ID and broadcasts image updates, activity logs, panorama images, and configuration changes.
CameraHub
Endpoint: /cameraHub
Protocol: WebSocket (wss://[hostname]/cameraHub)
Connection Flow
Hub Methods (Client → Server)
| Method | Parameters | Description |
|---|---|---|
JoinGroup | cameraId: string | Subscribe to updates for a specific camera. Adds the client's connection to the camera's SignalR group. |
LeaveGroup | cameraId: string | Unsubscribe from a camera's updates. Removes the client from the group. |
Broadcast Methods (Server → Group)
These methods send data to all clients in the specified camera group, excluding the sender.
| Hub Method | Client Receive Event | Payload | Description |
|---|---|---|---|
BroadcastImageToGroup | ReceiveImageBroadcast | SingleImageMetadataEntity | Broadcasts the latest captured image metadata for a camera |
BroadcastActivityLogMessageToGroup | ReceiveActivityLogBroadcast | SingleImageMetadataEntity | Broadcasts activity log entries (PTZ moves, guard tour toggles, manual messages) |
BroadcastPanoImageToGroup | ReceivePanoImageBroadcast | PanoImageMetadataEntity | Broadcasts the latest panorama image metadata |
BroadcastCurrentConfigToGroup | ReceiveCurrentConfigBroadcast | string (JSON) | Broadcasts camera configuration changes |
BroadcastSingleImageToGroup (client event: ReceiveBroadcast) is deprecated. Use BroadcastImageToGroup / ReceiveImageBroadcast instead.
Group Pattern
- Each camera has its own SignalR group identified by
cameraId - Clients can join multiple camera groups simultaneously
- Broadcasts are sent to all group members except the sender (
Clients.GroupExcept) - This prevents echo effects where the sender receives its own broadcast
BroadcastService (Server-Side)
The BroadcastService is a scoped service used by controllers to push activity log messages to SignalR groups from server-side operations (as opposed to client-initiated hub calls).
| Method | Description |
|---|---|
BroadcastActivityMessageToGroup(cameraId, message) | Sends an ActivityLogLatestByCamera record to all clients in the camera's group |
Used by:
ActivityLogController.AddMessage()— After inserting an activity log record, broadcasts it to the camera groupCameraMovementController.ToggleGuardTour()— After toggling patrol mode, broadcasts the activity log entryCameraMovementController.MoveCameraHome()— After a home move completes, broadcasts the activity log entryFunctionEndpointsController.LeaseCameraAfterMove()— After the Image Acquisition callback processes a lease, broadcasts the activity log entry
Client Integration
Connecting to the Hub
// Example: JavaScript/TypeScript client connection
import { HubConnectionBuilder } from "@microsoft/signalr";
const connection = new HubConnectionBuilder()
.withUrl("https://{api-hostname}/cameraHub")
.withAutomaticReconnect()
.build();
await connection.start();
Subscribing to Camera Updates
// Join a camera group
await connection.invoke("JoinGroup", "camera-001");
// Listen for image updates
connection.on("ReceiveImageBroadcast", (metadata) => {
console.log("New image:", metadata.imageUrl);
});
// Listen for activity log updates
connection.on("ReceiveActivityLogBroadcast", (message) => {
console.log("Activity:", message);
});
// Listen for panorama updates
connection.on("ReceivePanoImageBroadcast", (metadata) => {
console.log("New panorama:", metadata.imageUrl);
});
// Listen for config changes
connection.on("ReceiveCurrentConfigBroadcast", (config) => {
console.log("Config update:", config);
});
Leaving a Camera Group
await connection.invoke("LeaveGroup", "camera-001");
Configuration
SignalR is configured in ConfigureServices.cs and Program.cs:
// ConfigureServices.cs — Register SignalR with Azure backing
services.AddSignalR().AddAzureSignalR();
// Program.cs — Map the hub endpoint
app.MapHub<CameraHub>("/cameraHub");
The Azure SignalR Service connection string is loaded from Azure App Configuration / Key Vault. No local SignalR development server is needed — the Azure SignalR Service handles connection scaling in all environments.