Appearance
Peers (Rust)
When someone running the same protocol comes online, you get a peer. Send them data and pin connections you care about. Reach the peer API through app.peer(); peers themselves arrive as Events on app.events().
Peers vs. connections
These are two different layers, and the distinction matters when you build UI around presence:
- A connection is a transport-level encrypted link between two hosts (devices). There is one connection per
(luid, ruid, rhid), shared by every app talking to that host. Connections are wish-core's concern — your app never opens or sees them directly. - A peer is an app-level relationship: the tuple
(luid, ruid, rhid, rsid, protocol). A peer exists only when all three hold:- the two hosts have a connection,
- both sides run the same protocol, and
- the local app is permitted to use
luidon that connection.
So a host can be connected without any peer being online for your app — the device is reachable, but nothing is speaking your protocol there. Presence in an app should track peers, not connections: a peer going online is the signal that there is something at the other end you can actually talk to.
You learn about peers through Event::Online / Event::Offline on app.events() — Online when a peer appears, Offline when it goes away.
The Peer value:
rust
peer.luid // Vec<u8> — local identity UID
peer.ruid // Vec<u8> — remote identity UID
peer.rhid // Vec<u8> — remote host ID
peer.rsid // Vec<u8> — remote service/app ID
peer.protocol // String — protocol name
peer.online // boolSending data
peer().send(peer, frame) (peer: &Peer, frame: &[u8]) -> bool
Send a payload to a peer. No built-in retry — a full send buffer fails the call (507); resending is your app's decision (drop, queue, or back off).
rust
app.peer().send(&peer, b"hello")?;Frames are raw bytes — you choose the encoding. Most apps use CBOR (ciborium):
rust
let mut buf = Vec::new();
ciborium::into_writer(&msg, &mut buf)?;
app.peer().send(&peer, &buf)?;Inbound frames arrive as Event::Frame { peer, data }.
Peer pins
By default, connections are opportunistic — wish-core connects when it discovers a peer and disconnects when idle. Pins let you declare which connections matter.
peer().pin(...) (luid, ruid, rhid: &[u8], policy: PinPolicy, priority: u8) -> bool
Pin a peer — tell wish-core to maintain this connection.
rust
use wish_sdk::PinPolicy;
let any_host = [0u8; 32]; // all zeros = any host
app.peer().pin(&my_uid, &bob_uid, &any_host, PinPolicy::Eager, 0)?;Policies (PinPolicy):
Always— maintain connection persistently, reconnect on failureEager— connect when possible, allow disconnect when idle
Priority: 0 = highest, 255 = lowest. When resources are limited, higher priority pins are maintained first.
peer().unpin(luid, ruid, rhid) (luid, ruid, rhid: &[u8]) -> bool
Remove a peer pin.
peer().pins() () -> Vec<Pin>
List this app's peer pins.
rust
for pin in app.peer().pins()? {
println!("{:?} {}", pin.policy, pin.priority);
}