Realtime data streaming

You can use the SurrealDB SDK to create live queries that listen for changes in the database and automatically update your application when changes occur. This feature is useful for building real-time applications that need to respond to changes in the database.

MethodDescription
db.ListenLive(queryUuid) Listen responses from an existing live query
db.LiveQuery(sql) Initiate a live query from a SurrealQL statement
db.LiveRawQuery(sql, params) Initiate a live query from a SurrealQL statement, based on a raw SurrealQL query
db.LiveTable(table, diff) Initiate a live query from a table
db.Kill(queryUuid) Kills a running live query by it's UUID

.ListenLive<T>()

Listen responses from an existing live query.

Method Syntax

db.ListenLive<T>(queryUuid)

Arguments

ArgumentsDescription
queryUuid The UUID of the live query to consume.

Example usage

await using var liveQuery = db.ListenLive<Person>(queryUuid);

// Consume the live query...

You can then consume the live query using either an IAsyncEnumerable or an Observable.

Using an IAsyncEnumerable

:::note NOTE: This will block the current thread until the query is killed. :::

Option 1: Consume the live query via an IAsyncEnumerable

await foreach (var response in liveQuery)
{
// Either an Open, Create, Update, Delete or Close notification...

if (response is SurrealDbLiveQueryOpenResponse)
{
// Do something...
}
if (response is SurrealDbLiveQueryCreateResponse<Person> create)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryUpdateResponse<Person> update)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryDeleteResponse<Person> delete)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryCloseResponse)
{
// Do something...
}
}

Using an Observable

Option 2: Consume the live query via an Observable

liveQuery
.ToObservable()
.Subscribe((response) =>
{
// Either an Open, Create, Update, Delete or Close notification...

if (response is SurrealDbLiveQueryOpenResponse)
{
// Do something...
}
if (response is SurrealDbLiveQueryCreateResponse<Person> create)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryUpdateResponse<Person> update)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryDeleteResponse<Person> delete)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryCloseResponse)
{
// Do something...
}
});

You can also use the OfType operator to filter the responses.

liveQuery
.ToObservable()
.OfType<SurrealDbLiveQueryCreateResponse<Person>>()
.Select(response => response.Result)
.Subscribe((record) =>
{
// Use the created record
});

Note that this pattern is already simplified via methods available on the SurrealDbLiveQuery object. You can learn more about these methods in the LiveQuery methods section.


.LiveQuery<T>()

Initiate a live query from a SurrealQL statement.

Method Syntax

await db.LiveQuery<T>(sql)

Arguments

ArgumentsDescription
sql Specifies the SurrealQL statements.
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

const string table = "person"; 
await using var liveQuery = await db.LiveQuery<Person>($"LIVE SELECT * FROM type::table({table});");

// Consume the live query...

SurrealDbLiveQuery methods

The SurrealDbLiveQuery object provides the following methods:

GetResults()

Returns an enumerator that iterates asynchronously through the collection of results (all actions CREATE, UPDATE and DELETE, except OPEN and CLOSE).

Arguments

ArgumentsDescription
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

await foreach (var response in liveQuery.GetResults())
{
// Either a Create, Update or Delete notification...

if (response is SurrealDbLiveQueryCreateResponse<Person> create)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryUpdateResponse<Person> update)
{
// Use the `Result` record
}
if (response is SurrealDbLiveQueryDeleteResponse<Person> delete)
{
// Use the `Result` record
}
}

GetCreatedRecords()

Returns an enumerator that iterates asynchronously through the collection of created records.

Arguments

ArgumentsDescription
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

await foreach (var record in liveQuery.GetCreatedRecords())
{
// Use the created record
}

GetUpdatedRecords()

Returns an enumerator that iterates asynchronously through the collection of updated records.

Arguments

ArgumentsDescription
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

await foreach (var record in liveQuery.GetUpdatedRecords())
{
// Use the updated record
}

GetDeletedRecords()

Returns an enumerator that iterates asynchronously through the collection of deleted records.

Arguments

ArgumentsDescription
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

await foreach (var record in liveQuery.GetDeletedRecords())
{
// Use the deleted record
}

KillAsync()

Kills the underlying live query.

Method Syntax

await liveQuery.KillAsync(cancellationToken)

Arguments

ArgumentsDescription
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

// Consume the live query...

// Manually kill the live query
await liveQuery.KillAsync();


.LiveRawQuery<T>()

Initiate a live query from a SurrealQL statement, based on a raw SurrealQL query.

Method Syntax

await db.LiveRawQuery<T>(sql, params)

Arguments

ArgumentsDescription
sql Specifies the SurrealQL statements.
params Assigns variables which can be used in the query.
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveRawQuery<Person>("LIVE SELECT * FROM person;");

// Consume the live query...


.LiveTable<T>()

Initiate a live query from a table.

Method Syntax

await db.LiveTable<T>(table, diff)

Arguments

ArgumentsDescription
table The table name to listen for changes for.
diff If set to true, live notifications will include an array of JSON Patch objects, rather than the entire record for each notification.
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await using var liveQuery = await db.LiveTable<Person>("person");

// Consume the live query...


.Kill()

Kills a running live query by it's UUID.

Method Syntax

await db.Kill(queryUuid)

Arguments

ArgumentsDescription
queryUuid The UUID of the live query you wish to kill.
cancellationToken The cancellationToken enables graceful cancellation of asynchronous operations.

Example usage

await db.Kill(queryUuid);


Live Actions

A live query event can be one of the following:

ActionResultDescription
OPEN N/A Emitted when the live query is opened in the server.
CLOSE SocketClosed or QueryKilled Emitted when the live query is closed due to it either being killed or the connection being disconnected.
CREATE Result Emitted when a record within your subscription gets created
UPDATE Result Emitted when a record within your subscription gets updated
CREATE Result Emitted when a record within your subscription gets deleted