Я пытаюсь создать файл чата P2P в Firefox с использованием WebRT C, но до сих пор мне не удавалось найти какие-либо рабочие примеры или изменить какие-либо примеры, которые я нашел для работы между различными компьютерами в разных сетях. Примеры, которые я нашел, работают только на одном компьютере или на двух компьютерах в одной сети. Я ищу пример, где я могу сделать следующее:
Пользователь 1 инициирует соединение, нажимая кнопку запуска, которая генерирует описание сеанса и дает его им. Затем они отправляют это описание сеанса по электронной почте пользователю 2.
Пользователь 2 вставляет описание сеанса от пользователя 1 в текстовое поле и получает второе описание сеанса в ответ. Затем пользователь 2 отправляет это второе описание сеанса обратно пользователю 1.
Пользователь 1 вставляет описание второго сеанса пользователя 2 в текстовое поле, которое завершает соединение.
Теперь сеанс завершен, оба пользователя могут общаться в чате и обратно.
В конечном итоге моя цель - выполнить sh передачу описания сеанса через централизованный сервер, но я хочу сначала установить sh этот метод в качестве подтверждения концепции, потому что если я не смогу заставить его работать, то я бы предпочел не тратить время на бит сервера.
Эти два примера - в значительной степени то, что я хочу сделать, но они работают только на одном компьютере:
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Simple_RTCDataChannel_sample
https://webrtc.github.io/samples/src/content/datachannel/basic/
Этот пример - именно то, что я хочу сделать, но ему 7 лет и он больше не работает:
https://cjb.github.io/serverless-webrtc/serverless-webrtc.html
Вот моя адаптация файла примера Mozilla, который я тестирую выше:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body {
font-family: "Lucida Grande", "Arial", sans-serif;
font-size: 16px;
}
.messagebox {
border: 1px solid black;
padding: 5px;
width: 450px;
}
.buttonright {
float: right;
}
.buttonleft {
float: left;
}
.controlbox {
padding: 5px;
width: 450px;
height: 28px;
}
</style>
<script>
var initiateConnectionButton = null;
var getAnswerButton = null;
var completeConnectionButton = null;
var disconnectButton = null;
var sendButton = null;
var messageInputBox = null;
var receiveBox = null;
var localConnection = null;
var sendChannel = null;
var receiveChannel = null;
var constraints = null;
var configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
function handleSendChannelStatusChange(event) {
return;
}
function handleReceiveChannelStatusChange(event) {
return;
}
window.addEventListener('load', function () {
initiateConnectionButton = document.getElementById('initiate-connection-button');
getAnswerButton = document.getElementById('get-answer-button');
completeConnectionButton = document.getElementById('complete-connection-button');
disconnectButton = document.getElementById('disconnect-button');
sendButton = document.getElementById('sendButton');
messageInputBox = document.getElementById('message');
receiveBox = document.getElementById('receivebox');
initiateConnectionButton.addEventListener('click', function () {
localConnection = new RTCPeerConnection();
sendChannel = localConnection.createDataChannel("sendChannel");
sendChannel.onopen = handleSendChannelStatusChange;
sendChannel.onclose = handleSendChannelStatusChange;
localConnection.createOffer()
.then(function(offer) {
console.log(JSON.stringify(offer));
localConnection.setLocalDescription(offer);
})
.catch(function(error) {
console.log("Unable to create an offer: " + error.toString());
});
}, false);
getAnswerButton.addEventListener('click', function () {
localConnection = new RTCPeerConnection(configuration);
sendChannel = localConnection.createDataChannel("sendChannel");
sendChannel.onopen = handleSendChannelStatusChange;
sendChannel.onclose = handleSendChannelStatusChange;
localConnection.onicecandidate = function(e) {
localConnection.addIceCandidate(e.candidate);
// if (e.candidate && e.candidate['candidate'].includes("TCP")) {
// localConnection.addIceCandidate(e.candidate);
// }
}
let sessionDescription = new RTCSessionDescription(JSON.parse(document.getElementById("local-description-input").value));
localConnection.setRemoteDescription(sessionDescription)
.then(function() {
answer = localConnection.createAnswer();
})
.then(function(answer) {
console.log(answer);
let result = localConnection.setLocalDescription(answer);
return result;
})
.catch(function(error) {
console.log("Error: " + error.toString());
});
}, false);
completeConnectionButton.addEventListener('click', function () {
localConnection.ondatachannel = function (event) {
receiveChannel = event.channel;
receiveChannel.onmessage = function(event) {
var el = document.createElement("p");
var txtNode = document.createTextNode(event.data);
el.appendChild(txtNode);
receiveBox.appendChild(el);
};
receiveChannel.onopen = handleReceiveChannelStatusChange;
receiveChannel.onclose = handleReceiveChannelStatusChange;
};
localConnection.onicecandidate = function(e) {
if (e.candidate && e.candidate['candidate'].includes("tcp")) {
console.log(e.candidate);
localConnection.addIceCandidate(e.candidate);
}
}
let sessionDescription = new RTCSessionDescription({
type: "answer",
sdp: atob(document.getElementById("remote-description-input").value)
});
localConnection.setRemoteDescription(sessionDescription);
console.log(localConnection);
}, false);
disconnectButton.addEventListener('click', function () {
// Close the RTCDataChannels if they're open.
sendChannel.close();
receiveChannel.close();
// Close the RTCPeerConnections
localConnection.close();
sendChannel = null;
receiveChannel = null;
localConnection = null;
}, false);
sendButton.addEventListener('click', function() {
var message = messageInputBox.value;
sendChannel.send(message);
messageInputBox.value = "";
messageInputBox.focus();
}, false);
}, false);
</script>
</head>
<body>
<div class="controlbox">
<button id="disconnect-button">
Disconnect
</button>
</div>
<div class="messagebox">
<label for="message">Enter a message:
<input type="text" name="message" id="message" placeholder="Message text"
inputmode="latin" size=60 maxlength=120>
</label>
<button id="sendButton" name="sendButton" class="buttonright">
Send
</button>
</div>
<div class="messagebox" id="receivebox">
<p>Messages received:</p>
</div>
<h2>Initiate Connection</h2>
<button id="initiate-connection-button">
Initiate Connection
</button>
<h2>Get Answer</h2>
<textarea id="local-description-input"></textarea>
<button id="get-answer-button">Get Answer</button>
<h2>Complete Connection</h2>
<textarea id="remote-description-input"></textarea>
<button id="complete-connection-button">Submit</button>
</body>
</html>
Вот журнал about: webrt c, который я получаю после того, как я попытка подключения:
(универсальный / EMERG) Выход из подключенного сокета UDP
(универсальный / ERR) Ошибка сокета UDP: внутренняя ошибка в / builds / worker / checkouts / gecko / dom / network / UDPSocketParent. cpp: 268 this = 00000258866EA000
(ice / INFO) /builds/worker/checkouts/gecko/media/mtransport/third_party/nICEr/src/net/nr_socket_multi_tcp.c:17 nr_socket_multi_tcp_create_stun_server_socket, пропускающий сервер UDP STUN (адрес:)
(ice / WARNING) / builds / worker / checkouts / gecko / media / mtr ansport / third_party / nICEr / src / net / nr_socket_multi_tcp. c: 617 Функция nr_socket_multi_tcp_listen завершилась ошибкой 3
(ice / WARNING) ICE (P C: 1586652270128000 (идентификатор = 2147): файл = 2147 ///C:/Users/root/Desktop/webrtc/index2.html)): не удалось создать пассивный кандидат на хост TCP: 3
(ice / WARNING) ICE (P C) : 1586652270128000 (id = 2147483682 url = файл: /// C: /Users/root/Desktop/webrtc/index2.html)): peer (P C: 1586652270128000 (id = 2147483682 url = файл: ///C:/Users/root/Desktop/webrtc/index2.html):default) нет потока, соответствующего потоку P C: 1586652270128000 (id = 2147483682 url = file: /// C : /Users/root/Desktop/webrtc/index2.html) transport-id = transport_0 - 18a9322f: 167fe60f30b26ec3c9fd8ab65febec08
(лед / УВЕДОМЛЕНИЕ) ICE (P C: 158665227l = 478 = 478 = 2848) = id: file: /// C: /Users/root/Desktop/webrtc/index2.html)): peer (P C: 1586652270128000 (id = 2147483682 url = файл: /// C: /) Users / root / Desktop / webrtc / index2. html): по умолчанию) нет потоки с непустыми контрольными списками
(лед / УВЕДОМЛЕНИЕ) ICE (P C: 1586652270128000 (id = 2147483682 url = file: /// C: / Users / root / Desktop / webrtc / index2. html)): peer (P C: 1586652270128000 (id = 2147483682 url = файл: /// C: /Users/root/Desktop/webrtc/index2.html): по умолчанию) нет потоки с запросами до ответа
(лед / УВЕДОМЛЕНИЕ) ICE (P C: 1586652270128000 (id = 2147483682 url = file: /// C: / Users / root / Desktop / webrtc / index2 . html)): peer (P C: 1586652270128000 (id = 2147483682 url = файл: /// C: /Users/root/Desktop/webrtc/index2.html): по умолчанию) без проверок для начала
(ice / ERR) ICE (P C: 1586652270128000 (id = 2147483682 url = file: /// C: /Users/root/Desktop/webrtc/index2.html)): peer ( P C: 1586652270128000 (id = 2147483682 url = file: /// C: /Users/root/Desktop/webrtc/index2.html): по умолчанию) для сопряжения локального узла-кандидата ICE (IP4: 173.17). 64.254: 58401 / UDP)
(ice / ERR) ICE (P C: 1586652270128000 (id = 2147483682 url = file: /// C: / Users / root / Desktop / webrtc / index2 . html)): peer (P C: 1586652270128000 (id = 2147483682 url = файл: /// C: /Users/root/Desktop/webrtc/index2.html): по умолчанию) спаривание локально узел-кандидат ICE (IP4: 173.17.64.254: 59370 / TCP) активный
(оглушение / INFO) STUN-CLIENT (srflx (IP4: 173.17.64.254: 58401 / UDP | stun.l.google.com) : 19302)): Получен ответ; обработка
(лед / INFO) ICE (P C: 1586652270128000 (id = 2147483682 url = файл: /// C: /Users/root/Desktop/webrtc/index2.html) ): Все кандидаты инициализированы
+++++++ END ++++++++