Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions example/legacy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Legacy Two-Browser Test</title>
<style>
body { font-family: sans-serif; margin: 16px; }
.row { margin-bottom: 10px; }
#log { width: 100%; min-height: 260px; }
</style>
</head>
<body>
<h1>Legacy Two-Browser Test</h1>
<p>
Open this page in two browsers/tabs. In browser A click Create Lobby.
Copy the lobby code and paste it in browser B, then click Join Lobby.
</p>

<div class="row">
<button id="create" type="button">Create Lobby</button>
<input id="code" placeholder="Lobby code (copy from other browser)">
<button id="join" type="button">Join Lobby</button>
<button id="leave" type="button">Leave</button>
</div>

<div class="row">
<strong>Your peer id:</strong> <span id="peer-id">(not ready)</span><br>
<strong>Current lobby:</strong> <span id="lobby">(none)</span>
</div>

<textarea id="log" readonly></textarea>

<!-- Note: this file is for us to test if the legacy bundle still works, we recommend using the npm approach. -->
<script src="../dist/legacy.js"></script>
<script>
const peerIdEl = document.getElementById('peer-id')
const lobbyEl = document.getElementById('lobby')
const logEl = document.getElementById('log')
const codeInput = document.getElementById('code')

const NETWORK_ID = 'd0fe1ca1-7fa0-47ed-9469-6c792f68bae0'
const network = new window.netlib.Network(NETWORK_ID)

function log(line) {
logEl.value += line + '\n'
logEl.scrollTop = logEl.scrollHeight
}

function updateHeader() {
peerIdEl.textContent = network.id || '(not ready)'
lobbyEl.textContent = network.currentLobby || '(none)'
}

network.on('ready', () => {
updateHeader()
log('ready')
})

network.on('lobby', (code) => {
updateHeader()
codeInput.value = code
log('lobby ready: ' + code)
})

network.on('left', () => {
updateHeader()
log('left lobby')
})

network.on('connecting', (peer) => {
log('connecting to peer ' + peer.id)
})

network.on('connected', (peer) => {
log('connected to peer ' + peer.id + ' (peers=' + network.size + ')')
})

network.on('disconnected', (peer) => {
log('disconnected from peer ' + peer.id + ' (peers=' + network.size + ')')
})

network.on('signalingerror', (err) => {
log('signalingerror: ' + String(err))
console.error(err)
})

network.on('rtcerror', (err) => {
log('rtcerror: ' + String(err))
console.error(err)
})

document.getElementById('create').addEventListener('click', () => {
if (network.currentLobby !== undefined) {
log('already in lobby ' + network.currentLobby)
return
}
log('creating lobby...')
void network.create({ codeFormat: 'short', public: false })
})

document.getElementById('join').addEventListener('click', () => {
const code = codeInput.value.trim()
if (code === '') {
log('enter a lobby code first')
return
}
if (network.currentLobby !== undefined) {
log('already in lobby ' + network.currentLobby + ', leave first')
return
}

log('joining lobby ' + code + '...')
void network.join(code).then((info) => {
if (info === undefined) {
log('join failed: lobby not found or unavailable')
} else {
updateHeader()
log('joined lobby ' + info.code)
}
})
})

document.getElementById('leave').addEventListener('click', () => {
if (network.currentLobby === undefined) {
log('not in a lobby')
return
}
log('leaving lobby...')
void network.leave()
})

updateHeader()
</script>
</body>
</html>
62 changes: 32 additions & 30 deletions lib/peer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,36 +59,7 @@ export default class Peer {
}
this.conn.addEventListener('negotiationneeded', () => {
this.politenessTimeout = setTimeout(() => {
(async () => {
try {
if (this.closing) {
return
}
this.makingOffer = true
if (process.env.NODE_ENV === 'test') {
// Running tests with node and the wrtc package causes the
// setLocalDescription to fail with undefined as argment.
await this.conn.setLocalDescription(await this.conn.createOffer())
} else {
await this.conn.setLocalDescription()
}
const description = this.conn.localDescription
if (description != null) {
await this.testSessionWrapper?.(description, this.config, this.network.id, this.id)
this.signaling.send({
type: 'description',
source: this.network.id,
recipient: this.id,
description
})
}
} catch (e) {
const error = new SignalingError('unknown-error', e as string)
this.network._onSignalingError(error)
} finally {
this.makingOffer = false
}
})().catch(_ => {})
void this.handleNegotiationNeeded()
}, this.polite ? 100 : 0)
})

Expand Down Expand Up @@ -220,6 +191,37 @@ export default class Peer {
}
}

private async handleNegotiationNeeded (): Promise<void> {
try {
if (this.closing) {
return
}
this.makingOffer = true
if (process.env.NODE_ENV === 'test') {
// Running tests with node and the wrtc package causes the
// setLocalDescription to fail with undefined as argment.
await this.conn.setLocalDescription(await this.conn.createOffer())
} else {
await this.conn.setLocalDescription()
}
const description = this.conn.localDescription
if (description != null) {
await this.testSessionWrapper?.(description, this.config, this.network.id, this.id)
this.signaling.send({
type: 'description',
source: this.network.id,
recipient: this.id,
description
})
}
} catch (e) {
const error = new SignalingError('unknown-error', e as string)
this.network._onSignalingError(error)
} finally {
this.makingOffer = false
}
}

private onError (e: Event): void {
this.network.emit('rtcerror', e)
if (this.network.listenerCount('rtcerror') === 0) {
Expand Down
Loading