Module dittolive_ditto::presence

source ·
Expand description

Use ditto.presence() to gain insight to connected Peers in the Ditto mesh via the Presence API.

The Presence API can be used to inspect the ways in which peers are connected to one another in the Ditto mesh. Using .graph() or .observe(), you can see an immediate view of peer connections or receive callbacks with peer connection updates, respectively.

The key piece of data in the presence API is the PresenceGraph, which contains a description of the “local peer” as well as a list of “remote peers”. Remote peers are any peers which can be reached by this local peer in the Ditto mesh, either directly via a transport on this device, or indirectly via multiple hops through other peers.

§Example

Let’s take a look at how to request a PresenceGraph and how to read through it:

use dittolive_ditto::prelude::*;

// Get an immediate `PresenceGraph` showing current connections
let graph = ditto.presence().graph();
let my_key = &graph.local_peer.peer_key_string;
let my_connections = &graph.local_peer.connections;

// Let's find all peers that are directly connected to me, the local peer
let direct_peers = my_connections
    .iter()
    .map(|connection| {
        // Choose the peer in this connection that is not me
        if connection.peer_key_string1 == *my_key {
            &connection.peer_key_string2
        } else {
            &connection.peer_key_string1
        }
    })
    .collect::<Vec<_>>();
println!("My direct peers are {direct_peers:?}");

// Let's look up some details about _all_ the remote peers we can see
let remote_peers_summary = graph
    .remote_peers
    .iter()
    .map(|peer| {
        // Peer Key => (Name, OS, Connection Count)
        (
            &peer.peer_key_string,
            (&peer.device_name, &peer.os, peer.connections.len()),
        )
    })
    .collect::<std::collections::BTreeMap<_, _>>();
println!("A summary of my remote peers looks like this: {remote_peers_summary:#?}");

Please note that obtaining a PresenceGraph via .graph() only shows a snapshot of what devices were present when the call was made. In order to watch changes to device presence, we’ll need to use .observe() to register a callback and receive updates.

§Example

Let’s look at how we can use the .observe() API to register a callback and receive updates whenever the presence of our Ditto mesh changes. We could say the presence has changed if any peers have added or removed connections in the mesh.

use dittolive_ditto::prelude::*;

let mut maybe_prev_graph = Arc::new(Mutex::new(None));
let _presence_observer = ditto.presence().observe(move |graph| {
    let mut maybe_prev_graph = maybe_prev_graph.lock().unwrap();

    let Some(prev_graph) = &*maybe_prev_graph else {
        // First presence update! Print what remote peers we see by their keys
        let remote_peers = graph
            .remote_peers
            .iter()
            .map(|peer| &peer.peer_key_string)
            .collect::<Vec<_>>();
        println!("Received first presence update! Remote peers: {remote_peers:?}");
        *maybe_prev_graph = Some(graph.clone());
        return;
    };

    // Subsequent presence updates can compare the new graph against the old
    let prev_remote_peers = prev_graph
        .remote_peers
        .iter()
        .map(|peer| &peer.peer_key_string)
        .collect::<std::collections::HashSet<_>>();
    let latest_remote_peers = graph
        .remote_peers
        .iter()
        .map(|peer| &peer.peer_key_string)
        .collect::<std::collections::HashSet<_>>();

    // Detect if new peers have joined the mesh
    let new_peers = latest_remote_peers
        .difference(&prev_remote_peers)
        .collect::<Vec<_>>();
    if !new_peers.is_empty() {
        println!("New peers joined the mesh! {new_peers:?}");
    }

    // Detect if any peers left the mesh
    let lost_peers = prev_remote_peers
        .difference(&latest_remote_peers)
        .collect::<Vec<_>>();
    if !lost_peers.is_empty() {
        println!("Peers have left the mesh! {lost_peers:?}");
    }

    *maybe_prev_graph = Some(graph.clone());
});

Structs§

Enums§

  • Defines a simplified connection type between peers for reporting presence info.
  • Operating system used by a given peer.

Type Aliases§