Skip to content

Commit

Permalink
breaking change: support null candidates
Browse files Browse the repository at this point in the history
  • Loading branch information
shinyoshiaki committed Sep 20, 2024
1 parent 99042fc commit 9e5259d
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 19 deletions.
40 changes: 26 additions & 14 deletions packages/webrtc/src/peerConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class RTCPeerConnection extends EventTarget {
readonly onDataChannel = new Event<[RTCDataChannel]>();
readonly onRemoteTransceiverAdded = new Event<[RTCRtpTransceiver]>();
readonly onTransceiverAdded = new Event<[RTCRtpTransceiver]>();
readonly onIceCandidate = new Event<[RTCIceCandidate]>();
readonly onIceCandidate = new Event<[RTCIceCandidate | undefined]>();
readonly onNegotiationneeded = new Event<[]>();
readonly onTrack = new Event<[MediaStreamTrack]>();

Expand Down Expand Up @@ -227,11 +227,13 @@ export class RTCPeerConnection extends EventTarget {
return this._remoteDescription.toJSON();
}

private get _localDescription() {
/**@private */
get _localDescription() {
return this.pendingLocalDescription || this.currentLocalDescription;
}

private get _remoteDescription() {
/**@private */
get _remoteDescription() {
return this.pendingRemoteDescription || this.currentRemoteDescription;
}

Expand Down Expand Up @@ -512,6 +514,16 @@ export class RTCPeerConnection extends EventTarget {
log("localDescription not found when ice candidate was gathered");
return;
}
if (!candidate) {
this.setLocal(this._localDescription!);
this.onIceCandidate.execute(undefined);
if (this.onicecandidate) {
this.onicecandidate({ candidate: undefined });
}
this.emit("icecandidate", { candidate: undefined });
return;
}

if (this.config.bundlePolicy === "max-bundle" || this.remoteIsBundled) {
candidate.sdpMLineIndex = 0;
const media = this._localDescription?.media[0];
Expand Down Expand Up @@ -678,16 +690,6 @@ export class RTCPeerConnection extends EventTarget {
});
}

description.media
.filter((m) => ["audio", "video"].includes(m.kind))
.forEach((m, i) => {
addTransportDescription(m, this.transceivers[i].dtlsTransport);
});
const sctpMedia = description.media.find((m) => m.kind === "application");
if (this.sctpTransport && sctpMedia) {
addTransportDescription(sctpMedia, this.sctpTransport.dtlsTransport);
}

this.setLocal(description);

if (this.shouldNegotiationneeded) {
Expand All @@ -698,6 +700,16 @@ export class RTCPeerConnection extends EventTarget {
}

private setLocal(description: SessionDescription) {
description.media
.filter((m) => ["audio", "video"].includes(m.kind))
.forEach((m, i) => {
addTransportDescription(m, this.transceivers[i].dtlsTransport);
});
const sctpMedia = description.media.find((m) => m.kind === "application");
if (this.sctpTransport && sctpMedia) {
addTransportDescription(sctpMedia, this.sctpTransport.dtlsTransport);
}

if (description.type === "answer") {
this.currentLocalDescription = description;
this.pendingLocalDescription = undefined;
Expand Down Expand Up @@ -1743,7 +1755,7 @@ export interface RTCDataChannelEvent {
}

export interface RTCPeerConnectionIceEvent {
candidate: RTCIceCandidate;
candidate?: RTCIceCandidate;
}

type Media = "audio" | "video";
Expand Down
9 changes: 5 additions & 4 deletions packages/webrtc/src/transport/ice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const IceGathererStates = ["new", "gathering", "complete"] as const;
export type IceGathererState = (typeof IceGathererStates)[number];

export class RTCIceGatherer {
onIceCandidate: (candidate: IceCandidate) => void = () => {};
onIceCandidate: (candidate: IceCandidate | undefined) => void = () => {};
gatheringState: IceGathererState = "new";

readonly onGatheringStateChange = new Event<[IceGathererState]>();
Expand All @@ -126,9 +126,10 @@ export class RTCIceGatherer {
async gather() {
if (this.gatheringState === "new") {
this.setState("gathering");
await this.connection.gatherCandidates((candidate) =>
this.onIceCandidate(candidateFromIce(candidate)),
);
await this.connection.gatherCandidates((candidate) => {
this.onIceCandidate(candidateFromIce(candidate));
});
this.onIceCandidate(undefined);
this.setState("complete");
}
}
Expand Down
14 changes: 13 additions & 1 deletion packages/webrtc/tests/integrate/trickle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ describe("trickle", () => {
});

pcOffer.onIceCandidate.subscribe((candidate) => {
if (!candidate) {
expect(pcOffer._localDescription?.media.length).toBe(1);
return;
}
pcAnswer.addIceCandidate(candidate);
});

Expand All @@ -30,7 +34,9 @@ describe("trickle", () => {
});

const offer = await pcOffer.createOffer();
pcOffer.setLocalDescription(offer);
pcOffer.setLocalDescription(offer).then(() => {
expect(pcOffer._localDescription?.media.length).toBe(1);
});

await pcAnswer.setRemoteDescription(offer);
await pcAnswer.setLocalDescription(await pcAnswer.createAnswer());
Expand Down Expand Up @@ -58,9 +64,15 @@ describe("trickle", () => {
});

pcOffer.onIceCandidate.subscribe((candidate) => {
if (!candidate) {
return;
}
pcAnswer.addIceCandidate(candidate);
});
pcAnswer.onIceCandidate.subscribe((candidate) => {
if (!candidate) {
return;
}
pcOffer.addIceCandidate(candidate);
});

Expand Down
3 changes: 3 additions & 0 deletions packages/webrtc/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ function exchangeIceCandidates(pc1: RTCPeerConnection, pc2: RTCPeerConnection) {
// private function
function doExchange(localPc: RTCPeerConnection, remotePc: RTCPeerConnection) {
localPc.onIceCandidate.subscribe((candidate) => {
if (!candidate) {
return;
}
if (remotePc.signalingState !== "closed") {
remotePc.addIceCandidate(candidate);
}
Expand Down

0 comments on commit 9e5259d

Please sign in to comment.