我尝试在 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/