Сбой соединения Kurento WebRTC в ~ 30% случаев - PullRequest
0 голосов
/ 21 января 2019

Я провел дни, выискивая проблему с подключением без какой-либо удачи. Я пытаюсь реализовать относительно простой one2one Call с Kurento.

Ниже вы найдете журнал отладки Куренто для случая, когда соединение могло быть установлено, и случая, когда соединение не удалось.

Если вам нужны дополнительные журналы (например, клиенты, сервер сигнализации, tcpdumps или журналы трассировки Kurento, просто дайте мне знать, и я предоставлю!)

Любая помощь или новый вклад приветствуется!

Описание проблемы:

Примерно в 30% случаев соединение WebRTC не может быть установлено. К сожалению, мне не хватает какого-либо паттерна, когда Соединение может быть установлено, а когда нет, оно кажется совершенно случайным. Я нахожусь в той же сети, использую те же устройства, использую тот же сервер TURN, использую тот же протокол сигнализации, но в 30% случаев соединение не может быть установлено.

Когда я запускаю приложение локально, кажется, что оно работает намного надежнее, соединение может быть установлено почти в 100% случаев (или, может быть, даже в 100% случаев, я столько раз тестировал, что терял трек). Я настроил инфраструктуру локально с помощью Docker и запускаю различные контейнеры (TURN, Kurento, Signaling) в отдельных сетях, чтобы имитировать производственное развертывание.

Мы наблюдаем такое же поведение в нашей среде разработки и производства. В нашей среде разработки у нас абсолютно нет брандмауэров, так что, похоже, это не проблема.

Что я пытался найти причину проблемы:

В основном я сравнивал журналы дел, которые работали, и дел, которые не работали, но я не смог найти какой-либо существенной разницы между ними, которая могла бы указать мне на проблему.

Я протестировал соединение WebRTC через сервер TURN (с Firefox и флагом force_relay) и напрямую через Kurento, но в обоих случаях соединение не удается в ~ 30% случаев.

Я попытался отфильтровать всех кандидатов ICE, которые не являются кандидатами на ретрансляцию.

Я прослушал трафик между нашим сигнальным сервером (который также контролирует Kurento) и Kurento, чтобы увидеть какие-либо различия в обмене сообщениями JSON RPS, но они, по сути, одинаковы.

Я проверил наш сервер STUN и TURN с помощью этого инструмента: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/, и я получил как серверные рефлексивные, так и ретрансляционные кандидаты, которые выглядят правильно

Я обнаружил трафик от клиентов по успешному и неудачному соединению, но смог заметить существенную разницу

Я упростил медиа-конвейер Kurento (без записи, без хабов), но поведение такое же

Я использовал разные браузеры (Chrome, Firefox и нативная реализация iOS), но поведение такое же

Kurento отладки журналов случая, когда соединение может быть установлено:

https://gist.github.com/omnibrain/2bc7ad54f626d278d3c8bac29767ac4c

Журналы отладки Куренто для случая, когда соединение НЕ МОЖЕТ быть установлено:

https://gist.github.com/omnibrain/f7caee04a5c6d77ea22a9ccfa95dd825

Ответы [ 2 ]

0 голосов
/ 24 января 2019

После нескольких дней отладки и почти безумия мы наконец нашли причину нашей проблемы:

Мы использовали Swift-клиент Socket.IO и реализацию Socket.IO на сервере Java Netty Socket.IO.Клиент (iOS) использует длинный опрос для связи с сервером (Java).Оказывается, что сервер Netty Socket.IO выполняет URL-декодирование полезной нагрузки длинного опроса клиента Swift Socket.IO, но клиент Swift Socket.IO фактически не кодирует его URL-адресом.Это означало, что каждое «+», которое было отправлено с клиента Swift Socket.IO, было заменено на «» (пробел) на сервере.Почему это проблема?Потому что предложение SDP клиента содержит уфраг, который может содержать знак плюс!Поэтому, если SDP содержал «+», он был заменен на сервере пробелом, что приводило к сбою эхо-запросов STUN из-за невозможности проверки целостности сообщения.

