Roomzin.Sdk 2.0.0

dotnet add package Roomzin.Sdk --version 2.0.0
                    
NuGet\Install-Package Roomzin.Sdk -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Roomzin.Sdk" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Roomzin.Sdk" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Roomzin.Sdk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Roomzin.Sdk --version 2.0.0
                    
#r "nuget: Roomzin.Sdk, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Roomzin.Sdk@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Roomzin.Sdk&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Roomzin.Sdk&version=2.0.0
                    
Install as a Cake Tool

Roomzin C# SDK

Official C# SDK for Roomzin — a high-performance in-memory inventory engine for booking platforms.

The SDK provides a modern, idiomatic C# interface for communicating with Roomzin servers in both standalone and clustered deployments. It automatically handles connection management, request/response demuxing, and self-healing reconnections.


Features

  • Unified client for standalone and router (cluster) modes
  • Built-in connection self-healing
  • Automatic request routing (writes to leader, reads to followers) via router
  • Fully typed C# API
  • Async/await support
  • IAsyncDisposable client for resource management
  • Type-safe API with segment support

Requirements

  • .NET 6 or later
  • Roomzin Server v1.x
  • Roomzin Router (for cluster mode)

Installation

dotnet add package Roomzin.Sdk

Or via the NuGet Package Manager:

Install-Package Roomzin.Sdk

Client Setup

Standalone Mode

Connect directly to a standalone Roomzin server:

using Roomzin.Sdk;

var config = ConfigFactory.CreateConfig()
    .WithAddr("127.0.0.1")
    .WithPort(7777)
    .WithMode(Mode.Standalone)
    .WithTimeout(TimeSpan.FromSeconds(5))
    .WithKeepAlive(TimeSpan.FromSeconds(30))
    .Build();

var client = new Client(config);
await client.ConnectAsync();
await client.CloseAsync();

Cluster Mode (via Router)

Connect to a Roomzin cluster through the router:

using Roomzin.Sdk;

var config = ConfigFactory.CreateConfig()
    .WithAddr("router.example.com")
    .WithPort(9200)
    .WithMode(Mode.Router)
    .WithTimeout(TimeSpan.FromSeconds(30))
    .WithKeepAlive(TimeSpan.FromSeconds(30))
    .Build();

var client = new Client(config);
await client.ConnectAsync();
await client.CloseAsync();

Using Statement

using var client = new Client(config);
await client.ConnectAsync();
// Use client...
// Automatically disposed

Configuration Options

Option Description Default
WithAddr() Server or router address Required
WithPort() TCP port Required
WithMode() Mode.Standalone or Mode.Router Mode.Standalone
WithTimeout() Request timeout 2s
WithKeepAlive() TCP keep-alive interval 30s

Segment Routing

In cluster mode, every request must specify a segment. The router uses this to route the request to the correct shard.

string segment = "us-east";

// All API methods accept segment as a parameter
await client.SetPropAsync(segment, payload);

In standalone mode, the segment parameter is ignored but still required for API compatibility. This allows you to switch between standalone and cluster modes without changing your business logic.


Property Management

SetPropAsync

Adds or updates a property.

await client.SetPropAsync("downtown", new SetPropPayload
{
    Segment = "downtown",
    Area = "manhattan",
    PropertyId = "hotel_123",
    PropertyType = "hotel",
    Category = "luxury",
    Stars = 4,
    Latitude = 40.7128,
    Longitude = -74.0060,
    Amenities = new List<string> { "wifi", "pool", "gym" }
});

SearchPropAsync

Searches properties by segment, area, type, or location.

// By segment
var ids = await client.SearchPropAsync("downtown", new SearchPropPayload
{
    Segment = "downtown"
});

// By area
var ids = await client.SearchPropAsync("downtown", new SearchPropPayload
{
    Segment = "downtown",
    Area = "manhattan"
});

// By location (radius search)
var ids = await client.SearchPropAsync("downtown", new SearchPropPayload
{
    Segment = "downtown",
    Latitude = 40.7128,
    Longitude = -74.0060
});

PropExistAsync

Checks if a property exists.

bool exists = await client.PropExistAsync("downtown", "hotel_123");

PropRoomExistAsync

Checks if a specific room type exists for a property.

bool exists = await client.PropRoomExistAsync("downtown", new PropRoomExistPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite"
});

PropRoomListAsync

Lists all room types for a property.

var rooms = await client.PropRoomListAsync("downtown", "hotel_123");

PropRoomDateListAsync

Lists dates with availability data for a property and room type.

var dates = await client.PropRoomDateListAsync("downtown", new PropRoomDateListPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite"
});

Room Package Management

SetRoomPkgAsync

Sets availability, price, and rate features for a room type on a date.

await client.SetRoomPkgAsync("downtown", new SetRoomPkgPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20",
    Availability = 10,
    FinalPrice = 199,
    RateFeature = new List<string> { "free_cancellation", "breakfast_included" }
});

SetRoomAvlAsync

Sets exact availability for a room type on a specific date.

byte newAvail = await client.SetRoomAvlAsync("downtown", new UpdRoomAvlPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20",
    Amount = 20
});

IncRoomAvlAsync

Increases availability (e.g., on cancellation).

byte newAvail = await client.IncRoomAvlAsync("downtown", new UpdRoomAvlPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20",
    Amount = 1
});

DecRoomAvlAsync

