null

BigBlueButton и FreeSWITCH

Начиная с версии 0.71 BigBlueButton в качестве сервера конференций "из-коробки" использует FreeSWITCH. Как и ранее, весь комплекс поставляется в виде виртуального окружения на базе Ubuntu Linux.

Разработчики BigBlueButton обещают существенное улучшение качества звука при переходе на FreeSWITCH. Это связано с ограниченным набором звуковых кодеков, которые поддерживает Flash Player и должен понимать сервер конференций. Но все мои попытки перевести уже работающую на стенде BigBlueButton c Asterisk на FreeSWITCH ни к чему не привели: пользователи успешно регистрировались в конференции, но не появлялись в списке слушателей. Пришлось опять брать лопату и копаться авгиевых конюшнях.

Попробовав разные версии FreeSWITCH и собрав логи и tcpdump общения между BigBlueButton и FreeSWITCH (в отличие от Asterisk AMI, FreeSWITCH использует Event Socket Library протокол) мне удалось выяснить:

* Если используется
FreeSWITCH последней стабильной версии 1.0.6, в момент регистрации нового слушателя мы получаем ошибку на стороне Red5:
 

2010-11-15 17:19:02,625 [EslEventNotifier-1] ERROR o.f.esl.client.inbound.Client - Error caught notifying listener of event [EslEvent: name=[CUSTOM] subclass=[conference::maintenance] headers=2, eventHeaders=51, eventBody=0 lines.]
java.lang.NullPointerException: null
        at org.bigbluebutton.webconference.voice.freeswitch.FreeswitchApplication.conferenceEventJoin(FreeswitchApplication.java:140) [FreeswitchApplication.class:na]
        at org.freeswitch.esl.client.inbound.Client$3$2.run(Client.java:494) [org.freeswitch.esl.client-0.9.0-SNAPSHOT.jar:na]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.6.0]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.6.0]
        at java.lang.Thread.run(Thread.java:636) [na:1.6.0]


* Если используется последний нестабильный
FreeSWITCH snapshot oт 12-Nov-2010, ошибок никаких не регистрируется, однако и слушателей в Listeners window не появляется.

* А вот если собрать
FreeSWITCH snapshot от 15-Oct-2010, который на текущий момент доступен по ссылке, получается вполне себе рабочая связка.

Diff между snapshot'ами FreeSWITCH  разницей в месяц очень велик и пока я не добрался до esl/mod_conference, изменение логики работы которых привело к ошибкам в org.freeswitch.esl.client.inbound.Client (с негодованием хочу заметить, что эта библиотека также подверглась насилию со стороны разработчиков BigBlueButton и поставляется в модифицированном виде). Пока что я ограничился регистрацией двух багов: 639 и 739 на BBB Issues.

Только разработчиков такие новости не очень обрадовали и они пока забили на эти баги.

Ясно-понятно, что просто так оставить этого было нельзя. Поэтому на следующий день отведав лося с тыквой в пиве, я стал смотреть tcpdump'ом весь процесс общения BigBlueButton и разных версий FreeSWITCH. Вот чего я увидел:

* FreeSWITCH 1.0.6 в момент регистрации пользователя в конференции сообщал следующее:

Event-Subclass: conference%3A%3Amaintenance
Event-Name: CUSTOM
Core-UUID: 6e5788b4-d4f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2016%3A25%3A06
Event-Date-GMT: Mon,%2015%20Nov%202010%2016%3A25%3A06%20GMT
Event-Date-Timestamp: 1289838306794312
Event-Calling-File: mod_conference.c
Event-Calling-Function: conference_add_member
Event-Calling-Line-Number: 726
Conference-Name: 79334
Conference-Size: 1
Conference-Profile-Name: wideband
Channel-State: CS_EXECUTE
Channel-State-Number: 4
Channel-Name: sofia/external/79334%40192.168.50.117
Unique-ID: 292f71e8-d4f0-df11-99e4-001b24e04702
Call-Direction: inbound
Presence-Call-Direction: inbound
Answer-State: answered
Channel-Read-Codec-Name: L16
Channel-Read-Codec-Rate: 8000
Channel-Write-Codec-Name: PCMA
Channel-Write-Codec-Rate: 8000
Caller-Username: 79334
Caller-Dialplan: XML
Caller-Caller-ID-Name: deiter
Caller-Caller-ID-Number: 79334
Caller-Network-Addr: 192.168.50.117
Caller-ANI: 79334
Caller-Destination-Number: 79334
Caller-Unique-ID: 292f71e8-d4f0-df11-99e4-001b24e04702
Caller-Source: mod_sofia
Caller-Context: public
Caller-Channel-Name: sofia/external/79334%40192.168.50.117
Caller-Profile-Index: 1
Caller-Profile-Created-Time: 1289838306785296
Caller-Channel-Created-Time: 1289838306785296
Caller-Channel-Answered-Time: 1289838306792284
Caller-Channel-Progress-Time: 0
Caller-Channel-Progress-Media-Time: 0
Caller-Channel-Hangup-Time: 0
Caller-Channel-Transfer-Time: 0
Caller-Screen-Bit: true
Caller-Privacy-Hide-Name: false
Caller-Privacy-Hide-Number: false
Member-ID: 1
Member-Type: member
Action: add-member

 

