本文介绍了WebRTC连接在本地网络之外无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有以下WebRTC双向视频和音频流的设置:

手机

使用Google WebRTC实现Java包装的Android应用程序。已测试这两个库:

implementation 'org.webrtc:google-webrtc:1.0.+'
implementation 'com.github.webrtc-sdk:android:92.4515.03' // https://github.com/webrtc-sdk/android

RPI

WebRTC plugin的GStreamer基于gst-examples,并做了一些修改。

浏览器

还略微修改了gst-examplesJava脚本实现。它基于本机浏览器WebRTC支持。

转弯

CoTurn服务器在Docker中工作(coturn/coturn)。

问题

当从RPI调用到浏览器或从移动设备调用到浏览器时,无论是在本地网络还是通过互联网(通过TURN服务器),一切都运行正常。然而,当试图通过互联网连接RPI和Android设备时,它被卡住了(本地网络也可以)。设备相互通信,协商SDP和ICE候选,TURN服务器正确打开连接,但没有音频/视频。

查看Android日志时,第一个区别是没有触发ICE连接更改:

PeerConnectionObserver: onStandardizedIceConnectionChange: CHECKING

PeerConnectionObserver: onConnectionChange: CONNECTING

这发生在ICE考生交换之前。发送ICE候选后,不会与其他设备进行进一步通信,也不会触发任何状态更改。例如,在工作案例中如下所示:

PeerConnectionObserver: onSelectedCandidatePairChanged: org.webrtc.CandidatePairChangeEvent@a856333
PeerConnectionObserver: onStandardizedIceConnectionChange: CONNECTED
PeerConnectionObserver: onConnectionChange: CONNECTED
PeerConnectionObserver: onIceConnectionChange CONNECTED
[Internal data channel]: onStateChange
PeerConnectionObserver: onDataChannel org.webrtc.DataChannel@b76f6f0
[External data channel]: onStateChange

转弯日志完全没有显示任何可疑之处。

如有任何提示或帮助进一步调查此问题,我将不胜感激。

编辑:

在@RSATom的建议下,我们更仔细地查看了正在发送的ICE和SDP消息,没有发现任何丢弃。对于通过互联网和本地的移动-RPI通信,SDP是相同的。唯一的区别是随机生成的ID。冰块也没有太大区别。它对于第一个发送者(要约者)是相同的,而对于回答者则略有不同,因为它包含话轮详细信息:

通过互联网

video0:0:candidate:228040959 1 udp 2122260223 10.111.215.156 53556 typ host generation 0 ufrag 3SNh network-id 3 network-cost 900::UNKNOWN  
video0:0:candidate:559267639 1 udp 2122202367 ::1 48566 typ host generation 0 ufrag 3SNh network-id 2::UNKNOWN      
video0:0:candidate:1510613869 1 udp 2122129151 127.0.0.1 41279 typ host generation 0 ufrag 3SNh network-id 1::UNKNOWN   
video0:0:candidate:1876313031 1 tcp 1518222591 ::1 46051 typ host tcptype passive generation 0 ufrag 3SNh network-id 2::UNKNOWN 
video0:0:candidate:344579997 1 tcp 1518149375 127.0.0.1 60259 typ host tcptype passive generation 0 ufrag 3SNh network-id 1::UNKNOWN    
video0:0:candidate:842163049 1 udp 1686052607 31.0.91.196 6742 typ srflx raddr 10.111.215.156 rport 53556 generation 0 ufrag 3SNh network-id 3 network-cost 900:stun:3.70.23.20:3478:UNKNOWN    
video0:0:candidate:593469510 1 udp 41885439 172.31.0.169 14307 typ relay raddr 31.0.91.196 rport 6742 generation 0 ufrag 3SNh network-id 3 network-cost 900:turn:3.70.23.20:3478?transport=udp:UNKNOWN

通过本地WiFi

