Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android WebRTC数据通道始终为空,不发送ICE候选_Java_Android_Kotlin_Websocket_Webrtc - Fatal编程技术网

Java Android WebRTC数据通道始终为空,不发送ICE候选

Java Android WebRTC数据通道始终为空,不发送ICE候选,java,android,kotlin,websocket,webrtc,Java,Android,Kotlin,Websocket,Webrtc,我正在尝试创建一个Android应用程序,它使用WebRTC数据通道进行数据交换。我要发送的数据是基本字符串。诚然,这是我第一次看WebRTC,所以我对细节有点模糊。我的问题是,每当我尝试创建数据通道时,它总是空的,ICE候选请求似乎不会与信令服务器交换。我从开始并修改它,不交换视频,而是创建一个数据通道 我浏览了许多其他答案,但绝大多数都与浏览器中的WebRTC有关,而且数据通道示例在开始时很少出现。我还通过C++中的谷歌铬源代码实现来查看WebRTC,看看是否有什么可以学习但没有运气。 我的

我正在尝试创建一个Android应用程序,它使用WebRTC数据通道进行数据交换。我要发送的数据是基本字符串。诚然,这是我第一次看WebRTC,所以我对细节有点模糊。我的问题是,每当我尝试创建数据通道时,它总是空的,ICE候选请求似乎不会与信令服务器交换。我从开始并修改它,不交换视频,而是创建一个数据通道

我浏览了许多其他答案,但绝大多数都与浏览器中的WebRTC有关,而且数据通道示例在开始时很少出现。我还通过C++中的谷歌铬源代码实现来查看WebRTC,看看是否有什么可以学习但没有运气。 我的代码如下

webrtcsactivity.kt

//忽略导入
类WebRTCAvity:AppCompatActivity(){
专用lateinit var rtcClient:rtcClient
私有lateinit var信号客户端:信号客户端
private val sdpObserver=对象:AppSdpObserver(){
覆盖创建成功的乐趣(p0:SessionDescription?){
super.onCreateSuccess(p0)
signalingclient.send(p0)
println(“对字符串的会话描述:+p0.toString())//打印
}
}
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity\u web\u rtc)
//省略相机许可检查
OnCameraPermissionGrated()的
}
私人娱乐onCamerapermissiongrated(){
rtcClient=rtcClient(
应用
对象:PeerConnectionObserver(){
覆盖IceCandidate(p0:ICEScandidate?){
super.onIceCandidate(p0)
signalingclient.send(p0)
rtcClient.addIceCandidate(p0)
println(“ice候选字符串:+p0.toString())//不打印
}
覆盖数据通道(p0:数据通道?){
超级数据通道(p0)
}
}
)
signallingClient=signallingClient(createSignallingClientListener())
调用_button.setOnClickListener{//屏幕上的按钮启动发送报价
rtcClient.call(sdpObserver)
}
}
private fun CreateSignalingClientListener()=对象:SignalingClientListener{
覆盖已建立的连接(){
println(“建立连接”)
}
override fun onOfferReceived(描述:SessionDescription){
rtcClient.onRemoteSessionReceived(说明)
rtcClient.answer(sdpObserver)
println(“收到报价”)//打印
}
覆盖已收到的答复(说明:SessionDescription){
rtcClient.onRemoteSessionReceived(说明)
println(“收到答复”)//打印
}
覆盖已接收的ICeCandidateReceived(ICEScandidate:ICEScandidate){
rtcClient.addIceCandidate(ICEScandidate)
println(“信令客户端ice候选者”)//不打印
}
}
RTCClient.kt

//忽略导入
类RTCClient(
上下文:应用程序,
观察者:PeerConnection.观察者
) {
初始化{
initPeerConnectionFactory(上下文)
}
private val iceServer=listOf(
PeerConnection.IceServer.builder(“stun:stun1.l.google.com:19302”)
.createIceServer()文件
)
惰性{buildPeerConnectionFactory()}的私有val peerConnectionFactory
惰性{buildPeerConnection(observer)}的私有值peerConnection
private fun initPeerConnectionFactory(上下文:应用程序){
val options=PeerConnectionFactory.InitializationOptions.builder(上下文)
.setEnableInternalTracer(真)
.createInitializationOptions()
PeerConnectionFactory.initialize(选项)
}
private fun Build PeerConnectionFactory():PeerConnectionFactory{
返回PeerConnectionFactory
.builder()
.setOptions(PeerConnectionFactory.Options().apply{
disableEncryption=true
disableNetworkMonitor=true
})
.createPeerConnectionFactory()
}
private fun buildPeerConnection(观察者:PeerConnection.observer)=peerConnectionFactory.createPeerConnection(
iceServer,
观察者
)
private fun PeerConnection.call(sdpObserver:sdpObserver){
val约束=MediaConstraints()。应用{
//mandatory.add(MediaConstraints.KeyValuePair(“OfferToReceiveAudio”,“true”)//这样,ICE候选请求实际上是发送的,但我没有使用音频,所以我认为它不需要在这里
mandatory.add(MediaConstraints.KeyValuePair(“DtlsSrtpKeyAgreement”,“true”)//在某个地方的答案上看到了此约束,我无法判断是否需要它
}
createOffer(对象:SdpObserver by SdpObserver{
重写创建成功的乐趣(描述:SessionDescription?){
setLocalDescription(对象:SdpObserver{
覆盖乐趣设置失败(p0:字符串?){
}
覆盖有趣的onSetSuccess(){
}
覆盖创建成功的乐趣(p0:SessionDescription?){
}
重写onCreateFailure(p0:String?){
}
},desc)
sdpObserver.onCreateSuccess(desc)
}
},约束条件)
}
私密趣味对等连接。应答(sdpObserver:sdpObserver){
val约束=