Как определить, что WebRTC dataChannel.send доставлен? - PullRequest
1 голос
/ 06 октября 2019

Я пытаюсь написать приложение для чата, используя WebRTC, и могу отправлять сообщения через канал данных, используя код, подобный приведенному ниже:

const peerConnection = new RTCPeerConnection();

const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

с помощью dataChannel.send() Я могу отправлять данные по каналу правильно,но мне интересно знать, есть ли способ определить, что отправленное сообщение доставлено другой стороне или нет?

1 Ответ

1 голос
/ 08 октября 2019

Это самый простой ответ: отправьте ответ.

Но вам может не понадобиться, если вы используете заказанный , надежный канал данных (по умолчанию).

Упорядоченный надежный канал данных

С помощью одного из них вы определяете, что сообщение было отправлено , ожидая, пока bufferedAmount завершит работу. :

const pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
const channel = pc1.createDataChannel("chat");

chat.onkeypress = async e => {
  if (e.keyCode != 13) return;

  const before = channel.bufferedAmount;
  channel.send(chat.value);

  const after = channel.bufferedAmount;
  console.log(`Queued ${after - before} bytes`);

  channel.bufferedAmountLowThreshold = before; // set floor trigger and wait
  await new Promise(r => channel.addEventListener("bufferedamountlow", r));

  console.log(`Sent ${after - channel.bufferedAmount} bytes`);
  chat.value = "";
};

pc2.ondatachannel = e => e.channel.onmessage = e => console.log(`> ${e.data}`);
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.oniceconnectionstatechange = e => console.log(pc1.iceConnectionState);
pc1.onnegotiationneeded = async e => {
  await pc1.setLocalDescription(await pc1.createOffer());
  await pc2.setRemoteDescription(pc1.localDescription);
  await pc2.setLocalDescription(await pc2.createAnswer());
  await pc1.setRemoteDescription(pc2.localDescription);
}
Chat: <input id="chat"><br>

Поскольку канал надежен , он не откажется от отправки этого сообщения, пока оно не будет получено.

Поскольку канал заказан , он не будет отправлять второе сообщение, пока это сообщение не будет получено.

Это позволяет отправлять кучу сообщений подряд, не дожидаясь ответа. Пока bufferedAmount продолжает работать, вы знаете, что оно отправляется и принимается.

Короче говоря, чтобы определить, было ли получено сообщение, отправьте второе сообщение или попросите другую сторону отправить ответ.

Ненадежный канал данных

Если вы используете ненадежный канал данных, то отправка ответа является единственным способом. Но поскольку нет гарантии, что ответ вернет его, это может привести к ложным отрицаниям, что приведет к дублированию сообщений на принимающей стороне.

Ненадежный один способ, надежный другой

Использование согласованный аргумент конструктора , возможно создать канал данных, который ненадежен в одном направлении, но надежен в другом. Это можно использовать для устранения ненадежного ответа, чтобы избежать дублирования сообщений на принимающей стороне (pc2).

dc1 = pc1.createDataChannel("chat", {negotiated: true, id: 0, maxRetransmits: 0});
dc2 = pc2.createDataChannel("chat", {negotiated: true, id: 0});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...