Decreases availability (e.g., on booking).

byte newAvail = await client.DecRoomAvlAsync("downtown", new UpdRoomAvlPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20",
    Amount = 2
});

GetPropRoomDayAsync

Gets availability and pricing for a specific room on a specific date.

var day = await client.GetPropRoomDayAsync("downtown", new GetRoomDayRequest
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20"
});
Console.WriteLine($"Avail: {day.Availability}, Price: {day.FinalPrice}");

Search & Query

SearchAvailAsync

Searches available rooms by filters.

var results = await client.SearchAvailAsync("downtown", new SearchAvailPayload
{
    Segment = "downtown",
    RoomType = "suite",
    Date = new List<string> { "2026-07-20", "2026-07-21" },
    Limit = 50,
    MinPrice = 100,
    MaxPrice = 300,
    Amenities = new List<string> { "wifi", "pool" },
    RateFeature = new List<string> { "free_cancellation" }
});

foreach (var result in results)
{
    Console.WriteLine($"Property: {result.PropertyId}");
    foreach (var day in result.Days)
    {
        Console.WriteLine($"  {day.Date}: Avail {day.Availability}, Price {day.FinalPrice}");
    }
}

GetCodecsAsync

Gets the current codec registry (used internally for validation).

var codecs = await client.GetCodecsAsync();
Console.WriteLine(string.Join(", ", codecs.RateFeatures));

Delete Operations

DelRoomDayAsync

Deletes availability for a specific room on a specific date.

await client.DelRoomDayAsync("downtown", new DelRoomDayRequest
{
    PropertyId = "hotel_123",
    RoomType = "suite",
    Date = "2026-07-20"
});

DelPropDayAsync

Deletes all data for a property on a specific date.

await client.DelPropDayAsync("downtown", new DelPropDayRequest
{
    PropertyId = "hotel_123",
    Date = "2026-07-20"
});

DelPropRoomAsync

Deletes a room type from a property.

await client.DelPropRoomAsync("downtown", new DelPropRoomPayload
{
    PropertyId = "hotel_123",
    RoomType = "suite"
});

DelPropAsync

Deletes an entire property.

await client.DelPropAsync("downtown", "hotel_123");

DelSegmentAsync

Deletes a segment and all properties within it.

await client.DelSegmentAsync("downtown");

Error Handling

All async methods throw RoomzinException. Use the static helper methods to classify errors:

try
{
    await client.SetRoomPkgAsync("downtown", payload);
}
catch (RoomzinException ex) when (RoomzinException.IsRequest(ex))
{
    // Business rule violation - fix the request
    Console.WriteLine($"Request error: {ex.Code}");
}
catch (RoomzinException ex) when (RoomzinException.IsRetry(ex))
{
    // Temporary condition - retry with backoff
    await Task.Delay(100);
    await client.SetRoomPkgAsync("downtown", payload);
}
catch (RoomzinException ex) when (RoomzinException.IsClient(ex))
{
    // Authentication or protocol errors
    Console.WriteLine($"Client error: {ex.Message}");
}
catch (RoomzinException ex) when (RoomzinException.IsInternal(ex))
{
    // Unexpected server response
    throw new InvalidOperationException("Internal error", ex);
}

Error Categories

Category Description Action
Client Authentication or protocol errors Check credentials and configuration
Request Invalid input or business rule violation Fix request, don't retry
Retry Temporary server condition (429, 503) Retry with backoff
Internal Unexpected server response Log and investigate

Client Lifecycle

Create a single client during application startup and reuse it throughout your application.

// ✅ Good - create once, reuse
var client = new Client(config);
await client.ConnectAsync();
// Use client everywhere...
await client.CloseAsync();

// ❌ Bad - creating per request
foreach (var req in requests)
{
    var client = new Client(config); // Don't do this
    await client.SetRoomPkgAsync("downtown", req);
    await client.CloseAsync();
}

The client is safe for concurrent use and manages TCP connections internally.


Architecture

Standalone Mode

[SDK] → [Standalone Server]
  • Single TCP connection
  • Direct communication
  • Self-healing on disconnection

Cluster Mode

[SDK] → [Router] → [Shard Leader/Followers]
  • SDK sends segment and isWrite flag in header
  • Router routes writes to leader, reads to followers
  • Router handles cluster topology
  • SDK maintains single connection to router

Protocol

The SDK uses a framed binary protocol:

Standalone Frame:

[0xFF][ClrID(4)][TotalLen(4)][Payload]

Router Frame:

[0xFE][TotalLen(4)][SegmentLen(1)][Segment(n)][IsWrite(1)][ShardFrame]

Where ShardFrame is the standalone frame format.


Examples

A complete smoke example is available in the examples/csharp/ directory. It demonstrates the SDK's core features and can be run as a reference implementation or to verify your Roomzin setup.

cd examples/csharp
dotnet run

Documentation

For Roomzin concepts, deployment, and administration:

https://m-javani.github.io/roomzin-doc/docs.html


Contributing

Contributions are welcome! Please open an issue before proposing large changes.

All contributions are subject to the BUSL-1.1 License terms.


License

This SDK is licensed under the BUSL-1.1 License.

Note: This SDK communicates with Roomzin Server, which requires a valid Roomzin license.


Support


Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 104 8/19/2026
1.0.1 108 7/18/2026
1.0.0 101 7/18/2026