Skip to main content
Before you start: use Mesh SDK v0.33.0 on two reachable peers and approve their device addresses. The provider and requester snippets extend the quickstart. The sample operation is read-only and contains no sensitive data. A service is an application-defined capability offered by a peer. The SDK handles discovery and request/response; your application selects an authorized provider and implements the operation.
Service discovery is signed plaintext in v0.33.0. A request or response body is sealed in the MLS session with the other peer only once that peer runs 0.29.0 or later and the session is confirmed; the first request to a provider this device has never met, and requests to older peers, travel as signed plaintext that every device carrying them can read. Check event.encrypted on service_request_received and service_response_received, keep credentials and sensitive data out of metadata and first-contact bodies, and use encrypted messaging for confidential application data.

Start both peers

Complete the quickstart. Reuse its protocol instance. Register the requester handlers before calling startMesh(); register the provider after startup as described below.

Provider

This example returns a public capability status. Supply allowedRequester from your application’s enrollment policy.
Register the request listener before discovery begins. Call installStatusService after the protocol has started; the helper installs its listener before registering the service.

Requester

Create the client before startup. After startup, call discover(). The example filters results to one pre-approved provider. Inspect its service ID, version, capabilities and query ID, then call request(). Implement selection among several approved providers in your application. Discovery returns a query ID; results arrive as events. Requests return a request ID; correlate the response to the pending request and expected provider in your application.

Subscribe to a service

A request gets one answer. A subscription, from v0.32.0, gets every change as it happens: the consumer holds a lease on one topic of the provider’s service, and the provider sends it each update until the lease ends. Every subscription frame is sealed in the 1:1 MLS session between the two devices, with no plaintext fallback; a subscription made before a session exists starts one and waits for it. A topic has one of two modes, set by its first publish:

Provider

The provider decides who may subscribe. Under the default restricted policy each new subscriber raises service_subscribe_received, and the application calls acceptServiceSubscription or rejectServiceSubscription; a request left unanswered for 60 seconds is rejected. accept_all admits every peer with a session, and rules admits listed peers and members of listed groups and asks about or rejects everyone else.
publishServiceUpdate returns a report per call: sentLive subscribers were sent the update once over a live direct link, queued ones get it through the reliable path across hops, where a newer latest value replaces the one still queued for its key, and coalesced ones get the newest value after a short interval. serviceSubscribers lists who is subscribed, endServiceSubscription ends one subscription and clearServiceTopic starts a topic over.

Consumer

subscribeService returns the subscription ID that its events carry. The subscription is pending until the provider accepts it, then active; service_subscription_changed reports each change with a reason such as accepted, rejected or approval_timeout. Updates for a key never arrive older than one already delivered, and snapshot: true marks a catch-up value rather than a fresh publish.

Narrow a subscription

A topic pattern such as rooms/*, or * for every topic, follows each matching topic in its mode, up to 64, including topics first published after the subscription; every update names its topic. On a latest topic, the keys argument limits the subscription to the keys it lists, each exact or a prefix ending in *. The provider applies both, so an unmatched topic or a filtered key never leaves its device.

Get the state back

A consumer that missed updates gets the state back at its next lease renewal, after the provider restarts, or at once with resyncServiceSubscription. Nothing of a subscription survives a restart on either side: a consumer that restarts subscribes again, and a provider whose latest state matters republishes it at startup. A lease lasts 120 seconds by default and renews on its own while both devices run.

Handle failure

Give every operation an application deadline. A missing response does not prove that the provider did no work. Retry read-only operations under a bounded policy. For side effects, persist an operation ID and result at the provider before retrying or switching providers. A replacement provider must implement the same service contract and pass the same authorization checks. The SDK discovers providers; it does not decide your business policy or automatically transfer an unfinished job. See MeshServices methods, service events and the service discovery and subscriptions guide in the SDK repository.

Completion check

Done when: an approved provider returns a response correlated to the request, an unapproved requester receives no result, and a missing provider produces a visible timeout in your application. Continue with production qualification.