From defd8eab071ec2a97c5ffc5dc1d7e5c022196dfd Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Tue, 14 Apr 2026 18:20:37 +0400 Subject: [PATCH] fix(signal): send PresenceList directly to new client after ack The broadcast alone wasn't reaching the first client because its recv loop hadn't started yet when the second client registered. Now the relay sends PresenceList directly to the new client (right after RegisterPresenceAck) AND broadcasts to all others. This guarantees every client gets the full user list: - New client: via direct send (queued before recv loop starts) - Existing clients: via broadcast Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/wzp-relay/src/main.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/wzp-relay/src/main.rs b/crates/wzp-relay/src/main.rs index 11a41d3..22c885d 100644 --- a/crates/wzp-relay/src/main.rs +++ b/crates/wzp-relay/src/main.rs @@ -1016,10 +1016,16 @@ async fn main() -> anyhow::Result<()> { info!(%addr, fingerprint = %client_fp, alias = ?client_alias, "signal client registered"); - // Broadcast updated presence to all signal clients + // Send the full presence list directly to the new + // client (guaranteed delivery — their recv loop is + // about to start). Then broadcast to all OTHER + // clients so they learn about the new user. { let hub = signal_hub.lock().await; let presence = hub.presence_list(); + // Direct send to new client (arrives right after ack) + let _ = transport.send_signal(&presence).await; + // Broadcast to everyone else hub.broadcast(&presence).await; }