0 голосов
/ 24 января 2019

Глядя на ваши следы, ваш рабочий случай выбирает кандидата 10 , затем выбирает кандидата 7, нерабочий выбирает только кандидата 10.

kurento_logs_webrtc_working.txt

New candidate pair selected, local: 'candidate:10 1 UDP 335544831 10.10.36.134 50589 typ relay raddr 172.19.0.2 rport 9', remote: 'candidate:3993072200 1 UDP 41885695 10.10.36.134 53894 typ relay', stream_id: '1', component_id: 1
...
New candidate pair selected, local: 'candidate:7 1 UDP 1677722111 10.10.36.131 46842 typ srflx raddr 172.19.0.2 rport 46842', remote: 'candidate:266015763 1 UDP 2122260223 10.10.1.57 55125 typ host', stream_id: '1', component_id: 1

kurento_logs_webrtc_NOT_working.txt

new candidate pair selected, local: 'candidate:10 1 UDP 335544831 10.10.36.134 51280 typ relay raddr 172.19.0.2 rport 9', remote: 'candidate:3993072200 1 UDP 41885695 10.10.36.134 51287 typ relay', stream_id: '1', component_id: 1

Сначала я подумал, что вы повторно используете старых кандидатов, но порты изменились.Смена браузеров может изменить номера кандидатов, я не ожидал, что они будут детерминированными между запусками, поэтому мне пришлось посмотреть дважды.

Есть одно небольшое отличие от журнала - то, что нерабочий IceComponentStateChanged меняется наconnecting после появляется candidate:266015763, а не раньше.Не знаю, значимо ли это.

Общие замечания:

В прошлом, когда у нас было несколько категорий проблем:

  • на стороне клиента мытеряли кандидатов ICE - некоторые из кандидатов были отправлены до того, как мы были готовы, поэтому нам нужно было поставить их в очередь.IIRC, возможно, есть некоторые кандидаты в предложении SDP (или ответ, извините, это было давно), поэтому ваши слушатели должны быть готовы, прежде чем вы начнете.
  • мы отправляли кандидатов OLD - неправильный элемент воспроизведения использовался всервер сигнализации для предложения кандидатов клиентам, и они больше не действительны.

Я бы порекомендовал вам использовать Chrome с chrome: // webrtc-internals , чтобы помочь.Проблемы кандидатов в ICE видны в webrtc-internals, поскольку вы можете видеть конечный автомат, проходящий через его состояние.В нашем рабочем случае гораздо больше переходов, чем в нерабочих случаях.

Добавление прослушивателей на стороне клиента для трех ледовых событий также полезно:

this.peer.peerConnection.oniceconnectionstatechange = this.logloglog.bind(this, this.peer.peerConnection);
this.peer.peerConnection.onicegatheringstatechange = this.logloglog.bind(this, this.peer.peerConnection);
this.peer.peerConnection.onsignalingstatechange = this.logloglog.bind(this, this.peer.peerConnection);

Это позволяет увидеть, как происходит согласование.собирается, но в основном то, что в chrome: //webrtc-internals.

Последнее примечание, это то, что я использовал в разделе ведения журнала /etc/default/kurento-media-server:


# ICE debug logging: uncomment to enable in KMS and in the 3rd-party library 'libnice'
# - Note: This can get very verbose, log size will explode in the long term
#export GST_DEBUG="$GST_DEBUG,kmsiceniceagent:5,kmswebrtcsession:5,webrtcendpoint:4"
export G_MESSAGES_DEBUG="libnice,libnice-stun"
export NICE_DEBUG="$G_MESSAGES_DEBUG"

Я не помню, были ли они лучше, чем вы использовали, но я добавлю это.

...