Skip to main content

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

ParameterTypeDescription
urlstringEyesOnIt server URL, such as http://localhost:8000
optionsSocketIOOptionsOptional 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 SocketIOClient package defaults its path to /socket.io. If your EyesOnIt deployment exposes Socket.IO on /websocket, set options.Path = "/websocket" explicitly.

Connection And Disconnection

Typical flow:

  1. Create SocketClient.
  2. Register event handlers with +=.
  3. Join rooms directly or call JoinLiveSearchDetectionsAsync(...).
  4. Call ConnectAsync().
  5. Process incoming event payloads.
  6. Call LeaveRoomAsync(...) and DisconnectAsync() 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 underlying SocketIOClient.SocketIO instance 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(...), and JoinLiveSearchDetectionsAsync(...), then re-subscribes to them after reconnecting.
  • The C# SDK does not expose a public OnDisconnected event. Internally it logs disconnections and socket errors by handling the underlying OnDisconnected and OnError callbacks.

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 EventC# EventPayload Type
connection lifecycleOnConnectednone
subscribedOnSubscribedSubscribedData
stream_updateOnStreamUpdateStreamUpdateData[]
stream_detectionOnStreamDetectionStreamDetectionsData
performance_updateOnPerformanceUpdatePerformanceUpdateDataWrapper
live_search_updateOnLiveSearchUpdateLiveSearchUpdateData[]
live_search_detectionOnLiveSearchDetectionStreamDetectionsData

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:

ConstantRoom NameTypical Server Event
EOISocketRooms.AllStreamUpdatesall_stream_updatesstream_update
EOISocketRooms.AllStreamDetectionsall_stream_detectionsstream_detection
EOISocketRooms.AllPerformanceUpdatesall_performance_updatesperformance_update
EOISocketRooms.AllLiveSearchUpdatesall_live_search_updateslive_search_update
EOISocketRooms.LiveSearchDetectionslive_search_detectionsprefix for live_search_detection rooms

Room helpers:

  • JoinRoomAsync(room) stores the room locally and sends subscribe immediately if the socket is already connected.
  • JoinRoomsAsync(rooms) joins multiple rooms.
  • JoinLiveSearchDetectionsAsync(searchId) joins live_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 sends unsubscribe immediately if connected.
  • EOISocketRooms.StaticRoomNames contains 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:

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:

  • StreamUrl
  • Name
  • Event
  • Region
  • Time
  • FrameNum
  • ClassName
  • ObjectDescription
  • Condition
  • ResultId
  • Base64Image
  • Image

Condition is StreamDetectionConditionData, which can include:

  • Type
  • Count
  • LineName
  • AlertDirection
  • Objects

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:

Both performance types expose StreamUrl, CPUPercent, and GPUPercent.

OnLiveSearchUpdate

OnLiveSearchUpdate receives LiveSearchUpdateData[].

Each array entry includes:

  • SearchId
  • SearchType
  • ClassName
  • ObjectDescription
  • FaceMatchType
  • FacePersonId
  • FaceGroupId
  • Similarity
  • AlertThreshold
  • StartTime
  • EndTime
  • Active
  • Notification

Similarity is LiveSearchUpdateSimilarityData, which contains LiveSearchUpdateSimilarityImageData[].

Methods

MethodPurpose
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.