diff --git a/e2e/server/handler/ice/restart.ts b/e2e/server/handler/ice/restart.ts index b265fea7..05057862 100644 --- a/e2e/server/handler/ice/restart.ts +++ b/e2e/server/handler/ice/restart.ts @@ -38,7 +38,10 @@ export class ice_restart_answer { const offer = await this.pc.createOffer(); this.pc.setLocalDescription(offer); accept(this.pc.localDescription); + await this.pc.iceConnectionStateChange.watch((e) => e === "connected"); + this.pc.dataChannels[0].send("ping" + "pong" + "pang"); } + break; } } } diff --git a/e2e/server/main.ts b/e2e/server/main.ts index 714a8632..76b50d2c 100644 --- a/e2e/server/main.ts +++ b/e2e/server/main.ts @@ -57,6 +57,7 @@ import { mediachannel_simulcast_answer, mediachannel_simulcast_offer, } from "./handler/mediachannel/simulcast"; +import { ice_restart_answer } from "./handler/ice/restart"; const app = express(); app.use(express.json() as never); @@ -116,6 +117,7 @@ server.on("connectionrequest", async (_, accept) => { mediachannel_addtrack_removefirst_addtrack: new mediachannel_addtrack_removefirst_addtrack(), mediachannel_offer_replace_second: new mediachannel_offer_replace_second(), + ice_restart_answer: new ice_restart_answer(), }; const transport = accept(); diff --git a/e2e/tests/ice/restart.test.ts b/e2e/tests/ice/restart.test.ts new file mode 100644 index 00000000..b419c6ac --- /dev/null +++ b/e2e/tests/ice/restart.test.ts @@ -0,0 +1,122 @@ +import { peer, sleep, waitVideoPlay } from "../fixture"; + +describe("ice/restart", () => { + it( + "answer", + async () => + new Promise(async (done) => { + const label = "ice_restart_answer"; + + if (!peer.connected) await new Promise((r) => peer.on("open", r)); + await sleep(100); + + const pc = new RTCPeerConnection({ + iceServers: [{ urls: "stun:stun.l.google.com:19302" }], + }); + pc.ondatachannel = ({ channel }) => { + channel.onmessage = async ({ data }) => { + if (data === "ping" + "pong") { + const offer = await peer.request(label, { + type: "restart", + }); + await pc.setRemoteDescription(offer); + await pc.setLocalDescription(await pc.createAnswer()); + + peer + .request(label, { + type: "answer", + payload: pc.localDescription, + }) + .catch(() => {}); + } + + if (data === "ping" + "pong" + "pang") { + console.log(data); + pc.close(); + done(); + } + }; + channel.send("ping"); + }; + pc.ontrack = (ev) => { + waitVideoPlay(ev.track); + }; + pc.onicecandidate = ({ candidate }) => { + if (candidate) { + peer + .request(label, { + type: "candidate", + payload: candidate, + }) + .catch(() => {}); + } + }; + peer.on("request", async (request, accept) => { + if (request.method !== label) return; + const candidate = request.data; + await pc.addIceCandidate(candidate); + accept(); + }); + + const offer = await peer.request(label, { + type: "init", + }); + await pc.setRemoteDescription(offer); + await pc.setLocalDescription(await pc.createAnswer()); + + peer + .request(label, { + type: "answer", + payload: pc.localDescription, + }) + .catch(() => {}); + }), + 10 * 1000, + ); + + it( + "offer", + async () => + new Promise(async (done) => { + const label = "ice_trickle_offer"; + + if (!peer.connected) await new Promise((r) => peer.on("open", r)); + await sleep(100); + + const pc = new RTCPeerConnection({ + iceServers: [{ urls: "stun:stun.l.google.com:19302" }], + }); + const channel = pc.createDataChannel("dc"); + channel.onopen = () => { + channel.send("ping"); + }; + channel.onmessage = ({ data }) => { + expect(data).toBe("ping" + "pong"); + pc.close(); + done(); + }; + pc.onicecandidate = ({ candidate }) => { + peer + .request(label, { + type: "candidate", + payload: candidate, + }) + .catch(() => {}); + }; + peer.on("request", async (request, accept) => { + if (request.method !== label) return; + const candidate = request.data; + await pc.addIceCandidate(candidate); + accept(); + }); + + await pc.setLocalDescription(await pc.createOffer()); + const answer = await peer.request(label, { + type: "init", + payload: pc.localDescription, + }); + await pc.setRemoteDescription(answer); + }), + 10 * 1000, + ); +});