feat: RoomUpdate protocol — broadcast participant list on join/leave

- Add RoomUpdate signal message to wzp-proto with participant count + list
- Add RoomParticipant struct (fingerprint + optional alias)
- Store fingerprint/alias in relay Participant struct
- Broadcast RoomUpdate to all room members on join and leave
- Add signal recv task in Android engine to handle RoomUpdate
- Surface room_participant_count + room_participants in CallStats JSON
- Show "X in room" with participant names in Android in-call UI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude
2026-04-05 18:12:24 +00:00
parent a23d9f5e41
commit 2d4b8eebd5
9 changed files with 187 additions and 16 deletions

View File

@@ -502,14 +502,21 @@ async fn main() -> anyhow::Result<()> {
let participant_id = {
let mut mgr = room_mgr.lock().await;
match mgr.join(&room_name, addr, room::ParticipantSender::Quic(transport.clone()), authenticated_fp.as_deref()) {
Ok(id) => {
match mgr.join(
&room_name,
addr,
room::ParticipantSender::Quic(transport.clone()),
authenticated_fp.as_deref(),
None, // alias — TODO: accept from client
) {
Ok((id, update, senders)) => {
metrics.active_rooms.set(mgr.list().len() as i64);
drop(mgr); // release lock before async broadcast
room::broadcast_signal(&senders, &update).await;
id
}
Err(e) => {
error!(%addr, room = %room_name, "room join denied: {e}");
// Clean up the session we just created
metrics.active_sessions.dec();
let mut smgr = session_mgr.lock().await;
smgr.remove_session(session_id);