WebRTC datachannel with manual signaling, example please?

|▌冷眼眸甩不掉的悲伤 提交于 2020-06-11 07:53:26

问题


I'm really struggling to get a complete example of a WebRTC datachannel example that I can copy/paste and it works.

I would like a Javascript example of WebRTC datachannel with manual signaling i.e. When the example loads, it provides the Signaling data in one text box. I copy data manually (highlight, copy) and paste it in the peer's window which has a text box to accept that signaling data. I believe there needs to be an "answer" in the signaling data, so there need to be corresponding text boxes waiting for that input as well. Thank you.

Could the example use Google's free STUN server please.

I get really confused with bit by bit examples, I want one file please, that contains the HTML and Javascript (no CSS or JQuery please). It is enough for the code to work on Chrome only. Thanks.


回答1:


Here it is. Click the blue button below in two different tabs/windows/browsers/machines:

const config = {iceServers: [{urls: "stun:stun.1.google.com:19302"}]};
const pc = new RTCPeerConnection(config);
const dc = pc.createDataChannel("chat", {negotiated: true, id: 0});
const log = msg => div.innerHTML += `<br>${msg}`;
dc.onopen = () => chat.select();
dc.onmessage = e => log(`> ${e.data}`);
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState);

chat.onkeypress = function(e) {
  if (e.keyCode != 13) return;
  dc.send(chat.value);
  log(chat.value);
  chat.value = "";
};

async function createOffer() {
  button.disabled = true;
  await pc.setLocalDescription(await pc.createOffer());
  pc.onicecandidate = ({candidate}) => {
    if (candidate) return;
    offer.value = pc.localDescription.sdp;
    offer.select();
    answer.placeholder = "Paste answer here";
  };
}

offer.onkeypress = async function(e) {
  if (e.keyCode != 13 || pc.signalingState != "stable") return;
  button.disabled = offer.disabled = true;
  await pc.setRemoteDescription({type: "offer", sdp: offer.value});
  await pc.setLocalDescription(await pc.createAnswer());
  pc.onicecandidate = ({candidate}) => {
    if (candidate) return;
    answer.focus();
    answer.value = pc.localDescription.sdp;
    answer.select();
  };
};

answer.onkeypress = function(e) {
  if (e.keyCode != 13 || pc.signalingState != "have-local-offer") return;
  answer.disabled = true;
  pc.setRemoteDescription({type: "answer", sdp: answer.value});
};
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here"></textarea>
Answer: <textarea id="answer"></textarea><br><div id="div"></div>
Chat: <input id="chat"><br>

Then follow these steps:

  1. In Window A, press the Offer button and copy the offer to the clipboard.
  2. In Window B, paste that offer into "Paste offer here" and hit the ENTER key.
  3. Copy the answer that appears after a few seconds.
  4. Return to window A and paste that answer where it says "Paste answer here" and hit ENTER.

You should now see a message saying you're "connected". Type in the chat box to chat!

If you and a friend exchange the offer/answer somehow, you now have a direct peer-to-peer connection. This should work around the world (modulo symmetric NATs); no data server involved.




回答2:


const config = {iceServers: [{urls: "stun:stun.1.google.com:19302"}]};
const pc = new RTCPeerConnection(config);
const dc = pc.createDataChannel("chat", {negotiated: true, id: 0});
const log = msg => div.innerHTML += `<br>${msg}`;
dc.onopen = () => chat.select();
dc.onmessage = e => log(`> ${e.data}`);
pc.oniceconnectionstatechange = e => log(pc.iceConnectionState);

chat.onkeypress = function(e) {
  if (e.keyCode != 13) return;
  dc.send(chat.value);
  log(chat.value);
  chat.value = "";
};

async function createOffer() {
  button.disabled = true;
  await pc.setLocalDescription(await pc.createOffer());
  pc.onicecandidate = ({candidate}) => {
    if (candidate) return;
    offer.value = pc.localDescription.sdp;
    offer.select();
    answer.placeholder = "Paste answer here";
  };
}

offer.onkeypress = async function(e) {
  if (e.keyCode != 13 || pc.signalingState != "stable") return;
  button.disabled = offer.disabled = true;
  await pc.setRemoteDescription({type: "offer", sdp: offer.value});
  await pc.setLocalDescription(await pc.createAnswer());
  pc.onicecandidate = ({candidate}) => {
    if (candidate) return;
    answer.focus();
    answer.value = pc.localDescription.sdp;
    answer.select();
  };
};

answer.onkeypress = function(e) {
  if (e.keyCode != 13 || pc.signalingState != "have-local-offer") return;
  answer.disabled = true;
  pc.setRemoteDescription({type: "answer", sdp: answer.value});
};
<button id="button" onclick="createOffer()">Offer:</button>
<textarea id="offer" placeholder="Paste offer here"></textarea>
Answer: <textarea id="answer"></textarea><br><div id="div"></div>
Chat: <input id="chat"><br>


来源:https://stackoverflow.com/questions/54980799/webrtc-datachannel-with-manual-signaling-example-please

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!