Embedded Sync Server

How to set up an ObjectBox sync server that is embedded in your server application.

This page refers to the embedded sync server, not the standalone sync server. Usually, you want to use the standalone server.

Use Sync.server(boxStore, url, authenticatorCredentials) to start a sync server using a boxStore . The server binds to the address and port given in url.

When using wss as the protocol of the url a TLS encrypted connection is established. Use certificatePath(path) to supply a path to a certificate in PEM format. Use ws instead to turn off transport encryption.

authenticatorCredentials are used to authenticate clients. Use authenticatorCredentials(credentials) to add more than one set of allowed credentials.

SyncServer syncServer = Sync.server(
boxStore,
"wss://0.0.0.0:9999" /* Use ws for unencrypted traffic. */,
SyncCredentials.apiKey("api-key")
)
.certificatePath(certPath) // Server PEM certificate.
.build(); // Configures and starts the server.

During build() the server will start and become ready to accept connections from clients.

Client authentication

These are the currently supported options to authenticate clients:

API Key

SyncCredentials credentials = SyncCredentials.apiKey("api-key");

This can be any pre-shared secret string or byte sequence.

Google Sign-In

Not available, yet.

No authentication (insecure)

Never use this option to serve an app shipped to customers. It is inherently insecure and allows anyone to access the sync server.

SyncCredentials credentials = SyncCredentials.none();

For development and testing it is often easier to just have no authentication at all to quickly get things up and running.

Manually start

By default the server automatically binds to the given address and port and starts listening for clients. To turn this off use manualStart() when building the server. Then when ready use SyncServer.start() to start the server.

SyncServer syncServer =
syncBuilder.manualStart() // Do not auto-start after build().
.build();
// Start now.
syncServer.start();

Advanced

Listening to sync updates

For advanced use cases a server application might want to know which entities exactly have changed during a sync update.

Use changesListener(listener) to pass a SyncChangesListener when building the server. Or at any later point use SyncServer.setSyncChangesListener(listener) to set or update the listener. To remove the current listener use SyncServer.removeSyncChangesListener().

On each sync update the listener is called with an array of SyncChange objects. SyncChange.getEntityTypeId() returns the EntityInfo<T>.__ENTITY_ID of the affected entity type. Use getChangedIds() to get an array of IDs identifying which entities have changed, respectively getRemovedIds() for those that were removed.

SyncChangesListener changesListener = syncChanges -> {
for (SyncChange syncChange : syncChanges) {
// This is equal to Example_.__ENTITY_ID.
long entityId = syncChange.getEntityTypeId();
// The @Id values of changed and removed entities.
long[] changed = syncChange.getChangedIds();
long[] removed = syncChange.getRemovedIds();
}
};
// Set the listener when building the server.
syncBuilder.changesListener(changesListener);
// Or set the listener later.
syncServer.setSyncChangesListener(changesListener);
// Calling again replaces an existing listener.
syncServer.setSyncChangesListener(changesListener);
// Remove an existing listener.
syncServer.removeSyncChangesListener();

Adding peer servers

It is possible to have multiple sync servers for redundancy and load balancing where one or more secondary servers connect as special clients to a primary server. Use peer(url, credentials) to add the primary server when building a secondary server.

syncBuilder.peer(primaryServerUrl, SyncCredentials.apiKey("primary-api-key"));