页面重载后连接多个peerConnections
我创建使用的WebRTC智能手机监控Web应用程序,以及信令服务器我使用socket.io。
当我发送流,我创建了接收该流的“观看”页面上的RTCPeerConnection对象。流送我在不同的页面。用户可以从智能手机连接多达4个数据流,因此,“观看”页面上有多达四个RTCPeerConnection对象。
流一旦收到自动从“发送”页面的报价出现,那么RTCPeerConnection对象被创建的“监视”页上,并连接到标准的WebRTC架构。
“发送”页面:
function onCreateOfferSuccess(sdp){
//console.log(sdp);
pc.setLocalDescription(new RTCSessionDescription(sdp));
console.log('ask');
socket.emit('ask', {"sdp":JSON.stringify(pc.localDescription),
"user": loggedUserID,
"fromSocket": ownSocket});
}
“观看”页面:
socket.on('ask', function(offer){
if (offer.user === loggedUserID){
TempDescriptions = JSON.parse(offer.sdp);
console.log(TempDescriptions)
currTransmiterSocket = offer.fromSocket;
console.log(currTransmiterSocket);
getStream();
}
function getStream(){
try {
setTimeout(function(){
console.log(time, 'getStream()');
connection = getPeerConnection();
connection.setRemoteDescription(
new RTCSessionDescription(TempDescriptions),
function() {
connection.createAnswer(gotDescription, function(error){
console.log(error)
});
}, function(error){
console.log(error)
});
}, getStreamDelay*3000)
getStreamDelay++
}
catch(err){
console.log(err);
}
};
我的Web应用程序需要在其中,当我们从“观看”页面退出,再次返回到它,所有以前包括流必须显示的功能。
为了实现这个功能,我用的是oniceconnectionstatechange方法。如果数据流中断,则执行iceRestart功能,创建一个与选项报价{iceRestart:真正}
“发送”页面:
var options_with_restart = {offerToReceiveAudio: false,
offerToReceiveVideo: true,
iceRestart: true};
function iceRestart(event){
try{
setTimeout(function(){
pc.createOffer(options_with_restart).then(onCreateOfferSuccess, onCreateOfferError);
},1000);
} catch(error) {
console.log(error);
问题是,当我重新启动了“观看”页面,所有页面“发送”发送到问一次。只有一个对象被连接时,尽管在一次会创建四个RTCPeerConnection对象(让我们假定用户发送四个数据流)。
我一直在努力解决这个问题了好几天。我试图设置在后续调用为出现在上面的代码getStream()函数增加的时间延迟,我试图执行getStream()函数前检查signallingState
连接,我试了其他几种方法,但没有一次成功。
如果你需要我的代码,以帮助某些部分,请写信。
编辑:
在“观看”页面gotDescription()方法。
function gotDescription(sdp) {
try{
connection.setLocalDescription(sdp,
function() {
registerIceCandidate();
socket.emit('response', {"sdp": sdp,
"user": loggedUserID,
"fromSocket": ownSocket,
"toSocket": currTransmiterSocket});
}, function(error){
console.log(error)
});
} catch(err){
console.log(err);
}
}
我想补充console.log
与RTCPeerConnection object
控制台输出:.png1
日志显示连接的signalingState
是“稳定的”,但是当我开发的对象,signalingState
等于“有远程要约”
like here
回答如下:取下TempDescriptions
全局变量,并通过SDP直接getStream(offer.sdp)
。
否则,你socket.on('ask', function(offer){
称为4倍,覆盖TempDescriptions
。然后3+秒后您的4 setTimeout
s打滚,都只是访问TempDescriptions
的最终值。
这可能是为什么只有一个RTCPeerConnection再所连接。
在一般情况下,使用时间延迟到单独的连接似乎是一个坏主意,因为它会减慢重新连接。相反,为什么不发送id
?例如。
socket.emit('ask', {id: connectionNumber++,
sdp: JSON.stringify(pc.localDescription),
user: loggedUserID,
fromSocket: ownSocket});
Update: Stop adding global variables to window
当你分配到一个这样的未声明的变量:
connection = getPeerConnection();
......它创造了全球上window
,例如window.connection
,和你有同样的问题。您有4个连接,但你将它们存储在一个变量。
键入"use strict";
你的源文件,以赶上这头:
ReferenceError: assignment to undeclared variable connection
Scoping: The general problem
你在这里处理的4个连接,但你可能没有作用域每个实例的方法。
大多数其他语言会告诉你创建一个类,使对象实例,并把一切包括connection
this
。这是一个不错的办法。在JS,你可以使用闭包来代替。但您至少还需要4个变量抱着4个连接,或者connections
的数组。那你看看上e.g。来自id
我提到的,它处理的连接。
此外,您try
/ catch
es不会赶上异步错误。相反,定义所有这些回调的,我坚决高度异步的WebRTC API打交道时建议using promises,甚至async/await。这使得作用域微不足道。例如。
const connections = [];
socket.on('ask', async ({user, id, sdp, fromSocket}) => {
try {
if (user != loggedUserID) return;
if (!connections[id]) {
connections[id] = getPeerConnection();
registerIceCandidate(connections[id]);
}
const connection = connections[id];
await connection.setRemoteDescription(JSON.parse(sdp));
await connection.setLocalDescription(await connection.createAnswer());
socket.emit('response', {sdp,
user: loggedUserID,
fromSocket: ownSocket,
toSocket: fromSocket});
} catch (err) {
console.log(err);
}
};
这样,错误处理是坚实的。
页面重载后连接多个peerConnections
我创建使用的WebRTC智能手机监控Web应用程序,以及信令服务器我使用socket.io。
当我发送流,我创建了接收该流的“观看”页面上的RTCPeerConnection对象。流送我在不同的页面。用户可以从智能手机连接多达4个数据流,因此,“观看”页面上有多达四个RTCPeerConnection对象。
流一旦收到自动从“发送”页面的报价出现,那么RTCPeerConnection对象被创建的“监视”页上,并连接到标准的WebRTC架构。
“发送”页面:
function onCreateOfferSuccess(sdp){
//console.log(sdp);
pc.setLocalDescription(new RTCSessionDescription(sdp));
console.log('ask');
socket.emit('ask', {"sdp":JSON.stringify(pc.localDescription),
"user": loggedUserID,
"fromSocket": ownSocket});
}
“观看”页面:
socket.on('ask', function(offer){
if (offer.user === loggedUserID){
TempDescriptions = JSON.parse(offer.sdp);
console.log(TempDescriptions)
currTransmiterSocket = offer.fromSocket;
console.log(currTransmiterSocket);
getStream();
}
function getStream(){
try {
setTimeout(function(){
console.log(time, 'getStream()');
connection = getPeerConnection();
connection.setRemoteDescription(
new RTCSessionDescription(TempDescriptions),
function() {
connection.createAnswer(gotDescription, function(error){
console.log(error)
});
}, function(error){
console.log(error)
});
}, getStreamDelay*3000)
getStreamDelay++
}
catch(err){
console.log(err);
}
};
我的Web应用程序需要在其中,当我们从“观看”页面退出,再次返回到它,所有以前包括流必须显示的功能。
为了实现这个功能,我用的是oniceconnectionstatechange方法。如果数据流中断,则执行iceRestart功能,创建一个与选项报价{iceRestart:真正}
“发送”页面:
var options_with_restart = {offerToReceiveAudio: false,
offerToReceiveVideo: true,
iceRestart: true};
function iceRestart(event){
try{
setTimeout(function(){
pc.createOffer(options_with_restart).then(onCreateOfferSuccess, onCreateOfferError);
},1000);
} catch(error) {
console.log(error);
问题是,当我重新启动了“观看”页面,所有页面“发送”发送到问一次。只有一个对象被连接时,尽管在一次会创建四个RTCPeerConnection对象(让我们假定用户发送四个数据流)。
我一直在努力解决这个问题了好几天。我试图设置在后续调用为出现在上面的代码getStream()函数增加的时间延迟,我试图执行getStream()函数前检查signallingState
连接,我试了其他几种方法,但没有一次成功。
如果你需要我的代码,以帮助某些部分,请写信。
编辑:
在“观看”页面gotDescription()方法。
function gotDescription(sdp) {
try{
connection.setLocalDescription(sdp,
function() {
registerIceCandidate();
socket.emit('response', {"sdp": sdp,
"user": loggedUserID,
"fromSocket": ownSocket,
"toSocket": currTransmiterSocket});
}, function(error){
console.log(error)
});
} catch(err){
console.log(err);
}
}
我想补充console.log
与RTCPeerConnection object
控制台输出:.png1
日志显示连接的signalingState
是“稳定的”,但是当我开发的对象,signalingState
等于“有远程要约”
like here
回答如下:取下TempDescriptions
全局变量,并通过SDP直接getStream(offer.sdp)
。
否则,你socket.on('ask', function(offer){
称为4倍,覆盖TempDescriptions
。然后3+秒后您的4 setTimeout
s打滚,都只是访问TempDescriptions
的最终值。
这可能是为什么只有一个RTCPeerConnection再所连接。
在一般情况下,使用时间延迟到单独的连接似乎是一个坏主意,因为它会减慢重新连接。相反,为什么不发送id
?例如。
socket.emit('ask', {id: connectionNumber++,
sdp: JSON.stringify(pc.localDescription),
user: loggedUserID,
fromSocket: ownSocket});
Update: Stop adding global variables to window
当你分配到一个这样的未声明的变量:
connection = getPeerConnection();
......它创造了全球上window
,例如window.connection
,和你有同样的问题。您有4个连接,但你将它们存储在一个变量。
键入"use strict";
你的源文件,以赶上这头:
ReferenceError: assignment to undeclared variable connection
Scoping: The general problem
你在这里处理的4个连接,但你可能没有作用域每个实例的方法。
大多数其他语言会告诉你创建一个类,使对象实例,并把一切包括connection
this
。这是一个不错的办法。在JS,你可以使用闭包来代替。但您至少还需要4个变量抱着4个连接,或者connections
的数组。那你看看上e.g。来自id
我提到的,它处理的连接。
此外,您try
/ catch
es不会赶上异步错误。相反,定义所有这些回调的,我坚决高度异步的WebRTC API打交道时建议using promises,甚至async/await。这使得作用域微不足道。例如。
const connections = [];
socket.on('ask', async ({user, id, sdp, fromSocket}) => {
try {
if (user != loggedUserID) return;
if (!connections[id]) {
connections[id] = getPeerConnection();
registerIceCandidate(connections[id]);
}
const connection = connections[id];
await connection.setRemoteDescription(JSON.parse(sdp));
await connection.setLocalDescription(await connection.createAnswer());
socket.emit('response', {sdp,
user: loggedUserID,
fromSocket: ownSocket,
toSocket: fromSocket});
} catch (err) {
console.log(err);
}
};
这样,错误处理是坚实的。