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 = "";
};