* FreeSWITCH snapshot от 15-Oct-2010 в момент регистрации пользователя в конференции сообщал тоже самое, но несколько многословнее:

Event-Subclass: conference%3A%3Amaintenance
Event-Name: CUSTOM
Core-UUID: be90f9e0-c8f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2015%3A02%3A49
Event-Date-GMT: Mon,%2015%20Nov%202010%2015%3A02%3A49%20GMT
Event-Date-Timestamp: 1289833369882082
Event-Calling-File: mod_conference.c
Event-Calling-Function: conference_add_member
Event-Calling-Line-Number: 754
Conference-Name: 79334
Conference-Size: 1
Conference-Profile-Name: wideband
Floor: true
Channel-State: CS_EXECUTE
Channel-Call-State: ACTIVE
Channel-State-Number: 4
Channel-Name: sofia/external/79334%40192.168.50.117
Unique-ID: 4ef6cf69-c9f0-df11-99e4-001b24e04702
Call-Direction: inbound
Presence-Call-Direction: inbound
Answer-State: answered
Channel-Read-Codec-Name: L16
Channel-Read-Codec-Rate: 8000
Channel-Write-Codec-Name: PCMA
Channel-Write-Codec-Rate: 8000
Caller-Direction: inbound
Caller-Username: 79334
Caller-Dialplan: XML
Caller-Caller-ID-Name: deiter
Caller-Caller-ID-Number: 79334
Caller-Network-Addr: 192.168.50.117
Caller-ANI: 79334
Caller-Destination-Number: 79334
Caller-Unique-ID: 4ef6cf69-c9f0-df11-99e4-001b24e04702
Caller-Source: mod_sofia
Caller-Context: public
Caller-Channel-Name: sofia/external/79334%40192.168.50.117
Caller-Profile-Index: 1
Caller-Profile-Created-Time: 1289833369872755
Caller-Channel-Created-Time: 1289833369872755
Caller-Channel-Answered-Time: 1289833369880040
Caller-Channel-Progress-Time: 0
Caller-Channel-Progress-Media-Time: 0
Caller-Channel-Hangup-Time: 0
Caller-Channel-Transfer-Time: 0
Caller-Screen-Bit: true
Caller-Privacy-Hide-Name: false
Caller-Privacy-Hide-Number: false
Video: false
Hear: true
Speak: true
Talking: false
Member-ID: 1
Member-Type: member
Action: add-member

 

Разница заключается в дополнительных заголовках, которые отдает FreeSWITCH snapshot от 15-Oct-2010 при подключении пользователя к конференции:

Caller-Direction
Channel-Call-State
Floor
Hear
Speak
Talking
Video

 

Еще раз посмотрев на ошибку-исключение из Red5 error.log я пошел смотреть исходный код FreeswitchApplication.java:140 и нашел там причину ошибки в указанной строке:

    @Override
    public void conferenceEventJoin(String uniqueId, String confName, int confSize, EslEvent event) {
        Integer memberId = this.getMemeberIdFromEvent(event);
        Map<String, String> headers = event.getEventHeaders();
        String callerId = this.getCallerIdFromEvent(event);
        String callerIdName = this.getCallerIdNameFromEvent(event);
        boolean muted = headers.get("Speak").equals("true") ? false : true; //Was inverted which was causing a State issue
        boolean speeking = headers.get("Talking").equals("true") ? true : false;

        ParticipantJoinedEvent pj = new ParticipantJoinedEvent(memberId, confName,
                        callerId, callerIdName, muted, speeking);
        conferenceEventListener.handleConferenceEvent(pj);
    }

 

