...

среда, 4 июня 2014 г.

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, кол-центром, записью звонков и делали его отказоустойчивым.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий