当我通过本地连接使用它时,连接工作得很好(例如我和我妈妈连接到与我相同的 wifi),但我住在另一个城市的朋友却不行
看一下前端代码
let sendChannel;
let receiveChannel;
let localConnection;
let remoteConnection;
let is_girl = false;
let is_boy = false;
let girlCodeExecuted = false;
let boyCodeExecuted = false;
let connected = false;
let hasReceivedAnswer = false;
let hasReceivedoffer = false;
let intervalID;
let offer;
let answer;
const configuration = {
iceServers: [
{
urls: "stun:stun.l.google.com:19302",
},
{
urls: "TURNS:freeturn.net:5349",
username: 'free',
credential: 'free'
},
],
};
function skip() {
if (is_boy) {
localConnection.close();
} else if (is_girl) {
remoteConnection.close();
}
}
function onConnect() {
var skipButton = document.getElementById('skip');
skipButton.removeAttribute('disabled');
connected = true;
clearInterval(intervalID)
ulll.innerHTML = '';
}
function onDisconnect() {
sendChannel = undefined;
receiveChannel = undefined;
localConnection = undefined;
remoteConnection = undefined;
offer = undefined;
answer = undefined;
is_girl = false;
is_boy = false;
girlCodeExecuted = false;
boyCodeExecuted = false;
hasReceivedAnswer = false;
hasReceivedoffer = false;
connected = false;
console.log('ondisconnect');
var skipButton = document.getElementById('skip');
skipButton.setAttribute('disabled', '');
intervalID = setInterval(sendhello, 1000);
reconnect();
}
var socket = new WebSocket('wss://' + window.location.host + '/text/');
var ulll = document.querySelector("#ulll");
function reconnect() {
console.log("Reconnecting...");
socket = new WebSocket('wss://' + window.location.host + '/text/');
socket.onmessage = async function (event) {
var data = JSON.parse(event.data);
console.log(data);
if (data.waiting_users) {
if (data.waiting_users[0] === '{{user.username}}') {
await boy();
is_boy = true;
console.log('hi boy');
}
if (data.waiting_users[1] === '{{user.username}}') {
is_girl = true;
console.log('hi girl');
}
}
offer = await data.offer;
if (offer && is_girl && !hasReceivedoffer) {
console.log('entered stage2');
await girl(offer);
hasReceivedoffer = true
}
answer = await data.answer;
if(answer){clearInterval(intervalID)}
if (answer&& is_boy && !hasReceivedAnswer) {
await localConnection.setRemoteDescription(new RTCSessionDescription(answer));
console.log('boy just received answer');
hasReceivedAnswer = true;
}
};
}
async function boy() {
if (!boyCodeExecuted) {
console.log('boy is running');
localConnection = new RTCPeerConnection(configuration);
localConnection.onicecandidate = e => {
console.log("ICE candidate event:", e);
if (localConnection.iceGatheringState === 'complete') {
console.log("NEW ice candidate!!");
socket.send(JSON.stringify({ offer: localConnection.localDescription }));
}
};
sendChannel = localConnection.createDataChannel("sendChannel");
sendChannel.onmessage = e => {
console.log("Received message on sendChannel:", e.data);
let li = document.createElement('li');
li.id = 'you';
li.textContent = e.data;
li.classList.add("new-message");
ulll.appendChild(li);
}
sendChannel.onopen = e => {
console.log("sendChannel opened");
sendChannel.send('به {{ user.name }} {{user.age}} ساله از {{ user.city }} متصل شدید باهم دوست باشید :)');
socket.send(JSON.stringify({ d: 'hola' }));
socket.close();
console.log('boy is connected');
onConnect();
}
sendChannel.onclose = e => {
console.log("sendChannel closed");
ulll.innerHTML = '<li>درحال پیدا کردن کاربر ...</li>';
console.log("closed!");
document.getElementById('remoteVideo').srcObject = undefined;
document.getElementById('remoteVideo').src = "{% static 'loading.mp4' %}";
document.getElementById('remoteVideo').loop = true;
console.log('boy is disconnected');
onDisconnect();
}
stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
console.log("Local stream:", stream);
document.getElementById('localVideo').srcObject = stream;
localStream = stream;
document.getElementById('localVideo').muted = true;
localStream.getTracks().forEach(track => {
console.log("Adding track to localConnection:", track);
localConnection.addTrack(track, localStream);
});
offer = await localConnection.createOffer();
console.log("Created offer:", offer);
await localConnection.setLocalDescription(offer);
localConnection.ontrack = event => {
console.log('ontrack event fired in boy function');
if (event.streams[0]) {
console.log('Stream is defined in ontrack event');
document.getElementById('remoteVideo').srcObject = event.streams[0];
document.getElementById('remoteVideo').loop = false;
} else {
console.log('Stream is not defined in ontrack event');
document.getElementById('remoteVideo').src = "{% static 'loading.mp4' %}";
document.getElementById('remoteVideo').loop = true;
}
};
localConnection.onclose = event => {
console.log('Connection closed in boy function');
document.getElementById('remoteVideo').src = "{% static 'loading.mp4' %}";
document.getElementById('remoteVideo').loop = true;
};
boyCodeExecuted = true
}
}
async function girl(offer) {
if (!girlCodeExecuted) {
console.log('girl is running');
remoteConnection = new RTCPeerConnection(configuration);
remoteConnection.ondatachannel = e => {
console.log("Data channel event:", e);
receiveChannel = e.channel;
receiveChannel.onmessage = e => {
console.log("Received message on receiveChannel:", e.data);
let li = document.createElement('li');
li.id = 'you';
li.textContent = e.data;
li.classList.add("new-message");
ulll.appendChild(li);
};
receiveChannel.onopen = e => {
console.log("receiveChannel opened");
receiveChannel.send('به {{ user.name }} {{user.age}} ساله از {{ user.city }} متصل شدید باهم دوست باشید :)');
socket.close();
console.log('girl is connected');
onConnect();
};
receiveChannel.onclose = e => {
console.log("receiveChannel closed");
ulll.innerHTML = '<li>درحال پیدا کردن کاربر ...</li>';
console.log("closed!!!!!!");
document.getElementById('remoteVideo').srcObject = undefined;
document.getElementById('remoteVideo').src = "{% static 'loading.mp4' %}";
document.getElementById('remoteVideo').loop = true;
console.log('girl is disconnected');
onDisconnect();
};
remoteConnection.channel = receiveChannel;
};
if (remoteConnection.signalingState !== 'have-remote-offer') {
remoteConnection.ontrack = event => {
console.log("ontrack event fired in girl function");
if (event.streams && event.streams[0]) {
console.log('Stream is defined in ontrack event');
document.getElementById('remoteVideo').srcObject = event.streams[0];
document.getElementById('remoteVideo').loop = false;
}
};
await remoteConnection.setRemoteDescription(new RTCSessionDescription(offer));
stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
console.log("Local stream:", stream);
document.getElementById('localVideo').srcObject = stream;
document.getElementById('localVideo').muted = true;
stream.getTracks().forEach(track => {
console.log("Adding track to remoteConnection:", track);
remoteConnection.addTrack(track, stream);
});
let answer = await remoteConnection.createAnswer();
console.log("Created answer:", answer);
await remoteConnection.setLocalDescription(answer);
remoteConnection.onclose = event => {
console.log('Connection closed in girl function');
document.getElementById('remoteVideo').src = "{% static 'loading.mp4' %}";
document.getElementById('remoteVideo').loop = true;
};
console.log("Sending answer:", remoteConnection.localDescription);
socket.send(JSON.stringify({ answer: remoteConnection.localDescription }));
}
girlCodeExecuted = true;
}
}
function girl_message(message) {
let li = document.createElement("li");
li.id = "me";
li.textContent = message;
let ul = document.querySelector("#ulll");
ul.appendChild(li);
li.classList.add("new-message");
remoteConnection.channel.send(message);
document.getElementById('text').value = '';
}
function boy_message(message) {
let li = document.createElement("li");
li.id = "me";
li.textContent = message;
let ul = document.querySelector("#ulll");
ul.appendChild(li);
li.classList.add("new-message");
sendChannel.send(message);
document.getElementById('text').value = '';
}
socket.onopen = () => { console.log('یه سوکت باز شد'); }
function sendhello() {
if(!connected){
socket.send(JSON.stringify({helele : 'jehehe'}))
console.log('sending shit');}
}
intervalID = setInterval(sendhello, 1000);
socket.onmessage = async function (event) {
var data = JSON.parse(event.data);
console.log(data);
if (data.waiting_users) {
if (data.waiting_users[0] === '{{user.username}}') {
await boy();
is_boy = true;
console.log('hi boy');
}
if (data.waiting_users[1] === '{{user.username}}') {
is_girl = true;
console.log('hi girl');
}
}
offer = await data.offer;
if (offer && is_girl && !hasReceivedoffer) {
console.log('entered stage2');
await girl(offer);
hasReceivedoffer = true
}
answer = await data.answer;
if(answer){clearInterval(intervalID)}
if (answer&& is_boy && !hasReceivedAnswer) {
await localConnection.setRemoteDescription(new RTCSessionDescription(answer));
console.log('boy just received answer');
hasReceivedAnswer = true;
}
};
socket.onclose = (event) => {
console.log('WebSocket connection closed with code ' + event.code);
clearInterval(intervalID)
};
function send_message() {
let message = document.getElementById('text').value
console.log(message)
if (is_boy) {
boy_message(message);
} else if (is_girl) {
girl_message(message);
message = '';
}
}
const textInput = document.getElementById('text');
textInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
send_message()
}
});
在后端我使用 Django 通道,这不是问题,在两者的控制台中我看到他们接受了提议并回答 请帮助我,我的一生都在这个项目上。
我尝试了许多免费转弯服务器,例如计量和快速转弯,但问题仍然存在。
您的冰服务器定义不正确。只需使用:
iceServers: [
{
urls: ["stun:stun.l.google.com:19302"],
},
{
urls: ["turn:freeturn.net:5349"],
username: "free",
credential: "free"
},
],