Socket Handling
Use SocketClient when you want real-time stream, live-search, and performance updates from EyesOnIt instead of polling REST endpoints.
Imports
Import the socket client, room helpers, and the underlying Socket.IO options type:
using System;
using System.Threading.Tasks;
using SocketIOClient;
using EyesOnItSDK.SocketIO;
Create A Socket Client
Create the client with the EyesOnIt server URL and, optionally, SocketIOOptions from SocketIOClient.
var socket = new SocketClient("http://localhost:8000");
var socketWithOptions = new SocketClient(
"http://localhost:8000",
new SocketIOOptions
{
Path = "/websocket",
Reconnection = true
}
);
Constructor Parameters
| Parameter | Type | Description |
|---|---|---|
url | string | EyesOnIt server URL, such as http://localhost:8000 |
options | SocketIOOptions | Optional Socket.IO client options passed directly to SocketIOClient.SocketIO |
Common SocketIOOptions fields include Path, Query, ExtraHeaders, Auth, Reconnection, ReconnectionAttempts, ReconnectionDelay, ReconnectionDelayMax, ConnectionTimeout, Transport, and Proxy.
Notes:
- The C# SDK creates the underlying Socket.IO client lazily inside
ConnectAsync(). - The SDK sets
socket.Serializer = new NewtonsoftJsonSerializer()automatically. - The underlying
SocketIOClientpackage defaults its path to/socket.io. If your EyesOnIt deployment exposes Socket.IO on/websocket, setoptions.Path = "/websocket"explicitly.
Connection And Disconnection
Typical flow:
- Create
SocketClient. - Register event handlers with
+=. - Join rooms directly or call
JoinLiveSearchDetectionsAsync(...). - Call
ConnectAsync(). - Process incoming event payloads.
- Call
LeaveRoomAsync(...)andDisconnectAsync()when finished.
Example:
using System;
using System.Threading.Tasks;
using SocketIOClient;
using EyesOnItSDK.SocketIO;
public static async Task Main()
{
var socket = new SocketClient(
"http://localhost:8000",
new SocketIOOptions
{
Path = "/websocket",
Reconnection = true
}
);
socket.OnConnected += () => Console.WriteLine("Connected");
socket.OnSubscribed += payload => Console.WriteLine($"Subscribed to {payload.Room}");
socket.OnStreamDetection += payload =>
{
foreach (var detection in payload.Detections ?? Array.Empty<StreamDetectionData>())
{
Console.WriteLine($"{detection.Name}: {detection.Event} at {detection.Time}");
}
};
socket.OnPerformanceUpdate += payload =>
{
var totals = payload?.Performance?.Totals;
Console.WriteLine($"CPU {totals?.CPUPercent}, GPU {totals?.GPUPercent}");
};
await socket.JoinRoomsAsync(new[]
{
EOISocketRooms.AllStreamDetections,
EOISocketRooms.AllPerformanceUpdates
});
var liveSearchRoom = await socket.JoinLiveSearchDetectionsAsync(42);
Console.WriteLine($"Queued room {liveSearchRoom}");
await socket.ConnectAsync();
await socket.DisconnectAsync();
}
Connection behavior:
ConnectAsync()creates the underlyingSocketIOClient.SocketIOinstance the first time it is called, registers handlers once, and then opens the connection if it is not already connected.DisconnectAsync()closes the active connection if one exists.IsConnected()reports the current connection state.- The SDK remembers rooms joined through
JoinRoomAsync(...),JoinRoomsAsync(...), andJoinLiveSearchDetectionsAsync(...), then re-subscribes to them after reconnecting. - The C# SDK does not expose a public
OnDisconnectedevent. Internally it logs disconnections and socket errors by handling the underlyingOnDisconnectedandOnErrorcallbacks.
Handlers
In the C# SDK, socket handlers are exposed as .NET events. Subscribe with += and remove handlers later with -=.
The socket client listens for these server events:
| Server Event | C# Event | Payload Type |
|---|---|---|
| connection lifecycle | OnConnected | none |
subscribed | OnSubscribed | SubscribedData |
stream_update | OnStreamUpdate | StreamUpdateData[] |
stream_detection | OnStreamDetection | StreamDetectionsData |
performance_update | OnPerformanceUpdate | PerformanceUpdateDataWrapper |
live_search_update | OnLiveSearchUpdate | LiveSearchUpdateData[] |
live_search_detection | OnLiveSearchDetection | StreamDetectionsData |
Example:
socket.OnStreamUpdate += payload =>
{
foreach (var stream in payload ?? Array.Empty<StreamUpdateData>())
{
Console.WriteLine($"{stream.Name}: {stream.Status}");
}
};
socket.OnLiveSearchUpdate += payload =>
{
foreach (var search in payload ?? Array.Empty<LiveSearchUpdateData>())
{
Console.WriteLine($"Search {search.SearchId}: active = {search.Active}");
}
};
Rooms And Subscriptions
The SDK exports the built-in room names used by the EyesOnIt socket server:
| Constant | Room Name | Typical Server Event |
|---|---|---|
EOISocketRooms.AllStreamUpdates | all_stream_updates | stream_update |
EOISocketRooms.AllStreamDetections | all_stream_detections | stream_detection |
EOISocketRooms.AllPerformanceUpdates | all_performance_updates | performance_update |
EOISocketRooms.AllLiveSearchUpdates | all_live_search_updates | live_search_update |
EOISocketRooms.LiveSearchDetections | live_search_detections | prefix for live_search_detection rooms |
Room helpers:
JoinRoomAsync(room)stores the room locally and sendssubscribeimmediately if the socket is already connected.JoinRoomsAsync(rooms)joins multiple rooms.JoinLiveSearchDetectionsAsync(searchId)joinslive_search_detections_<searchId>and returns that room name.EOISocketRooms.LiveSearchDetectionsForSearch(searchId)builds the same live-search room name without joining it.LeaveRoomAsync(room)removes the room locally and sendsunsubscribeimmediately if connected.EOISocketRooms.StaticRoomNamescontains the static room constants other than the live-search detection prefix.
Event And Message Types
OnConnected
OnConnected does not receive a payload. The SDK raises it after the underlying socket connects and after it re-subscribes any remembered rooms.
OnSubscribed
OnSubscribed receives SubscribedData:
public class SubscribedData
{
public string Room { get; set; }
}
Use this event to confirm which room the server acknowledged.
OnStreamUpdate
OnStreamUpdate receives StreamUpdateData[].
Each array entry describes one stream:
public class StreamUpdateData
{
public string StreamUrl { get; set; }
public string Name { get; set; }
public string Status { get; set; }
public StreamUpdateRegionData[] Regions { get; set; }
}
Nested socket types used here are:
StreamUpdateRegionData:Name,DetectionConfigurationsStreamUpdateDetectionConfigsData:ClassName,ObjectDescriptionsStreamObjectDescriptionsData:Text,Confidence,OverThreshold
OnStreamDetection And OnLiveSearchDetection
OnStreamDetection and OnLiveSearchDetection both receive StreamDetectionsData:
public class StreamDetectionsData
{
public StreamDetectionData[] Detections { get; set; }
public string Base64Image { get; set; }
public System.Drawing.Image Image { get; set; }
}
Each detection in Detections is a StreamDetectionData object with fields such as:
StreamUrlNameEventRegionTimeFrameNumClassNameObjectDescriptionConditionResultIdBase64ImageImage
Condition is StreamDetectionConditionData, which can include:
TypeCountLineNameAlertDirectionObjects
Each object in Condition.Objects is StreamDetectionObjectData, which includes object descriptions, bounding box data, and optional image data. Bounding boxes use StreamDetectionBoundsData with Left, Top, Width, and Height.
When Base64Image is present on StreamDetectionsData, StreamDetectionData, or StreamDetectionObjectData, the SDK also decodes it into the corresponding Image property.
OnPerformanceUpdate
OnPerformanceUpdate receives PerformanceUpdateDataWrapper:
public class PerformanceUpdateDataWrapper
{
public PerformanceUpdateData Performance { get; set; }
}
Performance is PerformanceUpdateData, which contains:
Streams:PerformanceStreamData[]Totals:PerformanceTotalsData
Both performance types expose StreamUrl, CPUPercent, and GPUPercent.
OnLiveSearchUpdate
OnLiveSearchUpdate receives LiveSearchUpdateData[].
Each array entry includes:
SearchIdSearchTypeClassNameObjectDescriptionFaceMatchTypeFacePersonIdFaceGroupIdSimilarityAlertThresholdStartTimeEndTimeActiveNotification
Similarity is LiveSearchUpdateSimilarityData, which contains LiveSearchUpdateSimilarityImageData[].
Methods
| Method | Purpose |
|---|---|
ConnectAsync() | Opens the Socket.IO connection |
DisconnectAsync() | Closes the connection if it is active |
JoinRoomAsync(string room) | Remembers a room and subscribes immediately when connected |
JoinRoomsAsync(IEnumerable<string> rooms) | Joins multiple rooms |
JoinLiveSearchDetectionsAsync(int searchId) | Builds and joins a live-search detection room |
LeaveRoomAsync(string room) | Forgets a room and unsubscribes immediately when connected |
EmitAsync(string eventName, params object[] args) | Sends a custom event and requires an active connection |
IsConnected() | Returns the current connection state |
EmitAsync(...) throws InvalidOperationException if the socket is not connected. JoinRoomAsync(...) and LeaveRoomAsync(...) do not throw when disconnected; they update the locally remembered room list and only emit subscribe or unsubscribe immediately when a connection already exists.
See the API Reference for the field-by-field class reference.