SIP через WebRTC на продакшне. Как мы к этому шли и какие проблемы решали

    Доброго времени суток всем!

    Я уже писал о своем опыте работы с WebRTC тут, но учитывая то, что в последнее время всё больше статей на эту тему появляется на хабре и то, что я давно хотел написать о том, как мы добились стабильной работы SIP телефонии через WebRTC на продакшне, я решил написать через что мы прошли.

    А прошли мы через многое: боль, панику, истерики, кучу матов и пожелания добра мейнтейнерам.
    Сейчас же это всё в прошлом. Мы избавились от всех костылей, которые мы делали, и сделали так, чтобы операторы звонили и всё работало стабильно.
    В статье, я как можно подробнее описал все проблемы, с которыми мы сталкивались, используя как можно меньше кода и конфигов.

    Кому интересно, прошу под кат.


    Предыстория:



    Мы писали софт для нашего колцентра и у нас была возможность делать его так, чтобы не заморачиватся насчет кроссбраузерности.

    На первоначальном этапе мы выбрали:

    • SIPml5 — как фронтенд либу
    • Asterisk — как бекенд
    • Google Chrome — как браузер. где всё это должно работать.


    За весь путь мы использовали:

    • Asterisk и SIPml
    • Asterisk + Webrtc2sip и SIPml
    • Freeswitch + SIPml
    • Freeswitch + JSSIP


    Не много о софтах:


    • Asterisk — всем известный soft-switch. Делается умельцами из Digium
    • Freeswitch — Soft-switch. Oдин из конкурентов Asterisk
    • SIPml5 — позиционируют себя как первый HTML5 SIP клиент. Javascript либа для работы с SIP.
    • JSSIP — легковесная Javascript либа для работы с SIP.
    • WebRTC2SIP — SIP и медиа гейтвей


    asterisk + sipml


    Начало пути. Нам надо было добится рабочей схемы и позвонить с браузера себе на мобильный.
    Asterisk патчили и компиляли по этому мануалу
    После того, как мы этого добились, мы начали тестировать.

    В процессе тестирования мы обнаружили:

    1. «Белый шум» при звонке
    2. Тишина до 10 секунд при входящем звонке.
    3. Входящий звонок скидывал исходящий.


    1. «Белый шум» был исправлен с помощью этого патча
    2. Проблему со скидыванием звонка удалось решить, с помощью настройки пользователя на Asterisk. Был выставлен лимит 1 звонок на пользователя.
    3. Проблему с 10 секундной тишиной решили исправить, обновив Asterisk до версии 1.6.

    И вот мы уже на 1.6 астериске. После беглого тестирования стало понятно:

    • «Белого шума» нет
    • Нативная поддержка вебсокетов


    Но появились следующие проблемы:

    1. Астериск падает при входящем звонке на определении RTP
    2. Тишина до 10 секунд осталась.


    Проблему с тишиной удалось решить тем, что мы отказались от STUN в SIPml5. Ситуация стала лучше, но не исчезла полностью.
    Решили попробовать WebRTC2SIP, как советовали мейнтейнеры SIPml5.

    asterisk + webrtc2sip + sipml



    На этом этапе у нас следующая ситуация:

    • Нет старых багов
    • Asterisk не падает
    • Тишина исчезла.


    НО! Появилась проблема в том, что WebRTC2SIP не готов для продакшна. Он постоянно падал с разной периодичностью.
    Судя по багрепорту в треккере о проблеме знали уже полгода, когда мы стали его использовать. Поняв, что от мейнтейнеров ничего не добится, стали проблему решать сами.

    // А тем временем проект уже в продакшне.

    Потратив неделю и так не решив проблему, сделали рестартер webrtc2sip и стали смотреть в сторону Freeswitch.

    freeswitch + sipml



    В сторону Freeswitch я смотрел еще тогда, когда вышла Бета версия 1.4 с поддержкой WebRTC.

    На этом этапе стало понятно, что ни от Asterisk, ни от Doubango Telecom помощи ждать не стоит и нужно как-то решать проблему самим.

    На начальных этапах работы с Freeswitch очень выносят мозг xml конфиги, но когда привыкаешь к ним, то жить без них не можешь.
    После того, как мы добились от него работы в условиях, приближенных к продакшну, протестировали его, и поняв, что багов нет, стали тестировать дальше на продакшне, сохранив возможность перейти обратно на связку Asterisk + WebRTC2SIP

    После миграции проблемы со стороны софтсвитча исчезли. Появились проблемы со стороны SIPml:

    • Если позвонить и скинуть трубку, то sipml будет думать, что ему также звонят и будет пробовать взять уже мертвый звонок.
    • Звонок длился не больше 2х минут.


    Сделали несколько костылей для того, чтобы эти проблемы нам не мешали и решили перейти на JSSIP. О JSSIP знали уже около месяца. А еще тут было много ненависти к Doubango и их продуктам и огромное желание избавится от их продуктов.

    Проверив все на tryit.jssip.net и поняв, что проблем нет, через три дня, после миграции на JSSIP, у нас SIP стал работать стабильно и без багов.

    Резюме


    Вот такая история получилась. А теперь мое личное мнение по каждому софту.
    SIPml


    Плюсы:
    • Поддерживает трансфер


    Минусы:
    • Очень огромная. Минифицированный js файл весит > 1 Mb
    • Нет полной документации. Много чего приходилось выискивать по интернетам.
    • Больше заточена под WebRTC2sip
    • Много кода


    Пример подключения к серверу
    // Взято из документации
             SIPml.init(
                        function(e){
                            var stack =  new SIPml.Stack({realm: 'example.org', impi: 'bob', impu: 'sip:bob@example.org', password: 'mysecret',
                                events_listener: { events: 'started', listener: function(e){
                                            var callSession = stack.newSession('call-audiovideo', {
                                                    video_local: document.getElementById('video-local'),
                                                    video_remote: document.getElementById('video-remote'),
                                                    audio_remote: document.getElementById('audio-remote')
                                                });
                                            callSession.call('alice');
                                        } 
                                    }
                            });
                            stack.start();
                        }
                );
    


    Пример звонка
    // Взято из документации
                var callSession;
                var eventsListener = function(e){
                    console.info('session event = ' + e.type);
                }
                var makeCall = function(){
                    callSession = sipStack.newSession('call-audiovideo', {
                        video_local: document.getElementById('video-local'),
                        video_remote: document.getElementById('video-remote'),
                        audio_remote: document.getElementById('audio-remote'),
                        events_listener: { events: '*', listener: eventsListener } // optional: '*' means all events
                    });
                    callSession.call('johndoe');
                }
            
    


    JSSIP


    Плюсы:

    • Легковесная (~130kb)
    • Отличная документация на сайте разработчика
    • Отлично работает с Freeswitch(по идее и с Asterisk и другими, но тут я уже не проверял)
    • Отличное API


    Минусы:
    • Не умеет делать трансфер звонка


    Пример подключения к серверу:
    // Из документации
    var configuration = {
      'ws_servers': 'ws://sip-ws.example.com',
      'uri': 'sip:alice@example.com',
      'password': 'superpassword'
    };
    var coolPhone = new JsSIP.UA(configuration);
    
    


    Пример звонка
    // из документации
    var selfView =   document.getElementById('my-video');
    var remoteView =  document.getElementById('peer-video');
    
    // Register callbacks to desired call events
    var eventHandlers = {
      'progress':   function(e){ /* Your code here */ },
      'failed':     function(e){ /* Your code here */ },
      'started':    function(e){
        var rtcSession = e.sender;
    
        // Attach local stream to selfView
        if (rtcSession.getLocalStreams().length > 0) {
          selfView.src = window.URL.createObjectURL(rtcSession.getLocalStreams()[0]);
        }
    
        // Attach remote stream to remoteView
        if (rtcSession.getRemoteStreams().length > 0) {
          remoteView.src = window.URL.createObjectURL(rtcSession.getRemoteStreams()[0]);
        }
      },
      'ended':      function(e){ /* Your code here */ }
    };
    
    var options = {
      'eventHandlers': eventHandlers,
      'extraHeaders': [ 'X-Foo: foo', 'X-Bar: bar' ],
      'mediaConstraints': {'audio': true, 'video': true}
    };
    
    coolPhone.call('sip:bob@example.com', options);
    


    Webrtc2sip


    Плюсы:
    • Помог решить проблему с Asterisk

    Минусы:
    • Не стабильный
    • Стабильность наладили спустя год.


    Asterisk


    Как я понял, умельцы в одном релизе чинят, в другом ломают.
    На версии 1.7 SIP через WebRTC работать у меня перестал.

    Хабраюзер Ovoshlook отлично и подробно описал проблему:

    Умельцы уже пропатчили. сейчас всеобщая и всепоглащающая проблема в другом- когда астериск делает бриджинг он посылает инвайт с транспортом AVP, и если вызываемый абонент сидит на вебфоне — он соответственно ожидает транспорт AVPF и шифрование. Как следствие при звонке вызываемый будет отвечать 603 ошибкой c комментарием failed to get local sdp.
    В общем и целом — при исходящх астериск не следит за тем с какого устройства на нем сидит клиент. Как вариант можно проксировать и преобразовывать через openSIPS или Kamailio, но это уже совсем другая тема.

    В итоге всё это надоело и мы выбрали Freeswitch как soft-switch

    Freeswitch


    Плюсы:
    • Работает
    • Активно разрабатывается
    • Ничего не ломается в новых релизах

    Минусы:
    • Нет возможности сделать подобный колцентр, как в asterisk с бабой-роботом по таймауту


    Итог


    SIP стал работать стабильно. Операторы счастливы. Текущая связка Freeswitch+JSSIP обрабатывает ~10k звонков в сутки и до 15k в часы-пик.

    PS


    Кому интересно могу написать о том, как мы настраивали Freeswitch с интеграцией с MySQL, кол-центром, записью звонков и делали его отказоустойчивым.

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 20

      0
      Спасибо за указку куда смотреть.
      Про freeswitch интересно и с нетерпением буду ждать.
        0
        Тоже интересовался этой темой некоторое время назад, но так и не получил стабильного решения. Поэтому огромное спасибо за эту очень полезную статью!

        С огромным интересом почитал бы про интеграцию Freeswitch с колл-центром и отказоустойчивость всей этой конструкции.
          0
          Конечно интересно, ждем статьи по настройке!
            0
            Жду следующую статью!
              0
              Т.е. PBX вы не реализовали или были планы (как)? Могу предположить, что планировали перенаправление на asterisk под боком для таких целей?
                0
                Кому интересно могу написать о том, как мы настраивали Freeswitch с интеграцией с MySQL, кол-центром, записью звонков и делали его отказоустойчивым.

                Тема актуальна. Ждем =)
                  0
                  Как WebRTC работает за натом?

                  Последние годы проблемы были только с этим, поэтому WebRTC-решения до продакшена не дошли.
                    0
                    Нормально работает за натом. STUN помогает.
                    –1
                    В который раз вижу массивную попоболь от астериска. В который раз всех убеждаю НИКОГДА не пользоваться этим говном.
                      –1
                      +1. Пока всю боль не испытал, не понял этого :)
                        0
                        Использую asterisk как в больших организациях, так и дома. Железки от HP DL380G7 за кучуденег под Centos 6.5 до tp-link mr3020 за 500 руб под OpenWRT (домашний gsm-шлюз).

                        Попоболь была лишь единожды — трещал поток Е1. Дело оказалось в конвертере pcie->pci на материнке, при замене E1-карты на pcie-версию проблема решилась. В остальном вопросов нет. Собираемся переходить на 12-й релиз.

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

                        Сравнивать фрисвич и астериск вообще некорректно. Первый — софтсвич, второй — софтАТС. Никто не мешает использовать фрисвич как WebRTC-бэкенд.

                        Всё это чем-то неуловимо напоминает apache vs nginx. Для каждой задачи — свой инструмент, в общем.
                          0
                          Сравнивать Asterisk и Freeswitch имеет смысл только тогда, когда Asterisk используешь как soft-switch.

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

                          Скрывать то не скрывает, и использует на свой страх и риск. Но сейчас WebRTC стабильнее того, что было к примеру год назад
                      0
                      FreeSwitch — это правильно. Жаль мы пока не можем просто переключиться с Астериска на FreeSwitch, но с другой стороны, у нас все работает в связке Sipml5 + Asterisk 11.10 (SDES).
                        0
                        Огромное спасибо!
                          0
                          Интересно, где используется решение, 10k звонков в сутки — это достаточно много, колл-центр? Cloud-платформы не рассматривали для решения проблем в разы быстрее?
                            –1
                            Cloud-платформы не рассматривали. Нужно было своё. Да, делали для кол-центра.
                              0
                              А в чем причина «Нужно было свое»? Если откинуть challenge
                                0
                                Клауды далеко от нас и проблема во внешнем канале. Да и как-то не задумывались, решили сразу сделать свое.
                                  0
                                  Это надо изучать, тут не про public-клауд речь :) Но подход имеет право на жизнь, спасибо за ответы!
                            0
                            А сам клиент на JsSIP нормально звонки принимает?

                            Only users with full accounts can post comments. Log in, please.