Async sctp transport chat
by jib1
HTML
Chat: <input id="chat" disabled>
<div id="div" ></div>
JavaScript
const console = {log: msg => div.innerHTML += `${msg}<br>`};
const dump = f => console.log(`${f.toString().slice(6)} = ${JSON.stringify(f(), null, 2)}`);
const dumpSctp = f => {
function sctp(sctp) {
if (!sctp) return sctp;
const {state, maxMessageSize, maxChannels} = sctp;
return `{state: ${state}, maxMessageSize: ${maxMessageSize}, maxChannels: ${maxChannels}}`;
};
console.log(`${f.toString().slice(6)} = ${sctp(f())}`);
}
const pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
const channel = pc1.createDataChannel("chat");
channel.onopen = () => chat.disabled = false;
dump(() => channel.id);
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.onnegotiationneeded = async e => {
await pc1.setLocalDescription();
dump(() => pc1.signalingState);
dumpSctp(() => pc1.sctp);
pc1.sctp.onstatechange = () => { dump(() => pc1.sctp.state); dump(() => channel.id); }
await pc2.setRemoteDescription(pc1.localDescription);
dump(() => pc2.signalingState);
dumpSctp(() => pc2.sctp);
await pc2.setLocalDescription();
dump(() => pc2.signalingState);
dumpSctp(() => pc2.sctp);
await pc1.setRemoteDescription(pc2.localDescription);
dump(() => pc1.signalingState);
dumpSctp(() => pc1.sctp);
};
pc2.ondatachannel = ({channel}) => {
channel.onopen = () => console.log("<br>Chat!");
channel.onmessage = ({data}) => console.log(`> ${data}`);
};
chat.onkeypress = ({keyCode}) => {
if (keyCode != 13) return;
channel.send(chat.value);
chat.value = "";
};