我已经有一段时间enter image description here这个错误了
一直试图使用异步来等待本地描述更新,但是由于我的代码现在如何工作,它无法将其集成,而且我还听说socket.on已经实现了异步本身。
我还尝试过在vs代码中使用断点来调试效果不佳的代码。
如果有人知道解决方法,将不胜感激。 代码附在下面
'use strict';
var localStream;
var remoteStream;
var isInitiator;
var configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
var pc = new RTCPeerConnection(configuration);
// Define action buttons.
const callButton = document.getElementById('callButton');
const hangupButton = document.getElementById('hangupButton');
/////////////////////////////////////////////
window.room = prompt('Enter room name:');
var socket = io.connect();
if (room !== '') {
console.log('Message from client: Asking to join room ' + room);
socket.emit('create or join', room);
}
socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
startVideo();
});
socket.on('joined', function(room) {
console.log('joined: ' + room);
startVideo();
});
socket.on('log', function(array) {
console.log.apply(console, array);
});
////////////////////////////////////////////////
function sendMessage(message) {
socket.emit('message', message);
}
// This client receives a message
socket.on('message', function(message) {
try {
if (message.type === 'offer') {
pc.setRemoteDescription(new RTCSessionDescription(message));
// const stream = navigator.mediaDevices.getUserMedia({
// audio: true,
// video: true
// });
// stream.getTracks().forEach(track => pc.addTrack(track, localStream));
pc.setLocalDescription(
pc.createAnswer(setLocalAndSendMessage, function(err) {
console
.log(err.name + ': ' + err.message)
.then(pc.setLocalDescription);
})
);
} else if (message.type === 'answer') {
console.log('This is to check if answer was returned');
pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate') {
pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
});
////////////////////////////////////////////////////
const localVideo = document.querySelector('#localVideo');
const remoteVideo = document.querySelector('#remoteVideo');
// Set up initial action buttons status: disable call and hangup.
callButton.disabled = true;
hangupButton.disabled = true;
// Add click event handlers for buttons.
callButton.addEventListener('click', callStart);
hangupButton.addEventListener('click', hangupCall);
function startVideo() {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(function(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
})
.catch(function(err) {
console.log('getUserMedia() error: ' + err.name);
});
callButton.disabled = false;
}
function callStart() {
createPeerConnection();
//pc.addTrack(mediaStream);
//stream.getTracks().forEach(track => pc.addTrack(track, localStream));
callButton.disabled = true;
hangupButton.disabled = false;
if (isInitiator) {
console.log('Sending offer to peer');
pc.createOffer(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message).then(pc.setLocalDescription);
});
}
}
/////////////////////////////////////////////////////////
function createPeerConnection() {
try {
pc = new RTCPeerConnection(null);
pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
pc.ontrack = event => {
if (remoteVideo.srcObject) return;
remoteVideo.srcObject = event.streams[0];
};
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}
function setLocalAndSendMessage(sessionDescription) {
console.log('setLocalAndSendMessage sending message', sessionDescription);
pc.setLocalDescription(sessionDescription);
sendMessage(sessionDescription);
}
function hangupCall() {
pc.close();
pc = null;
}
答案 0 :(得分:2)
没有了解异步代码的解决方法。您不会在这里粘贴自己的方式。
如果您不打算使用async/await,则需要应对JavaScript是单线程的,并且永远不能阻塞以等待异步操作完成,因此您永远不能直接使用异步方法的返回值,就像您要在此处进行的操作一样:
createAnswer
是一种异步方法,返回promise,而不是答案,所以这是错误:
pc.setLocalDescription( // <-- wrong
pc.createAnswer(setLocalAndSendMessage, function(err) { //
console
.log(err.name + ': ' + err.message)
.then(pc.setLocalDescription);
})
);
您正在呼叫setLocalDescription(promise)
,由于承诺不是有效的描述,因此您会提到错误。相反,a promise is an object you attach callbacks to:
const promise = pc.createAnswer();
promise.then(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message);
});
或简单地:
pc.createAnswer()
.then(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message);
});
我们甚至可以连续使用then
来形成promise chain:
pc.createAnswer()
.then(function(answer) {
return pc.setLocalDescription(answer);
})
.then(function() {
sendMessage(pc.localDescription);
})
.catch(function(err) {
console.log(err.name + ': ' + err.message);
});
此外,我不必告诉你console.log()
并没有兑现承诺!
遗憾的是,您要在此处复制really old code,并且RTCPeerConnection
具有一些旧版API,并提供了一些技巧,有时可以使呼叫者摆脱调用这些协商方法的麻烦,而无需真正的承诺链或检查错误。但这不可避免地会导致麻烦。