ThingsDB.Connector 1.0.2

dotnet add package ThingsDB.Connector --version 1.0.2
NuGet\Install-Package ThingsDB.Connector -Version 1.0.2
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="ThingsDB.Connector" Version="1.0.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ThingsDB.Connector --version 1.0.2
#r "nuget: ThingsDB.Connector, 1.0.2"
#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.
// Install ThingsDB.Connector as a Cake Addin
#addin nuget:?package=ThingsDB.Connector&version=1.0.2

// Install ThingsDB.Connector as a Cake Tool
#tool nuget:?package=ThingsDB.Connector&version=1.0.2

CI Release Version

C# connector for ThingsDB



Installation

This library is distributed via NuGet.

Using a package manager:

Install-Package ThingsDB.Connector

Or, by using NET CLI:

dotnet add package ThingsDB.Connector

Quick usage

// Create a new connector instance and configure a default scope
Connector conn = new("playground.thingsdb.net", 9400, true)
{
  DefaultScope = "//Doc";
};
// Optionally, configure a stream for logging
conn.SetLogStream(Console.Out);

// Make the connection
await conn.Connect(token);  // You need either a token or a username + password

// Perform a query
var response = await conn.Query(@"
    'Hello world!';
");
// The response is in bytes and can be deserialized using MessagePack.
var msg = MessagePackSerializer.Deserialize<string>(response);

Console.WriteLine(msg);  // Hello world!

Connector

To interact with ThingsDB using this library, you'll always require a Connector instance. Even when employing a Room to monitor events, you must first attach the Room to a Connector before it can function.

The Connector is designed to handle asynchronous operations and is not thread-safe. While we anticipate providing a thread-safe Connector in the future, for the time being, each thread must be furnished with its own Connector instance.

Constructor

Connector(string host);
Connector(string host, int port);
Connector(string host, int port, bool useSsl);
  • host (string, required): A hostname, IP address, FQDN to connect to.
  • useSsl (bool): Enable for creating a secure connection using SSL/TLS.
  • port (int): TCP port to connect to. The default port is 9200.

Close

void Close();

Closed an open connection. Usually called once when the application is closed.

Connect

async Task Connect(string token);
async Task Connect(string username, string password);

Connect using either a token or by username and password.

DefaultScope

string DefaultScope = "/thingsdb";

If not set, the scope /thingsdb is used as default scope.

DefaultTimeout

TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30.0);

If not set, a default timeout of 30 seconds is used.

OnNodeStatus

delegate void OnNodeStatus(NodeStatus nodeStatus) = null;

You may configure a callback function to handle NodeStatus changes.

SetAutoReconnect

void SetAutoReconnect(bool autoReconnect);

By default, auto reconnect is true.

IsAutoReconnect

void IsAutoReconnect();

Returns true if auto reconnect is enabled.

SetLogStream

void SetLogStream(TextWriter? logStream);

Configure a log stream. For example:

conn.SetLogStream(Console.Out);

Query

async Task<byte[]> Query(string code);
async Task<byte[]> Query(string scope, string code);
async Task<byte[]> Query<T>(string code, T? kwargs);
async Task<byte[]> Query<T>(string scope, string code, T? kwargs);
async Task<byte[]> Query<T>(string scope, string code, T? kwargs, TimeSpan timeout);
  • scope (string): If not given, the default scope is used.
  • code (string, required): The code to query.
  • kwargs (Dictionary<string, T>): Variable which are used in the code.
  • timeout (int): If not given, the default timeout is used.
Example
var kwargs = new Dictionary<string, int> {
  { "a", 6 },
  { "b", 7 }
};
var response = await conn.Query("a * b;", kwargs);
var result = Unpack.Deserialize<int>(response);
// result = 42;

Run

async Task<byte[]> Run(string procedure);
async Task<byte[]> Run(string scope, string procedure);
async Task<byte[]> Run<T>(string procedure, T? argsOrKwargs);
async Task<byte[]> Run<T>(string scope, string procedure, T? argsOrKwargs);
async Task<byte[]> Run<T>(string scope, string procedure, T? argsOrKwargs, TimeSpan timeout);
  • scope (string): If not given, the default scope is used.
  • procedure (string, required): The procedure to execute.
  • argsOrKwargs (Dictionary<string, T> or T[]): Arguments for the procedure may be given either using a dictionary with string keys, or positional by supplying the arguments in an array.
  • timeout (int): If not given, the default timeout is used.
