Ikon.Sdk
2.0.4
See the version list below for details.
dotnet add package Ikon.Sdk --version 2.0.4
NuGet\Install-Package Ikon.Sdk -Version 2.0.4
<PackageReference Include="Ikon.Sdk" Version="2.0.4" />
<PackageVersion Include="Ikon.Sdk" Version="2.0.4" />
<PackageReference Include="Ikon.Sdk" />
paket add Ikon.Sdk --version 2.0.4
#r "nuget: Ikon.Sdk, 2.0.4"
#:package Ikon.Sdk@2.0.4
#addin nuget:?package=Ikon.Sdk&version=2.0.4
#tool nuget:?package=Ikon.Sdk&version=2.0.4
Ikon AI C# SDK
The Ikon AI C# SDK provides a simple way to connect to Ikon AI App from any .NET application. It supports .NET 10 and .NET Standard 2.1 (including Unity).
Features
- Three authentication modes: API Key, Local Development, Backend
- Automatic reconnection with exponential backoff
- Audio streaming with Opus encoding/decoding
- Flexible audio streaming modes
- Function registration and remote invocation
- Low-level protocol message access
Installation
Install the NuGet package:
dotnet add package Ikon.Sdk
Quick Start
using Ikon.Sdk;
// Create configuration with API key authentication
var config = new IkonClientConfig
{
ApiKey = new ApiKeyConfig
{
ApiKey = Environment.GetEnvironmentVariable("IKON_API_KEY")!,
SpaceId = "your-space-id",
ExternalUserId = "user-123"
},
Description = "My App"
};
// Create and connect the client
using var client = new IkonClient(config);
client.Ready += async (sender, e) =>
{
Console.WriteLine("Connected!");
client.SignalReady();
};
client.MessageReceived += async (sender, e) =>
{
Console.WriteLine($"Received: {e.Message.Opcode}");
};
await client.ConnectAsync();
Authentication Modes
The SDK supports three authentication modes. Exactly one must be configured.
API Key Authentication
Use this for programmatic access to Ikon AI App. Get your API key from the Ikon portal.
var config = new IkonClientConfig
{
ApiKey = new ApiKeyConfig
{
ApiKey = "ikon-xxxxx", // API key from portal
SpaceId = "...", // Space ID
ExternalUserId = "user-123", // Your user identifier
ChannelKey = "main", // Optional: specific channel
BackendType = BackendType.Production,
UserType = UserType.Human,
ClientType = ClientType.DesktopApp
}
};
Local Development
Connect directly to a local Ikon server during development.
var config = new IkonClientConfig
{
Local = new LocalConfig
{
Host = "localhost",
HttpsPort = 8443,
UserId = "dev-user"
}
};
Backend Authentication
Use existing Ikon backend login credentials. This is for applications that have already authenticated to the backend.
var config = new IkonClientConfig
{
Backend = new BackendConfig
{
SpaceId = "...",
ChannelKey = "main", // Optional
UserType = UserType.Human,
ClientType = ClientType.DesktopApp
}
};
Connection Lifecycle
Connection States
The client tracks its connection state via the State property:
| State | Description |
|---|---|
Idle |
Initial state, not connected |
Connecting |
Authentication and connection in progress |
Connected |
Fully connected and ready |
Reconnecting |
Lost connection, attempting automatic reconnect |
Offline |
Disconnected (user-initiated or max retries exceeded) |
Helper extension methods are available:
state.IsConnecting()- True ifConnectingorReconnectingstate.IsConnected()- True ifConnectedstate.IsOffline()- True ifIdleorOffline
Events
// Connection state changes
client.StateChanged += async (sender, e) =>
{
Console.WriteLine($"State: {e.State}");
};
// Connection established and ready
client.Ready += async (sender, e) =>
{
// Perform initialization here
client.SignalReady(); // Signal that this client is ready (mandatory)
};
// Server is stopping (can still send messages)
client.Stopping += async (sender, e) =>
{
Console.WriteLine("Server stopping...");
};
// Disconnected from server
client.Disconnected += async (sender, e) =>
{
Console.WriteLine("Disconnected");
};
// Error occurred
client.ErrorOccurred += async (sender, e) =>
{
Console.WriteLine($"Error: {e.Error.Message}");
};
// Protocol message received
client.MessageReceived += async (sender, e) =>
{
Console.WriteLine($"Message: {e.Message.Opcode}");
};
Connecting and Disconnecting
// Connect (will throw on failure)
await client.ConnectAsync();
// Wait for a specific client to connect
bool found = await client.WaitForClientAsync(
productId: "my-product",
userId: "user-123",
timeout: TimeSpan.FromSeconds(30)
);
// Disconnect
await client.DisconnectAsync();
// Or dispose (also disconnects)
client.Dispose();
Automatic Reconnection
The SDK automatically attempts to reconnect when the connection is lost unexpectedly. Configure reconnection behavior:
var config = new IkonClientConfig
{
// ... authentication config ...
Timeouts = new TimeoutConfig
{
ReconnectBackoff = TimeSpan.FromMilliseconds(500), // Initial backoff
MaxReconnectAttempts = 6 // Max attempts
}
};
Reconnection uses exponential backoff (500ms, 1s, 2s, 4s, 8s, 16s by default).
Sending Messages
Raw Protocol Messages
// Send a raw protocol message
var message = ProtocolMessage.Create(client.ClientContext.SessionId, payload);
client.SendMessage(message);
Typed Payloads
// Send a typed payload (creates ProtocolMessage automatically)
client.SendMessage(new MyCustomPayload { /* ... */ });
Audio
The SDK provides comprehensive audio support with automatic Opus encoding/decoding.
Sending Audio
Send audio to the server:
// Get audio samples (float PCM, range [-1.0, 1.0])
ReadOnlyMemory<float> samples = GetAudioSamples();
// Send audio
client.SendAudio(
samples: samples,
sampleRate: 48000,
channelCount: 1,
isFirst: true, // First chunk of this stream
isLast: false // More chunks coming
);
// Send final chunk
client.SendAudio(samples, 48000, 1, isFirst: false, isLast: true);
// Optional: specify stream ID, total duration, encoder options, and target clients
client.SendAudio(
samples: samples,
sampleRate: 48000,
channelCount: 1,
isFirst: true,
isLast: true,
streamId: "my-audio-stream", // Unique stream identifier
totalDuration: TimeSpan.FromSeconds(5),
encoderOptions: new AudioEncoderOptions // Custom encoder settings
{
Bitrate = 64000,
Complexity = 10
},
targetIds: new[] { 123, 456 } // Target specific session IDs
);
// Set default encoder options for all audio
client.DefaultEncoderOptions = new AudioEncoderOptions
{
Bitrate = 48000,
Complexity = 8
};
Receiving Audio
Subscribe to audio events to receive incoming audio streams:
client.AudioInputStreamBeginAsync += async (sender, e) =>
{
Console.WriteLine($"Audio stream started: {e.StreamId}");
Console.WriteLine($" Codec: {e.Codec}");
Console.WriteLine($" Sample rate: {e.SampleRate}");
Console.WriteLine($" Channel count: {e.ChannelCount}");
// Optional: override sample rate (SDK will resample)
// e.SampleRate = 44100;
// Optional: change streaming mode
// e.StreamingMode = AudioInputStreamingMode.DelayUntilTotalDurationKnown;
};
client.AudioInputFrameAsync += async (sender, e) =>
{
// e.Samples contains decoded PCM float samples
float[] samples = e.Samples;
Console.WriteLine($"Frame: {e.StreamId}");
Console.WriteLine($" Samples: {samples.Length}");
Console.WriteLine($" IsFirst: {e.IsFirst}");
Console.WriteLine($" IsLast: {e.IsLast}");
Console.WriteLine($" Total duration: {e.TotalDuration}"); // Zero if unknown
// Process or play the audio samples...
};
client.AudioInputStreamEndAsync += async (sender, e) =>
{
Console.WriteLine($"Audio stream ended: {e.StreamId}");
};
Audio Streaming Modes
Control how audio frames are delivered:
| Mode | Behavior |
|---|---|
Streaming |
Forward frames immediately (lowest latency) |
DelayUntilTotalDurationKnown |
Buffer until the total duration is known, then stream |
DelayUntilIsLast |
Buffer everything, emit all frames when stream ends |
Set the streaming mode in the AudioInputStreamBeginAsync event handler:
client.AudioInputStreamBeginAsync += async (sender, e) =>
{
// Buffer audio for UI timeline display
e.StreamingMode = AudioInputStreamingMode.DelayUntilTotalDurationKnown;
};
Functions
The SDK provides a function registry system that allows you to register callable functions that can be invoked locally or shared with other connected clients via the server.
Registering Functions
Attribute-Based Registration (Recommended)
Mark methods with the [Function] attribute and register the containing class:
using Ikon.Common.Core.Functions;
public class MyFunctions
{
[Function(Description = "Greets a user by name")]
public string Greet(string name)
{
return $"Hello, {name}!";
}
[Function(Description = "Calculates sum", Visibility = FunctionVisibility.Shared)]
public async Task<int> AddAsync(int a, int b)
{
return a + b;
}
[Function(Description = "Streams numbers")]
public async IAsyncEnumerable<int> CountAsync(int max)
{
for (int i = 0; i < max; i++)
yield return i;
}
}
// Register all [Function] methods from an instance
var myFuncs = new MyFunctions();
FunctionRegistry.Instance.RegisterFromInstance(myFuncs);
// Or register from a type (static methods only)
FunctionRegistry.Instance.RegisterFromType<MyStaticFunctions>();
// Or scan entire assembly
FunctionRegistry.Instance.RegisterFromAssembly(typeof(MyFunctions).Assembly);
Manual Registration (Lambda/Delegate)
Register functions directly using lambdas:
// Simple synchronous function
FunctionRegistry.Instance.AddFunction(
Function.Register((string name) => $"Hello, {name}!", "Greet")
);
// Async function
FunctionRegistry.Instance.AddFunction(
Function.Register(async (int a, int b) =>
{
await Task.Delay(10);
return a + b;
}, "AddAsync")
);
// With attributes (description, visibility, etc.)
FunctionRegistry.Instance.AddFunction(
Function.Register(
(string query) => SearchDatabase(query),
"Search",
new FunctionAttribute { Description = "Searches the database", Visibility = FunctionVisibility.Shared }
)
);
Function Visibility
Functions can be either local or shared:
- Local (default): Only available within this process
- Shared: Distributed to the server and accessible by other connected clients
// Local - only available in this process (default)
[Function(Visibility = FunctionVisibility.Local)]
public string LocalOnly() => "local";
// Shared - distributed to server and other clients
[Function(Visibility = FunctionVisibility.Shared)]
public string SharedWithAll() => "shared";
// Override visibility at registration time
FunctionRegistry.Instance.RegisterFromInstance(myFuncs, FunctionVisibility.Shared);
Discovering Functions
Query the registry to find available functions:
// Get all registered function names
var names = FunctionRegistry.Instance.GetAllFunctionNames();
// Check if a function exists
if (FunctionRegistry.Instance.HasFunction("MyFunc"))
{
var func = FunctionRegistry.Instance.GetFunction("MyFunc");
Console.WriteLine($"Found: {func?.Name}, Params: {func?.Parameters.Length}");
}
// Get all functions (including remote)
var allFuncs = FunctionRegistry.Instance.Functions;
// Get only remote functions (registered by other clients)
var remoteFuncs = FunctionRegistry.Instance.GetRemoteFunctions();
// Get only local functions
var localFuncs = FunctionRegistry.Instance.GetLocalFunctions();
// Find which clients have a specific function
var clientIds = FunctionRegistry.Instance.GetClientSessionsWithFunction("SharedFunc");
Calling Functions
Call registered functions locally or remotely:
// Synchronous call
string result = FunctionRegistry.Instance.Call<string>("Greet", "World");
// Async call
int sum = await FunctionRegistry.Instance.CallAsync<int>("AddAsync", 1, 2);
// Void async call
await FunctionRegistry.Instance.CallAsync("LogMessage", "Hello");
// Call a function on a specific remote client
int remoteSum = await FunctionRegistry.Instance.CallAsync<int>("Calculate", targetId: 123, 5, 10);
// Streaming results (async enumerable)
await foreach (var item in FunctionRegistry.Instance.CallAsyncEnumerable<int>("CountAsync", 10))
{
Console.WriteLine(item);
}
Removing Functions
// Remove a specific function by name (local functions only)
FunctionRegistry.Instance.RemoveFunction("MyFunc");
// Clear all local functions
FunctionRegistry.Instance.ClearLocalFunctions();
Function Events
Subscribe to function registration events:
FunctionRegistry.Instance.FunctionRegistered += func =>
{
Console.WriteLine($"Registered: {func.Name} ({func.Attribute.Visibility})");
};
FunctionRegistry.Instance.FunctionUnregistered += name =>
{
Console.WriteLine($"Unregistered: {name}");
};
Advanced Configuration
Timeouts
var config = new IkonClientConfig
{
// ... authentication ...
Timeouts = new TimeoutConfig
{
ConnectionTimeout = TimeSpan.FromSeconds(30), // Connection timeout
ProvisioningTimeout = TimeSpan.FromSeconds(60), // Server startup timeout
KeepaliveTimeout = TimeSpan.FromSeconds(125), // Keepalive timeout
ReconnectBackoff = TimeSpan.FromMilliseconds(500),
MaxReconnectAttempts = 6
}
};
Protocol Options
var config = new IkonClientConfig
{
// ... authentication ...
// Filter which message types to receive/send
OpcodeGroupsFromServer = Opcode.GROUP_ALL,
OpcodeGroupsToServer = Opcode.GROUP_ALL,
// Receive all messages, not just those targeted to this client
ReceiveAllMessages = false,
// Payload serialization format
PayloadType = PayloadType.Teleport // Default
};
Client Identification
var config = new IkonClientConfig
{
// ... authentication ...
DeviceId = "unique-device-id",
ProductId = "my-app",
VersionId = "1.0.0",
InstallId = "install-xyz",
Locale = "en-US",
Description = "My Application",
UserAgent = "my-app/1.0.0",
Parameters = new Dictionary<string, string>
{
["custom_param"] = "value"
}
};
API Reference
Core Types
| Type | Description |
|---|---|
IkonClient |
Main client class for connecting to Ikon servers |
IkonClientConfig |
Configuration for the client |
ConnectionState |
Enum: Idle, Connecting, Connected, Reconnecting, Offline |
Configuration Types
| Type | Description |
|---|---|
LocalConfig |
Configuration for local server development |
ApiKeyConfig |
Configuration for API key authentication |
BackendConfig |
Configuration for backend authentication |
TimeoutConfig |
Timeout settings |
BackendType |
Enum: Production, Development |
Audio Types
| Type | Description |
|---|---|
AudioInputStreamingMode |
Enum: Streaming, DelayUntilTotalDurationKnown, DelayUntilIsLast |
AudioInputStreamBeginEventArgs |
Event args for audio stream start |
AudioInputFrameEventArgs |
Event args for audio frame |
AudioInputStreamEndEventArgs |
Event args for audio stream end |
AudioEncoderOptions |
Options for configuring the Opus encoder |
Function Types
| Type | Description |
|---|---|
FunctionRegistry |
Central registry for function registration and invocation |
Function |
Immutable function metadata and callback |
FunctionAttribute |
Attribute for marking methods as registerable functions |
FunctionVisibility |
Enum: Local, Shared |
FunctionParameter |
Parameter metadata (name, type, default value) |
Event Types
| Type | Description |
|---|---|
MessageEventArgs |
Event args containing a ProtocolMessage |
ConnectionStateEventArgs |
Event args containing the new ConnectionState |
ErrorEventArgs |
Event args containing an Exception |
License
This SDK is licensed under the Ikon AI SDK License. See LICENSE for details.
Support
For issues and feature requests, contact Ikon support or open an issue on GitHub.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Ikon.Common.Core (>= 3.1.40)
- Ikon.Resonance.Core (>= 3.1.40)
- System.Net.Http.Json (>= 10.0.0)
-
net10.0
- Ikon.Common.Core (>= 3.1.40)
- Ikon.Resonance.Core (>= 3.1.40)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.