ios - WebRTC DataChannel 未在 iOS native 应用程序上打开

标签 ios objective-c iphone swift webrtc

我尝试在 iOS(10) 应用程序中使用 WebRTC 数据通道实现数据传输功能。 目前尝试通过本地传输重新实现官方示例( https://github.com/webrtc/samples/blob/gh-pages/src/content/datachannel/datatransfer/js/main.js ) 但我的数据通道从未打开...

这是我在 Swift 中的测试代码:

import Foundation
import WebRTC
import RealmSwift

class StreamingAPIWrapper {
    internal static let sharedInstance = StreamingAPIWrapper()

    var localConnection: RTCPeerConnection?
    var remoteConnection: RTCPeerConnection?
    var sendChannel: RTCDataChannel?
    var reciveChannel: RTCDataChannel?

    let dataChannelDelegate = MyRTCDataChannelDelegate()
    let factory = RTCPeerConnectionFactory()


    class func initStreamingAPI() {
        RTCInitializeSSL()
    }

    class func deinitStreamingAPI() {
        RTCCleanupSSL()
    }

    func connect() {

        let configuration = RTCConfiguration()
        configuration.bundlePolicy = .balanced
        let server = RTCIceServer(urlStrings: ["stun:stun.l.google.com:19302"])
        configuration.iceServers = [server]

        let mandatoryConstraints = ["OfferToReceiveAudio": "true", "OfferToReceiveVideo": "true"]
        let optionalConstraints = [ "DtlsSrtpKeyAgreement": "true", "RtpDataChannels" : "true", "internalSctpDataChannels" : "true"]
        let constraints = RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: optionalConstraints)

        let localConnectionDelegate = MyRTCPeerConnectionDelegate()
        localConnectionDelegate.onGenerateCandidate = { candidate in
            self.remoteConnection!.add(candidate)
        }
        localConnection =  factory.peerConnection(with: configuration,
                                                 constraints: constraints,
                                                 delegate: localConnectionDelegate)
        print("Created local connection")

        let remoteConnectionDelegate = MyRTCPeerConnectionDelegate()
        remoteConnectionDelegate.onGenerateCandidate = { candidate in
            self.localConnection!.add(candidate)
        }
        remoteConnection = factory.peerConnection(with: configuration,
                                                  constraints: constraints,
                                                  delegate: remoteConnectionDelegate)
        print("Created remote connection")

        localConnection?.offer(for: constraints, completionHandler: { (description1, _) in
            self.localConnection?.setLocalDescription(description1!, completionHandler: { _ in })
            self.remoteConnection?.setRemoteDescription(description1!, completionHandler: { _ in })
            self.remoteConnection?.answer(for: constraints, completionHandler: { (description2, error) in
                self.localConnection?.setRemoteDescription(description2!, completionHandler: { _ in })
                self.remoteConnection?.setLocalDescription(description2!, completionHandler: { _ in })
            })
        })

        let dataChannelConfiguration = RTCDataChannelConfiguration()
        dataChannelConfiguration.isOrdered = true
        sendChannel = localConnection?.dataChannel(forLabel: "test", configuration: dataChannelConfiguration)
    }
}

class MyRTCPeerConnectionDelegate: NSObject, RTCPeerConnectionDelegate {

    var onConnect: (() -> ())?
    var onGenerateCandidate: ((RTCIceCandidate) -> ())?
    var onOffer: (() -> ())?

    func peerConnection(_ peerConnection: RTCPeerConnection, didAdd stream: RTCMediaStream) {
        print("didAddStream")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didRemove stream: RTCMediaStream) {
        print("didRemoveStream")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didOpen dataChannel: RTCDataChannel) {
        print("didOpenDataChannel")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate) {

        onGenerateCandidate?(candidate)

        print("didGenerateCandidate")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didRemove candidates: [RTCIceCandidate]) {
        print("didRemoveCandidates")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState) {
        print("didChangeIceGatheringState")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceConnectionState) {
        print("didChangeIceConnectionState \(newState.rawValue)")
    }
    func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState) {
        print("didChangeSignalingState \(stateChanged.rawValue)")
    }
    func peerConnectionShouldNegotiate(_ peerConnection: RTCPeerConnection) {
        print("shouldNegotiate")
    }
}

class MyRTCDataChannelDelegate: NSObject, RTCDataChannelDelegate {
    func dataChannel(_ dataChannel: RTCDataChannel, didReceiveMessageWith buffer: RTCDataBuffer) {
        print("didReciveMessage")
    }
    func dataChannel(_ dataChannel: RTCDataChannel, didChangeBufferedAmount amount: UInt64) {
        print("didChangeAmount")
    }
    func dataChannelDidChangeState(_ dataChannel: RTCDataChannel) {
        print("didChangeDataChannel")
    }
}

这会生成输出:

Created local connection
Created remote connection
didChangeSignalingState 1
didChangeSignalingState 3
shouldNegotiate
didChangeIceGatheringState
didGenerateCandidate
didGenerateCandidate
didGenerateCandidate
didGenerateCandidate
didChangeSignalingState 0
didChangeIceConnectionState 1
didChangeSignalingState 0
didChangeIceConnectionState 1
didChangeIceGatheringState

我还尝试了 One to many webrtc 中的代码,用websockets服务器进行信令,但datachannel也没有打开。 我做错了什么?

最佳答案

根据提供的代码,您将在创建报价后创建数据通道。

将dataChannel添加到peerConnection后创建Offer,
以便提供/应答 SDP 将包含数据通道详细信息。

RtpDataChannels 已弃用,因此无需在约束中指定。

关于ios - WebRTC DataChannel 未在 iOS native 应用程序上打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44559253/

相关文章:

ios - 具有3D旋转的CAEmitterCell

ios - Xcode6 Interface Builder 约束不拉伸(stretch) subview

ios - 奇怪的错误 - 对象变为零

html - 如何在 TTTAttributedLabel 中将 HTML anchor 设为可点击链接?

android - 介于IOS和安卓之间的谷歌

ios - 在 deinit 中清除强引用是否是正确的模式?

ios - 将数据返回给第一个 ViewController

ios - 使用 URL 在 Xcode 中修改 UIImageview

iphone - 同一库的重复符号 XCode 重复库?

iphone - iOS开发中如何处理自定义事件?