feat(messaging): subscribe to live ChatEvent SSE updates #204
No reviewers
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_archipelagos!204
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "development_messaging_sse_subscribe"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes the user-visible side of hero_archipelagos #182: the messaging archipelago no longer requires a page reload to see new messages. Recipients see incoming bubbles within ~1-2 seconds via Server-Sent Events.
This is the third and final PR in the multi-repo fix:
web_events.socklistener (merged).subscribe()(merged).Related Issue
Closes #182
Changes
archipelagos/messaging/src/archipelago.rsAfter the existing
fetch_chatsuse_effect, a newuse_effectspawns a long-lived task that:services::subscribe_chat_events(osis_url, context_name, public_key)(thin wrapper aroundCommunicationClient::subscribe).Ok(ChatEvent::ChatmessageNew { message, .. }):conversationswith truncatedlast_message,last_message_time, and (when not actively viewing the chat)unread_count += 1.services::chatmessage_to_messagedataand pushes toactive_messageswith the same dedupe rule as the optimistic-insert path (by message id).Ok(ChatEvent::ConversationUpdated(conv)):Err(SubscribeError::Resync(_)): re-fetchesconversationsand the active chat's messages without closing the stream.Err(SubscribeError::Disconnected): breaks the inner loop, sleeps with backoff, reconnects.Err(SubscribeError::SseError(msg)): logs viatracing::warn!, continues consuming.Sender race fix in
handle_sendWhen the SSE event echo of the user's own send arrived before the optimistic-insert in
handle_sendran, the existing dedupe (!already_present) skipped theis_own = trueoverride and the sender briefly saw a gray bubble for their own message. The fix:archipelagos/messaging/src/services/messaging_service.rsAdds
subscribe_chat_events(osis_url, context_name, public_key) -> Result<impl Stream<Item = Result<ChatEvent, SubscribeError>> + Unpin, String>— thin wrapper aroundCommunicationClient::subscribeso the archipelago doesn't have to construct the client directly.archipelagos/messaging/Cargo.tomlcfg(not(target_arch = "wasm32"))):tokio = { version = "1", features = ["time", "rt"] }fortokio::time::sleepin the backoff loop.cfg(target_arch = "wasm32")):gloo-timers = { version = "0.3", features = ["futures"] }forgloo_timers::future::TimeoutFuturein the backoff loop.Test plan
cargo check -p hero_archipelagos_messaging --target x86_64-unknown-linux-gnu— clean.cargo check -p hero_archipelagos_messaging --target wasm32-unknown-unknown— clean.is_own = true.Notes
Pre-auth carve-out on the server
The server-side filter (hero_osis PR #44) currently delivers all events to anonymous subscribers (no
X-Public-Keyheader) because the messaging archipelago still runs on theSYSTEM_KEY = "system"placeholder identity. This is documented as aTODOto flip back to fail-closed once real authentication lands. Post-auth, the participant filter on the server side becomes the only line of defence — that path is exercised by hero_osis's unit tests and remains correct for any caller that does supply a real public key.Issue #192 is NOT addressed here
The pre-existing bug where every message renders as
bubble-other(gray) after a page reload — including the user's own — is issue #192, a regression of #62. That's a separate root cause (server hardcodessender_public_key = "system", breaking theis_owncheck on fetched messages) and is essentially blocked on auth landing. The race fix in this PR'shandle_sendkeeps the just-sent bubble blue at send time, but reload-time rendering is unchanged from the existing behaviour.