如何正确关闭一个PeerConnection

5

我有一个使用webrtc的voip应用程序。最近我重新设计了很多代码,使信令更加一致。现在唯一的大问题是,当我关闭peerconnection时,应用程序会在一些内部OpenGL代码上崩溃。我使用以下代码来关闭连接:

[peerConnection removeStream:lms];
[peerConnection close];
peerConnection = nil;

我之前使用的代码删除了与webrtc相关的很多内容,但是我发现许多对象可以重用,并且只需要在应用程序启动时进行初始化。我需要做什么来确保应用程序在我结束通话时不会崩溃?

  • 我正在使用版本号为6825
  • 我正在使用Xcode 5.1.1
  • 在第四代iPad上测试,运行iOS7

编辑:
我将上述代码移至后台线程,现在它不再崩溃。但是现在,在几次呼叫后,我的日志文件会被以下行刷屏(每秒大约3或4次):

Failed to make complete framebuffer object 8cdd

当出现这种情况时,以下是日志历史记录的最后一部分:

2014-10-14 11:53:45.045 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)2
2014-10-14 11:53:45.046 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)3
2014-10-14 11:53:50.732 BeeldZorgApp[4912:3903] peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)<RTCPeerConnection: 0x157c9640>
2014-10-14 11:53:50.742 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)6
2014-10-14 11:53:50.743 BeeldZorgApp[4912:3903] peerConnection signalingStateChanged:(RTCSignalingState)5
2014-10-14 11:53:59.955 BeeldZorgApp[4912:3903] peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)<RTCPeerConnection: 0x19a62e30>
2014-10-14 11:53:59.980 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.028 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.091 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.119 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.152 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.185 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.218 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.252 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.284 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.319 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.352 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.384 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.417 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.451 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.486 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.518 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.552 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
3个回答

10

原来发现在离开视图控制器之前,需要从其superview中移除RTCEAGLVideoViews。现在我使用以下代码进行清理:

//these are both RTCEAGLVideoViews
[remoteVideoView removeFromSuperview];
[localVideoView removeFromSuperview];
[peerConnection removeStream:lms];
[peerConnection close];
peerConnection = nil;

希望我能因为你的那句话“我将上面的代码移到了后台线程,现在不再崩溃”而感激你1000次... :) - Ankur

2
如果将peerConnection设置为nil,当您再次尝试呼叫某人(第二次)时,视图控制器会出现关于此的错误。 我认为应该将PeerConnectionFactory静态类中的peerConnection值设置为nil。因此,当您调用工厂的peerConnectionWithConfiguration方法时,会得到nil值。 我的建议是使用close()方法就足够了(使用Swift):
self.remoteVideoView.removeFromSuperview()
self.localVideoView.removeFromSuperview()
self.peerConnection.removeStream(self.mediaStream)
self.peerConnection.close()

PS:我正在使用最新版本的webrtc库。


你不能重复使用peerconnection对象本身(变量可以,但实例不行),你必须创建一个新的。那么为什么要将对象保留在内存中呢?只调用close()可能足以使其工作,但这并不是很干净。 - Kevin
请纠正我如果我错了,但我在等待iOS在我解除视图控制器时删除所有变量。因为它们是变量并且依赖于实例。根据您的说法,在删除实例之前,我们必须将所有变量设置为nil。@Kevin - Sercan özen
这取决于您是否使用ARC,我在我的webrtc实现中没有使用,因此我手动清除所有内容。 - Kevin

0

在我的代码中,我做了这样的事情。我遇到了一个问题,即在结束通话后,麦克风黄点仍然可见。这段代码解决了所有问题:

if let capturer = self.videoCapturer as? RTCCameraVideoCapturer{
        capturer.stopCapture()
    }
    
    self.screenCapturer = nil
    
    if(self.peerConnection != nil) {
        for mStream in self.peerConnection!.localStreams {
            peerConnection?.remove(mStream)
        }
    }
    
    for participant in remoteParticipants {
        participant.peerConnection?.close()
    }
    
    self.peerConnection?.close()
    self.webSocketListener?.endConnection()
    
    self.delegate = nil
    self.remoteParticipants.removeAll()
    self.webSocket = nil
    localVideoTrack = nil
    remoteVideoTracks.removeAll()
    localDataChannel = nil
    remoteDataChannel = nil
    self.peerConnection = nil
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接