conferenceEventJoin пытается прочитать в переменную muted значение заголовка Speak, а при его отсутствии мы получаем исключение. Такой же результат может вызвать следующая строка, но до нее просто дело не доходит. Соответсвенно, отсутствие заголовков Speak/Talking делает невозможным взаимодействие FreeSWITCH 1.0.6 и BigBlueButton.

Теперь давайте разберемся, почему же не работает последний нестабильный FreeSWITCH snapshot oт 12-Nov-2010. tcpdump сессии между BigBlueButton и FreeSWITCH показывает полное отсутствие уведомлений о ходе конференции:

Content-Type: auth/request

auth ClueCon

Content-Type: command/reply
Reply-Text: +OK accepted

noevents

Content-Type: command/reply
Reply-Text: -ERR not listening for events

event plain all

Content-Type: command/reply
Reply-Text: +OK event listener enabled plain

filter Event-Name heartbeat

Content-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[heartbeat]

filter Event-Name custom

Content-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[custom]

filter Event-Name background_job

ontent-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[background_job]

api conference 75427 xml_list

Content-Type: api/response
Content-Length: 27

Conference 75427 not found

 

В соответствии с документацией на Mod Event Socket разберем этот сеанс по командам:

2 строка: аутентификация

5 строка: отказ от получения каких-либо уведомлений

8 строка: формат и список уведомлений, которые мы хотим получать

11 строка: установка фильтра на получение только Heartbeat уведомлений

14 и 17 строки добавление к существующему фильтру нескольких типов уведомлений - Custom и Background_Job.

20 строка: проверка существования конференции

на этом какой-либо вывод со стороны FreeSWITCH snapshot oт 12-Nov-2010 почему-то прекращется. Напомню еще раз,что процесс общения с FreeSWITCH snapshot от 15-Oct-2010 выглядит гораздо насыщенней:

Content-Type: auth/request

auth ClueCon

Content-Type: command/reply
Reply-Text: +OK accepted

noevents

Content-Type: command/reply
Reply-Text: -ERR not listening for events

event plain all

Content-Type: command/reply
Reply-Text: +OK event listener enabled plain

filter Event-Name heartbeat

Content-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[heartbeat]

Content-Length: 634
Content-Type: text/event-plain

filter Event-Name custom

Content-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[custom]

filter Event-Name background_job
Content-Type: command/reply
Reply-Text: +OK filter added. [Event-Name]=[background_job]

Content-Length: 633
Content-Type: text/event-plain

Event-Name: HEARTBEAT
Core-UUID: be90f9e0-c8f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2015%3A00%3A00
Event-Date-GMT: Mon,%2015%20Nov%202010%2015%3A00%3A00%20GMT
Event-Date-Timestamp: 1289833200410315
Event-Calling-File: switch_core.c
Event-Calling-Function: send_heartbeat
Event-Calling-Line-Number: 65
Event-Info: System%20Ready
Up-Time: 0%20years,%200%20days,%200%20hours,%201%20minute,%200%20seconds,%20112%20milliseconds,%20290%20microseconds
Session-Count: 0
Session-Per-Sec: 30
Session-Since-Startup: 0
Idle-CPU: 100.000000

Content-Length: 635
Content-Type: text/event-plain

Event-Name: HEARTBEAT
Core-UUID: be90f9e0-c8f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2015%3A01%3A20
Event-Date-GMT: Mon,%2015%20Nov%202010%2015%3A01%3A20%20GMT
Event-Date-Timestamp: 1289833280122785
Event-Calling-File: switch_core.c
Event-Calling-Function: send_heartbeat
Event-Calling-Line-Number: 65
Event-Info: System%20Ready
Up-Time: 0%20years,%200%20days,%200%20hours,%202%20minutes,%2019%20seconds,%20824%20milliseconds,%20760%20microseconds
Session-Count: 0
Session-Per-Sec: 30
Session-Since-Startup: 0
Idle-CPU: 100.000000