Example
// This example assumes a procedure "multiply" exists. The procedure can be
// created using the following code:
//
//     new_procedure('multiply', |a, b| a * b);
//
int[] args = [6, 7];
var response = await conn.Run("multiply", args);
var result = Unpack.Deserialize<int>(response);
// result = 42;

Room

The Room class is supposed be subclassed and can be initiated using code to bind the instance to a room in ThingsDB.

using ThingsDB;

// The Room constructor needs two arguments:
//   * Connector conn
//       This a ThingsDB Connector instance
//   * string code
//       This is ThingsDB code which will be executed on join and must return
//       the Id for the room to join. For example ".my_room.id();"
//       If you beforehand know the Id, you can simple create a string with the
//       room Id in it. For example: "123".
//  Optionally, you may provide a scope for the room. If not given, the default
//  scope of the connector will be used. For example:
//    Room(conn, "//my_scope", ".my_room.id()")
public class MyRoom(Connector conn) : Room(conn, ".roomd();")
{
    [Event("new-message")]
    public void OnNewMessage(byte[][] args)
    {
        var msg = Unpack.Deserialize<string>(args[0]);
        Console.WriteLine(msg);
    }
}

With the Event argument you can create event handlers for specific events. The example above shows how the Event argument must be used.

Overrides

When creating a Room class, some methods exist which may be overwritten. Each of the methods have their own purpose which will be explained here.

Note: It is not required to call the base class method for these overrides.

OnInit
public override void OnInit()
{
    // This method will only be called only once when the Join() function is
    // called. When the connection is lost and the room is re-joined, the method
    // will *not* be called again. Use the OnJoin override if you require this.
}
OnJoin
public override Task OnJoin()
{
    // This is an async method and is the best function to be used if the room
    // requires information from ThingsDB to function. This method will be
    // called on each join. A room may join again after a connection was lost.
    // If this happens, we usually want to make sure our room is synchronized
    // with the latest state of ThingsDB.
}
OnEmit
public override void OnEmit(string eventName, byte[][] args)
{
    // Called when no event handler is configured for the event and must accept
    // the following two arguments:
    //  * string eventName
    //      Contains the name for the event.
    //  * byte[][] args
    //      Array with arguments. The array may be empty and each argument in
    //      the array is of type bytes and can be deserialized using
    //      MessagePack (or the Unpack.Deserialize method which is exactly the
    //      same).
}
OnLeave
public override void OnLeave()
{
    // This method is called the Leave() method is called. It will *not* be
    // triggered when for example the connection is lost.
}
OnDelete
public override void OnDelete()
{
    // This method will be called when the room is removed. Be aware that it may
    // take an iteration of the garbage collector in ThingsDB before a room is
    // truly deleted.
}

Conn

Connector Conn;

Exposes the ThingsDB Connector which is bound to the room.

Id

ulong Id();

Return the Id of the room.

Scope

string Scope();

Return the scope of the room.

Join

public async Task Join();
public async Task Join(TimeSpan wait);

The Join method must be called to actually join the room. The Join method by default waits before the first call to the OnJoin() method has finished. Thus, you know that all the initializers in the OnJoin override have finished once the Join method has finished. If it takes longer than wait, a TimeoutException is raised. The wait argument may also be set to 0 in which case we disable this behavior and do not wait for the OnJoin method to finish.

NoJoin

public async Task NoJoin();

If you do not want to Join the Room, but only use the room to emit events, you can use the NoJoin method. This room will not listen for events and can only be used for the Emit(..) method.

Emit

public async Task Emit(string eventName);
public async Task Emit<T>(string eventName, params T[]? args)

Emit an event to the room.

  • eventName (string, required): The name for the event to emit.
  • args (...T): Arguments for the event. Multiple argument are allowed.
Example
await myRoom.Emit("new-message", "This is a test message!");

Leave

public async Task Leave();

No longer listen to events for this room.

Unpack

Unpack utilities for deserializing data.

Deserialize

Unpack.Deserialize<T>(response) -> T

This is like an alias for the MessagePack.Deserialize method.

IsNil

Unpack.IsNil(response) -> bool

Easy way to check if a response is equal to nil.

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. 
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
1.0.2 148 12/14/2023
1.0.1 161 12/13/2023
1.0.0 156 12/13/2023

Fixed NuGet Package.