Changes:
- Update App.jsx to use Rondevu.connect() instead of new + initialize()
- Update publishService to use 'service' parameter instead of 'serviceFqn'
- Remove explicit claimUsername() calls (now implicit)
- Add comprehensive NODE_HOST_GUIDE.md for hosting WebRTC services in Node.js
- Update README with Node.js hosting section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
CRITICAL BUG FIX: As the answerer, we should NOT create our own data channel.
The host (offerer) creates the channel, and we receive it via ondatachannel event.
This was causing messages to be sent on a different channel than the one
the host was listening to, so no messages were being received.
Changes:
- Remove pc.createDataChannel() call
- Add pc.ondatachannel event handler
- Wrap data channel setup in setupDataChannel() function
- Called when channel is received from host
- Increase delay to 500ms before sending identify
- Monitor channel state before sending
- Log bufferedAmount after send
- Add onclose handler for debugging
- Send 'identify' message on connection
- Wait for 'identify_ack' acknowledgment
- Send 'message' type with text for chat
- Keep connection open 5s to receive responses
- Move onicecandidate handler setup before setLocalDescription
- Directly use API for sending candidates instead of signaler
- Use signaler only for receiving remote candidates
Better error message when wrtc is not installed, with clear
instructions on how to install it.
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
wrtc requires native compilation and may fail on some systems.
Make it optional so the demo can build without it. Users who want
to run the Node.js test script can install it separately.
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Adds test-connect.js script that:
- Connects to production Rondevu API
- Discovers chat service from @bas
- Establishes WebRTC connection using wrtc
- Sends 'hello' message via data channel
Usage: npm test
Requires:
- Node.js 19+ (or 18 with --experimental-global-webcrypto)
- wrtc package for WebRTC in Node.js
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed loading condition from checking rondevu existence to checking setupStep.
New users now see the claim UI immediately instead of being stuck on Loading.
The previous change broke the claim flow for new users because handleClaimUsername
expected rondevu to exist, but we stopped creating it during initialization for
new users. Now handleClaimUsername creates the Rondevu instance itself.
- Added generateRandomUsername() function
- Prefill username input with random suggestion
- Only create Rondevu instance for returning users with saved credentials
- Changed placeholder to "Choose a username"
- Users must explicitly click "Claim Username" button
This prevents automatic username claiming that was polluting the database
with anonymous users on every page load.
- Show real-time status of each host connection in the pool
- Status indicators: Waiting (gray), Answer received (orange), Connecting (blue), Connected (green)
- Visual feedback shows when offerer is waiting for answerer acceptance
- Connection pool counter shows active/total connections
- Helps users understand the connection lifecycle
- Remove pending requests approval flow
- Auto-accept and open chat immediately when someone connects (same UX as initiating)
- Remove accept/decline buttons and pending requests UI
- Simplified flow: connection -> chat opens automatically
- Both offerer and answerer now have consistent UX
Close Button Improvements:
- Change pause icon (⏸) to close icon (✕) for clarity
- Change orange background to red (#dc3545) to indicate destructive action
- Update tooltip from 'Close chat' to 'End chat'
- Now visually distinct from the trash icon for removing friends
Add Disconnect for Incoming Chats:
- Add ✕ disconnect button to 'Active Chats' section (non-friends)
- Allows host to disconnect from incoming connections
- Same red styling as friend chat close button
- Shows 'Disconnected from {username}' toast
Both buttons now clearly indicate their purpose and work consistently
across friends and incoming chats.
Connection Request Approval:
- Add 'Connection Requests' section showing pending incoming connections
- Host must explicitly accept or deny incoming connection requests
- Shows username before accepting (no auto-accept)
- Accept: moves to active chats and sends acknowledgment
- Decline: closes connection and removes from pending
- Toast notification when someone wants to chat
Friends List UX Improvements:
- Add ⏸ (pause) button to close active chat without removing friend
- Change ✕ to 🗑 (trash) icon for removing friends
- Add confirmation dialog before removing a friend
- Separate 'close chat' from 'remove friend' actions
- Clearer visual distinction between actions
This prevents accidental friend removal and gives hosts control over
who they connect with before establishing the chat.
UI improvements:
- Add 'Incoming Chats' section showing connections from non-friends
- Auto-select and show incoming chat when someone connects
- Toast notification when someone connects to you as host
ICE polling fix:
- Stop ICE candidate polling once connection is established
- Prevents unnecessary network requests after connection succeeds
- Only poll while in 'connecting' state
This fixes:
1. Host couldn't see incoming chats (they weren't in UI)
2. Answerer kept polling ICE candidates even after connected
CRITICAL FIX: ICE gathering starts immediately when setLocalDescription() is
called, but we didn't have offerIds yet to send them to the server. This meant
all ICE candidates were lost before we could send them.
Solution:
- Attach temporary ICE handler BEFORE setLocalDescription()
- Buffer all ICE candidates in array until we have offerId
- After publishing and receiving offerIds, send all buffered candidates
- Replace handler with permanent one for any future candidates
This fixes the root cause of answerers not receiving any offerer candidates.
- Log when answerer starts polling for offerer ICE candidates
- Log count of candidates received from offerer
- Log each candidate being added with details
- Log success/failure of adding each candidate
- Log when answerer sends their own ICE candidates to server
- Helps debug ICE candidate exchange on answerer side
- Offerer now filters for answerer ICE candidates only
- Ignores own candidates returned from server
- Uses role field to distinguish between offerer and answerer candidates
- Improves logging to show answerer candidate count
- Add offerId to RTCPeerConnection mapping for answer processing
- Setup ICE candidate handlers on offerer peer connections
- Replace answer-only polling with combined pollOffers() endpoint
- Process both answers and ICE candidates in single poll operation
- Track last poll timestamp to avoid reprocessing old data
- Send offerer ICE candidates to server via addOfferIceCandidates()
- Reduces HTTP requests and completes bidirectional ICE exchange
Host now polls for answered offers every 2 seconds using the new
efficient batch endpoint. When an answer is received, the host
automatically sets the remote description to complete the WebRTC
connection.
Changes:
- Store offerId to RTCPeerConnection mapping when publishing
- Poll for answered offers with timestamp filtering
- Automatically handle incoming answers
- Track last answer timestamp to avoid reprocessing
This completes the bidirectional WebRTC signaling flow.
- Add comprehensive logging for init and publish flows
- Verify username is claimed before publishing service
- Detect keypair mismatches and provide clear error messages
- Handle authentication errors more gracefully
- Auto-claim username if not claimed during publish
- Improved user guidance for common errors
- Install client from local path instead of npm registry
- Workaround for npm registry propagation delay
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Complete rewrite to use low-level Rondevu API directly
- Removed ServiceHost/ServiceClient abstractions
- Manual RTCPeerConnection and data channel setup
- Custom polling for answers and ICE candidates
- Updated to use new Rondevu class instead of RondevuService
- Direct signaling method calls instead of getAPI()
- Reduced from 926 lines to 542 lines (42% reduction)
- Demonstrates complete WebRTC flow with clear offerer/answerer roles
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Properly await isUsernameClaimed() check during initialization
- Verify saved username is still valid on the server
- Show 'Welcome back' toast when restoring session
- Handle expired usernames gracefully
- Update to @xtr-dev/rondevu-client v0.10.1
- Replace Rondevu class with RondevuService, ServiceHost, ServiceClient
- Simplify demo implementation (removed complex features)
- Use new event-driven API for connections
- Support custom RTC configuration
- Backup old implementation as App-old.jsx
Breaking changes from v1 API:
- RondevuService for username claiming
- ServiceHost for hosting services with offer pool
- ServiceClient for connecting with auto-reconnection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- ServiceHost: Manages offer pool for hosting services
- ServiceClient: Connects to hosted services with auto-reconnection
- RondevuService: High-level API for username claiming and service publishing
Note: Demo code still uses old Rondevu API and needs refactoring
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated to @xtr-dev/rondevu-client@0.9.2 which fixes critical timing
issue where ICE candidates were generated before handlers were attached.
Now includes detailed logging for service pool ICE candidate generation
with candidate types (host/srflx/relay) for debugging TURN issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added a settings modal with dropdown to select from preset RTC
configurations or provide custom JSON config:
- IPv4 TURN (Recommended): Uses explicit IPv4 addresses to avoid
DNS resolution issues and address type mismatches
- Hostname TURNS (TLS): Uses secure TURNS on port 5349 with hostname
- Google STUN Only: Minimal config for testing direct connections
- Force TURN Relay: Testing mode that forces relay usage
- Custom Configuration: Users can paste their own RTCConfiguration JSON
Settings are persisted in localStorage and applied to all new
connections and service exposures.
This allows users to test different configurations without rebuilding
and helps diagnose connection issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated to @xtr-dev/rondevu-client@0.9.1 which includes detailed
ICE candidate exchange logging for debugging connection issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated ICE configuration to use TURNS (TLS/DTLS) on port 5349
as the preferred relay method, with plain TURN on port 3478 as
fallback. WebRTC will try secure endpoints first for better
security and reliability.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed channel name from 'chat' to 'rondevu-service' to match the
channel name created by the service pool. This fixes the connection
failure where the offerer's channel and answerer's channel had
different names and couldn't connect.
The service pool creates a channel named 'rondevu-service', so clients
must use the same name to receive that channel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added iceTransportPolicy: 'relay' to RTC_CONFIG to force TURN relay usage.
This bypasses NAT hairpinning issues when testing on the same network
(e.g., two browser tabs on the same machine).
This setting ensures maximum compatibility and reliability for WebRTC
connections by always using the TURN relay instead of attempting direct
or STUN-based connections.
Note: Should be commented out in production to allow direct connections
when possible for better performance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The demo now uses npm link to use the local client development version
instead of the published package from npm registry.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Services were expiring after 60 seconds (default offer TTL).
Set TTL to 300000ms (5 minutes) so chat services stay discoverable
while users have the page open.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>