最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

页面重载后连接多个peerConnections

IT培训 admin 2浏览 0评论

页面重载后连接多个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.logRTCPeerConnection object

控制台输出:.png1

日志显示连接的signalingState是“稳定的”,但是当我开发的对象,signalingState等于“有远程要约”

like here

回答如下:

取下TempDescriptions全局变量,并通过SDP直接getStream(offer.sdp)

否则,你socket.on('ask', function(offer){称为4倍,覆盖TempDescriptions。然后3+秒后您的4 setTimeouts打滚,都只是访问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 / catches不会赶上异步错误。相反,定义所有这些回调的,我坚决高度异步的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.logRTCPeerConnection object

控制台输出:.png1

日志显示连接的signalingState是“稳定的”,但是当我开发的对象,signalingState等于“有远程要约”

like here

回答如下:

取下TempDescriptions全局变量,并通过SDP直接getStream(offer.sdp)

否则,你socket.on('ask', function(offer){称为4倍,覆盖TempDescriptions。然后3+秒后您的4 setTimeouts打滚,都只是访问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 / catches不会赶上异步错误。相反,定义所有这些回调的,我坚决高度异步的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);
  }
};

这样,错误处理是坚实的。

发布评论

评论列表 (0)

  1. 暂无评论