swift - GoogleWebRTC 挂起(卡住)swift native 应用程序(OpenVidu)中的主线程

标签 swift multithreading webrtc webrtc-ios openvidu

我们的 iOS (swift) native 应用程序与 OpenVidu 实现(在引擎盖下使用 GoogleWebRTC)存在挂起问题(应用程序由于主线程锁定而卡住)。需要的具体条件:需要加入现有的房间,并且至少有 8 名参与者已经在直播。有 6 名参与者时,这种情况发生的频率较低,而且在 6 人以下时几乎不会发生。如果参与者一个一个加入,它不会挂起,只有当您加入房间时所有其他参与者都已经在流式传输。这表明问题的并发性质。
GoogleWebRTC 挂起 setRemoteDescription称呼:

func setRemoteDescription(sdpAnswer: String) {
    let sessionDescription: RTCSessionDescription = RTCSessionDescription(type: RTCSdpType.answer, sdp: sdpAnswer)
    self.peerConnection!.setRemoteDescription(sessionDescription, completionHandler: {(error) in
        print("Local Peer Remote Description set: " + error.debugDescription)
    })
}
main thread hangs
正如你在上面的截图中看到的,主线程卡在 __psynch_cvwait 上。 .似乎没有任何其他线程被锁定。 锁永远不会释放 让应用程序完全卡住。
为了解决这个问题,我尝试了以下方法:
  • 我将 OpenVidu 信号服务器处理(RPC 协议(protocol))从主线程移动到单独的线程中。这只会导致锁定现在发生在我创建的单独线程之一中。它现在不会阻止 UI,但会阻止 OV 信号。问题仍然存在。
  • 我添加了锁以同步(一个接一个)处理每个信令事件(参与者加入事件、发布视频等)。这也无济于事(它实际上使情况变得更糟)。
  • 我没有使用 Cocoapods 的 GoogleWebRTC v. 1.1.31999,而是下载了最新的 GoogleWebRTC 源代码,在发布配置中构建它们,然后 included into my project .这对解决问题没有帮助。

  • 任何建议/意见将不胜感激。
    谢谢!
    编辑 1:signaling_threadworker_thread两者都在等待同一种锁中的东西。在锁定的那一刻,他们都没有执行我的任何代码。
    我还尝试在 GoogleWebRTC 的调试版本中运行,在这种情况下不会发生锁定,但一切都运行得更慢(这对于调试来说是可以的,但我们不能在生产中使用它)。
    enter image description here
    编辑 2:
    我试图添加额外的 DispatchQueueoffersetLocalDescription回调,但这没有任何改变。该问题仍然可以很好地重现(几乎 100% 的时间,如果我有 8 个参与者有流):
        self.peerConnection!.offer(for: constrains) { (sdp, error) in
            DispatchQueue.global(qos: .background).async {
    
                guard let sdp = sdp else {
                    return
                }
    
                self.peerConnection!.setLocalDescription(sdp, completionHandler: { (error) in
                    DispatchQueue.global(qos: .background).async {
                        completion(sdp)
                    }
                })
            }
        }
    

    最佳答案

    WebRTC Obj-C API 可以从任何线程调用,但大多数方法调用被传递到 WebRTC 的内部线程,称为 signalling thread .
    此外,回调/观察者如 SetLocalDescriptionObserverInterfaceRTCSetSessionDescriptionCompletionHandlersignaling thread 上从 WebRTC 调用.
    看截图,好像是信令线程当前被阻塞了,不能再调用WebRTC API调用了。
    因此,为了避免死锁,最好创建自己的线程/dispatch_queue并处理回调。

    https://webrtc.googlesource.com/src/+/0a52ede821ba12ee6fff6260d69cddcca5b86a4e/api/g3doc/index.md
    https://webrtc.googlesource.com/src/+/0a52ede821ba12ee6fff6260d69cddcca5b86a4e/api/g3doc/threading_design.md
    详情。

    关于swift - GoogleWebRTC 挂起(卡住)swift native 应用程序(OpenVidu)中的主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67634075/

    相关文章:

    ios - 在 Swift SpriteKit 中使用 SKLabelNode 作为父级创建一个按钮

    swift - 如何将 ViewController 添加到 UITabBarController 并以编程方式加载它?

    在 Safari 浏览器中使用 webrtc 进行音频聊天?

    javascript - 一对多麦克风流媒体实现

    ios - 为什么我的 UILabel 没有截断?

    swift - AudioKit - 绘制文件的完整波形

    c# - ReaderWriterLockSlim 或 Lock

    java - JEdi​​torPane图片异步下载问题

    Python 线程 - 参数数量错误

    javascript - RTCMultiConnection 返回当前流