Add init method into WebRTC Signalling

This commit is contained in:
sergystepanov 2026-06-06 14:20:17 +03:00
parent 844d84b6ac
commit fa783dc7cd
2 changed files with 46 additions and 45 deletions

View file

@ -486,40 +486,29 @@ sub(MESSAGE, onMessage);
function handleWebrtcStart({ data, initiator }) {
workerManager.whoami(data.wid);
const datachannel = (ch) => {
if (ch.label === "data") {
// we'll handle ws and webrtc server messages in one place
ch.onmessage = (x) => onMessage(api.fromBytes(x.data));
}
return ch;
};
webrtc.start({
initiator,
iceServers: data.ice,
media: stream.video.el,
onDataChannel: datachannel,
onDataChannel: (ch) => {
if (ch.label === "data") {
// we'll handle ws and webrtc server messages in one place
ch.onmessage = (x) => onMessage(api.fromBytes(x.data));
}
return ch;
},
onConnect: onConnectionReady,
onDisconnect: () => {
input.retropad.toggle(false);
webrtc.stop();
},
signalling: {
init: api.server.initWebrtcStream,
sendIceCandidate: api.server.sendIceCandidate,
sendSdp: api.server.sendSdp,
},
});
if (initiator) {
webrtc.createDataChannel({ onChannel: datachannel });
webrtc.offer().then((offer) => {
if (!offer) return;
api.server.initWebrtcStream({ initiator, sdpOffer: offer });
});
} else {
api.server.initWebrtcStream();
}
gameList.set(data.games);
}

View file

@ -17,7 +17,7 @@ const ice = ((signaller) => {
const onCandidate = (/** @type {RTCPeerConnectionIceEvent} */ ev) => {
if (!ev.candidate) return;
log.debug(`[rtc] [ice] local`, ev.candidate);
signaller?.sendIceCandiadte(ev.candidate);
signaller()?.sendIceCandidate(ev.candidate);
};
const onCandidateError = (
@ -78,7 +78,7 @@ const ice = ((signaller) => {
flush,
close: () => (buf = []),
};
})(signal);
})(() => signal);
const isConnected = () => pc?.connectionState === "connected";
@ -90,6 +90,20 @@ const mung = (sdp) =>
const stub = () => {};
const offer = async () => {
if (!pc || !caller) return;
try {
const offer = await pc.createOffer();
offer.sdp = mung(offer.sdp);
await pc.setLocalDescription(offer);
log.debug("[rtc] [sdp] local:", offer);
return offer;
} catch (e) {
log.error("[rtc] [sdp] local:", e);
}
};
/**
* WebRTC connection module.
*/
@ -151,20 +165,31 @@ export const webrtc = {
log.debug("[rtc] negotiation");
};
pc.ontrack = (event) => stream.addTrack(event.track);
},
offer: async () => {
if (!pc || !caller) return;
try {
const offer = await pc.createOffer();
offer.sdp = mung(offer.sdp);
await pc.setLocalDescription(offer);
log.debug("[rtc] [sdp] local:", offer);
return offer;
} catch (e) {
log.error("[rtc] [sdp] local:", e);
if (initiator) {
// push datachannel
try {
let ch = pc.createDataChannel("data", {
ordered: false,
maxRetransmits: 0,
});
ch = onDataChannel ? onDataChannel(ch) : ch;
if (!ch) throw new Error("null channel");
channels.set(ch.label, ch);
} catch (e) {
log.error("[rtc] failed to create data channel", e);
return;
}
offer().then((offer) => {
if (!offer) return;
signalling.init({ initiator, sdpOffer: offer });
});
} else {
signalling.init();
}
},
offer,
answer: async (/** @type {RTCSessionDescriptionInit} */ sdp) => {
log.debug("[rtc] [sdp] remote:", sdp);
@ -203,19 +228,6 @@ export const webrtc = {
if (!isConnected()) return Promise.resolve();
return await pc.getStats();
},
createDataChannel: ({ onChannel }) => {
try {
let ch = pc.createDataChannel("data", {
ordered: false,
maxRetransmits: 0,
});
ch = onChannel ? onChannel(ch) : ch;
if (!ch) throw new Error("null channel");
channels.set(ch.label, ch);
} catch (e) {
log.error("[rtc] failed to create data channel", e);
}
},
stop: () => {
if (stream) {
while (stream.getTracks().length > 0) {