Content-Length: 1792
Content-Type: text/event-plain

Event-Subclass: conference%3A%3Amaintenance
Event-Name: CUSTOM
Core-UUID: be90f9e0-c8f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2015%3A02%3A49
Event-Date-GMT: Mon,%2015%20Nov%202010%2015%3A02%3A49%20GMT
Event-Date-Timestamp: 1289833369882082
Event-Calling-File: mod_conference.c
Event-Calling-Function: conference_add_member
Event-Calling-Line-Number: 754
Conference-Name: 79334
Conference-Size: 1
Conference-Profile-Name: wideband
Floor: true
Channel-State: CS_EXECUTE
Channel-Call-State: ACTIVE
Channel-State-Number: 4
Channel-Name: sofia/external/79334%40192.168.50.117
Unique-ID: 4ef6cf69-c9f0-df11-99e4-001b24e04702
Call-Direction: inbound
Presence-Call-Direction: inbound
Answer-State: answered
Channel-Read-Codec-Name: L16
Channel-Read-Codec-Rate: 8000
Channel-Write-Codec-Name: PCMA
Channel-Write-Codec-Rate: 8000
Caller-Direction: inbound
Caller-Username: 79334
Caller-Dialplan: XML
Caller-Caller-ID-Name: deiter
Caller-Caller-ID-Number: 79334
Caller-Network-Addr: 192.168.50.117
Caller-ANI: 79334
Caller-Destination-Number: 79334
Caller-Unique-ID: 4ef6cf69-c9f0-df11-99e4-001b24e04702
Caller-Source: mod_sofia
Caller-Context: public
Caller-Channel-Name: sofia/external/79334%40192.168.50.117
Caller-Profile-Index: 1
Caller-Profile-Created-Time: 1289833369872755
Caller-Channel-Created-Time: 1289833369872755
Caller-Channel-Answered-Time: 1289833369880040
Caller-Channel-Progress-Time: 0
Caller-Channel-Progress-Media-Time: 0
Caller-Channel-Hangup-Time: 0
Caller-Channel-Transfer-Time: 0
Caller-Screen-Bit: true
Caller-Privacy-Hide-Name: false
Caller-Privacy-Hide-Number: false
Video: false
Hear: true
Speak: true
Talking: false
Member-ID: 1
Member-Type: member
Action: add-member

Content-Length: 634
Content-Type: text/event-plain

Event-Subclass: conference%3A%3Amaintenance
Event-Name: CUSTOM
Core-UUID: be90f9e0-c8f0-df11-99e4-001b24e04702
FreeSWITCH-Hostname: x4150b.tdc
FreeSWITCH-IPv4: 192.168.50.117
FreeSWITCH-IPv6: %3A%3A1
Event-Date-Local: 2010-11-15%2015%3A02%3A52
Event-Date-GMT: Mon,%2015%20Nov%202010%2015%3A02%3A52%20GMT
Event-Date-Timestamp: 1289833372603706
Event-Calling-File: mod_conference.c
Event-Calling-Function: conference_thread_run
Event-Calling-Line-Number: 1168
Conference-Name: 79334
Conference-Size: 1
Conference-Profile-Name: wideband
Action: play-file-done
File: /fs-current/sounds/en/us/callie/conference/conf-alone.wav
Async: true

 

Не придумав ни одного правдоподобного объяснения такой разницы в поведении, я подключился при помощи telnet к Mod Event Socket разных версий FreeSWITCH и стал повторять поведение BigBlueButton. Набирал соответствующие команды и сравнивал реакцию. Оказалось, что для октябрьского FreeSWITCH snapshot команда filter Event-Name добавляет к существующему фильтру новые условия, в то время как для ноябрьского FreeSWITCH snapshot аналогичная команда переопределяет существующий фильтр. Это и объясняет отсутствие событий в ходе конференции и пустое окно слушателей. Как итог, я зарегистрировал  Issue ESL-52 и жду комментария разработчиков.

Добавлено 24.11.2010: Через пару дней я попросил разработчиков как-нибудь отреагировать на открытый баг. На следующий день ошибка была исправлена. Сейчас FreeSWITCH успешно работает в качестве сервера конференций для BigBlueButton.

Не делайте из еды культа!

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

Ничего не найдено. n is 0