Developer SDK

Kotlin examples

Install the SDK · View source on GitHub ↗

Kotlin peer messages

Installation · Integration · Sockets · Messages

This local Device example discovers real-time peers and exchanges text over subprotocol 4096 using the shared URMS v1 TEXT/ACK format. Its files are Main.kt and build.gradle.kts; the Device bootstrap is described in Integration.

Build and check

Use Gradle and JDK 21; the build selects Kotlin 2.2.20. It compiles client/UrSession.java, UrMessages.java and MessageCodec.java, so keep the adjacent Java directory. Install the matching SDK in Maven Local or add -PsdkVersion=VERSION to each Gradle command; the default is 0.0.1-dev.0. Run from kotlin/messages:

gradle --console=plain build
gradle --console=plain run --args=--self-test
gradle --console=plain run --args=--version

--self-test checks the golden vectors and malformed-frame rejection without client credentials or live networking. --version reports the SDK version; bindings with native runtime assets also check that they load. Dependency/build steps may download packages.

Live two-terminal demo

Provision two distinct top-level clients in the same network through your authenticated backend. Terminal A and terminal B need different scoped JWTs with different client_id claims and different persisted instance UUIDs. Only the backend holds the root JWT; Integration includes the executable allocator.

In terminal A, from this directory, export client A's values and start the receiver:

export URNETWORK_CLIENT_JWT='scoped-client-jwt-from-your-service'
export URNETWORK_INSTANCE_ID='persisted-installation-uuid'
gradle --console=plain run --args=self
gradle --console=plain run --args=peers
gradle --console=plain run --args=watch

self prints this client's ID and exits. peers prints the current peer snapshot; watch remains running, refreshes on SDK peer notifications, and receives TEXT/returns ACK. Peer output includes SDK metadata, disconnected count and the SDK-derived client color. Start terminal B with its own URNETWORK_CLIENT_JWT and URNETWORK_INSTANCE_ID, then use A's discovered client ID:

export URNETWORK_PEER_CLIENT_ID='client-id-discovered-in-terminal-a'
gradle --console=plain run --args="send $URNETWORK_PEER_CLIENT_ID hi"

The sender queries the selected peer's supported subprotocols before sending and requires 4096. A failed query, enqueue failure or ACK timeout is reported as a failure. A matching application ACK means the receiver parsed and accepted the TEXT; correlation uses (source client ID, message ID). Use the discovered client ID as the destination, not an instance UUID or display name. For text containing spaces, keep the message in one quoted argument (or inside the quoted Maven/Gradle argument string).

Incoming bytes and retained source identity are copied before the native callback returns; queued work parses frames and sends ACKs outside that callback. Keep subscriptions and Device owners alive through shutdown. Some FFI bridges keep a small callback root until process exit because native close can race a late callback. The protocol defines exact validation, UTF-8 limits, golden bytes and timeout semantics.