video0:0:candidate:2858526953 1 udp 2122260223 192.168.0.21 38123 typ host generation 0 ufrag rwx/ network-id 3 network-cost 10::UNKNOWN
video0:0:candidate:559267639 1 udp 2122202367 ::1 52058 typ host generation 0 ufrag rwx/ network-id 2::UNKNOWN
video0:0:candidate:1510613869 1 udp 2122129151 127.0.0.1 39469 typ host generation 0 ufrag rwx/ network-id 1::UNKNOWN
video0:0:candidate:842163049 1 udp 1686052607 178.235.191.135 13607 typ srflx raddr 192.168.0.21 rport 38123 generation 0 ufrag rwx/ network-id 3 network-cost 10:stun:3.70.23.20:3478:UNKNOWN
video0:0:candidate:1876313031 1 tcp 1518222591 ::1 51551 typ host tcptype passive generation 0 ufrag rwx/ network-id 2::UNKNOWN
video0:0:candidate:344579997 1 tcp 1518149375 127.0.0.1 41007 typ host tcptype passive generation 0 ufrag rwx/ network-id 1::UNKNOWN
video0:0:candidate:593469510 1 udp 41885439 172.31.0.169 13744 typ relay raddr 178.235.191.135 rport 13607 generation 0 ufrag rwx/ network-id 3 network-cost 10:turn:3.70.23.20:3478?transport=udp:UNKNOWN

ICE消息的顺序似乎未保持。

完整日志的差异(互联网左,本地右):https://www.diffchecker.com/elEA6rkJ

ICE消息差异:https://www.diffchecker.com/C1TzPcMm

编辑2:

我错过了一些日志不存在。通过互联网连接的完整日志差异(工作与不工作)可用here。有几点不同:

  1. 无效连接遗漏了许多通知连接创建和保持连接的日志,但仍显示以下内容:
tag: basic_ice_controller.cc 
message: (line 541): Sorting 0 available connections
  1. 对于无效连接,RTP SSRCtransport_cc已关闭
  2. GStreamer使用流别名(如video0audio0),这会导致ICE候选错误,如下所示:
ReadyToUseRemoteCandidate: Invalid candidate. Mid 0 specified but no media section with that mid found.
  1. 存在要转换的失败的TCP请求:
LS_INFO
tag: turn_port.cc 
message: (line 375): Port[31f33800:video0:1:0:relay:Net[lo:127.0.0.x/8:Loopback:id=1]]: Trying to connect to TURN server via tcp @ sicdev-turn.ddns.net:3478

LS_INFO
tag: android_network_monitor.cc 
message: (line 422): Find network handle.

LS_WARNING
tag: android_network_monitor.cc 
message: (line 307): BindSocketToNetwork unable to find network handle for addr: 127.0.0.x ifname: lo

LS_VERBOSE
tag: physical_socket_server.cc 
message: (line 207): Binding socket to loopback address failed; result: -3

LS_ERROR
tag: basic_packet_socket_factory.cc 
message: (line 186): TCP connect failed with error 22

LS_ERROR
tag: turn_port.cc 
message: (line 379): Failed to create TURN client socket

推荐答案

如果是你的话我会怎么做:

  1. 添加create-offer/create-answer/set-offer/set-answer请求的日志
  2. 添加每个传入/传出候选冰块的日志和end-of-candidates

然后查看日志并检查:

  1. 所有Ice候选人真的是在向对方传递信息。
  2. end-of-candidates在所有其他候选冰块之后交付。
  3. Set-Offer/Set-Answer之后的冰块候选人
  4. 双方都可以访问您的STUN/TURN服务器(使用https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/)
  5. 您已在STUN/TURN服务器上配置了IPv6(某些GSM提供商根本不能使用IPv4)

更新%1

根据日志,您的Android设备使用的是IPv4。因此,现在没有必要担心IPv6。关于end-of-candidates-您可以查看我是如何使用webrtcbinhere生成它的。Android的类似代码:

    private val connectionObserver = object: PeerConnection.Observer {
        // ... some overrides skipped ...

        override fun onIceCandidate(candidate: IceCandidate) {
            Log.d(TAG, "onIceCandidate "$candidate"")
        }
        override fun onIceGatheringChange(state: PeerConnection.IceGatheringState) {
            Log.d(TAG, "IceGathering state: $state")
            if(state == PeerConnection.IceGatheringState.COMPLETE) {
                Log.d(TAG, "onIceCandidate "a=end-of-candidates"")
            }
        }

        // ... some overrides skipped ...
    }

还请检查以下内容:

在Android上

  1. 您真的是在为每个即将到来的Ice候选对象调用org.webrtc.PeerConnection.addIceCandidate
  2. org.webrtc.PeerConnection.setRemoteDescription调用
  3. 之后

在RPI上

  1. 您真的为每个即将到来的Ice候选对象调用g_signal_emit_by_nameWITHadd-ice-candidate

更新%2

我注意到您的中继冰候选指向内网IP(172.31.0.169)。这可能意味着您的配置错误。服务器。


更新%3

请与https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/确认relay您的两面都有有效的IP。

这篇关于WebRTC连接在本地网络之外无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 10:09