mirror of
https://github.com/xtr-dev/rondevu-client.git
synced 2025-12-13 20:33:25 +00:00
Add ICE server preset support and update to Rondevu.connect()
- Add 4 ICE server presets: ipv4-turn, hostname-turns, google-stun, relay-only - Update Rondevu.connect() to accept preset string or custom RTCIceServer array - Support both automatic (maxOffers) and manual (offers array) modes in publishService() - Rename internal poll() to pollInternal() to avoid conflict with public API - Update README examples to use presets and proper offer factory pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
96
README.md
96
README.md
@@ -38,76 +38,43 @@ npm install @xtr-dev/rondevu-client
|
||||
```typescript
|
||||
import { Rondevu } from '@xtr-dev/rondevu-client'
|
||||
|
||||
// 1. Connect to Rondevu (generates keypair, username auto-claimed on first request)
|
||||
// 1. Connect to Rondevu with ICE server preset (generates keypair, username auto-claimed on first request)
|
||||
const rondevu = await Rondevu.connect({
|
||||
apiUrl: 'https://api.ronde.vu',
|
||||
username: 'alice' // Or omit for anonymous username
|
||||
username: 'alice', // Or omit for anonymous username
|
||||
iceServers: 'ipv4-turn' // Use preset: 'ipv4-turn', 'hostname-turns', 'google-stun', or 'relay-only'
|
||||
})
|
||||
|
||||
// 2. Create WebRTC offer
|
||||
const pc = new RTCPeerConnection({
|
||||
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
|
||||
})
|
||||
|
||||
const dc = pc.createDataChannel('chat')
|
||||
|
||||
const offer = await pc.createOffer()
|
||||
await pc.setLocalDescription(offer)
|
||||
|
||||
// 4. Publish service
|
||||
const service = await rondevu.publishService({
|
||||
// 2. Publish service with custom offer factory for event handling
|
||||
await rondevu.publishService({
|
||||
service: 'chat:1.0.0',
|
||||
offers: [{ sdp: offer.sdp }],
|
||||
maxOffers: 5, // Maintain up to 5 concurrent offers
|
||||
offerFactory: async (rtcConfig) => {
|
||||
const pc = new RTCPeerConnection(rtcConfig)
|
||||
const dc = pc.createDataChannel('chat')
|
||||
|
||||
// Set up event listeners during creation
|
||||
dc.addEventListener('open', () => {
|
||||
console.log('Connection opened!')
|
||||
dc.send('Hello from Alice!')
|
||||
})
|
||||
|
||||
dc.addEventListener('message', (e) => {
|
||||
console.log('Received message:', e.data)
|
||||
})
|
||||
|
||||
const offer = await pc.createOffer()
|
||||
await pc.setLocalDescription(offer)
|
||||
return { pc, dc, offer }
|
||||
},
|
||||
ttl: 300000
|
||||
})
|
||||
|
||||
const offerId = service.offers[0].offerId
|
||||
// 3. Start accepting connections (auto-fills offers and polls)
|
||||
await rondevu.startFilling()
|
||||
|
||||
// 5. Poll for answer and ICE candidates (combined)
|
||||
let lastPollTimestamp = 0
|
||||
const pollInterval = setInterval(async () => {
|
||||
const result = await rondevu.pollOffers(lastPollTimestamp)
|
||||
|
||||
// Check for answer
|
||||
if (result.answers.length > 0) {
|
||||
const answer = result.answers.find(a => a.offerId === offerId)
|
||||
if (answer) {
|
||||
await pc.setRemoteDescription({ type: 'answer', sdp: answer.sdp })
|
||||
lastPollTimestamp = answer.answeredAt
|
||||
}
|
||||
}
|
||||
|
||||
// Process ICE candidates
|
||||
if (result.iceCandidates[offerId]) {
|
||||
const candidates = result.iceCandidates[offerId]
|
||||
.filter(c => c.role === 'answerer') // Only answerer's candidates
|
||||
|
||||
for (const item of candidates) {
|
||||
await pc.addIceCandidate(new RTCIceCandidate(item.candidate))
|
||||
lastPollTimestamp = Math.max(lastPollTimestamp, item.createdAt)
|
||||
}
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
// 6. Send ICE candidates
|
||||
pc.onicecandidate = (event) => {
|
||||
if (event.candidate) {
|
||||
rondevu.addOfferIceCandidates(
|
||||
'chat:1.0.0@alice',
|
||||
offerId,
|
||||
[event.candidate.toJSON()]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Handle messages
|
||||
dc.onmessage = (event) => {
|
||||
console.log('Received:', event.data)
|
||||
}
|
||||
|
||||
dc.onopen = () => {
|
||||
dc.send('Hello from Alice!')
|
||||
}
|
||||
// 4. Stop when done
|
||||
// rondevu.stopFilling()
|
||||
```
|
||||
|
||||
### Connecting to a Service (Answerer)
|
||||
@@ -115,16 +82,17 @@ dc.onopen = () => {
|
||||
```typescript
|
||||
import { Rondevu } from '@xtr-dev/rondevu-client'
|
||||
|
||||
// 1. Connect to Rondevu
|
||||
// 1. Connect to Rondevu with ICE server preset
|
||||
const rondevu = await Rondevu.connect({
|
||||
apiUrl: 'https://api.ronde.vu',
|
||||
username: 'bob'
|
||||
username: 'bob',
|
||||
iceServers: 'ipv4-turn' // Use same preset as offerer
|
||||
})
|
||||
|
||||
// 2. Get service offer
|
||||
const serviceData = await rondevu.getService('chat:1.0.0@alice')
|
||||
|
||||
// 3. Create peer connection
|
||||
// 3. Create peer connection (use custom ICE servers if needed)
|
||||
const pc = new RTCPeerConnection({
|
||||
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user