pull WebRTC Failed (Session does not exist)

pride

Member
Здравствуйте!
Задача забрать поток с одного wcs на другой c помощью webrtc:

wcs.com - сервер на котором опубликован поток
wcs1.com - собственно сюда хочу забрать поток и проиграть

WCS 5.2.396, стоковый и без каких либо изменений конфигов.
  1. Публикую поток на wcs.com (с помощью демо "Two-way Streaming") под именем test
  2. Делаю post запрос на wcs1.com (https://wcs1.com:8444/rest-api/pull/pull):
    Code:
    https://wcs1.com:8444/rest-api/pull/pull  [code: 200]
    {  "uri":"wss://wcs.com:8443",
      "localStreamName" : "test",
      "remoteStreamName" : "test"
    }
  3. Проверяю забрал ли он поток:
    Code:
    https://wcs1.com:8444/rest-api/pull/find_all  [code: 200]
    {
    "localMediaSessionId": "a9023d1c-fd69-4f84-a891-414a21a071c6",
    "localStreamName": "test",
    "remoteStreamName": "test",
    "uri": "wss://wcs.com:8443/websocket",
    "status": "NEW",
    "hasAudio": true,
    "hasVideo": true,
    "record": false
    }
  4. Иду в пример "Player" на wcs1.com:
    Code:
    WCS URL : wss://wcs1.com:8443
    Stream: test
    Получаю: FAILED (Session does not exist)
  5. Через какое то время:
    Code:
    https://wcs1.com:8444/rest-api/pull/find_all  [code: 404]
    {
    "exception": "com.flashphoner.rest.server.exception.NotFoundException",
    "path": "/rest-api/pull/find_all",
    "error": "Not Found",
    "message": "NOT FOUND",
    "timestamp": 1573655229258,
    "status": 404
    }

Логи wcs.com:
Code:
15:22:23,298 WARN       WSServerHandler - WSS-pool-22-thread-1 Close channel [id: 0x25e21301, /0.0.0.0:34003 => /0.0.0.0:8443] because: javax.net.ssl.SSLException 'not an SSL/TLS record: 474554202f776562736f636b657420485454502f312e310d0a557067726164653a20776562736f636b65740d0a436f6e6e656374696f6e3a20557067726164650d0a5365632d576562536f636b65742d4b65793a207767625635344d736536396868756d584634306b62773d3d0d0a486f73743a207763732e70726964652d766164696d2e636f6d0d0a4f726967696e3a20687474703a2f2f7763732e70726964652d766164696d2e636f6d3a383434330d0a5365632d576562536f636b65742d56657273696f6e3a2031330d0a0d0a'
Логи wcs1.com:
Code:
15:22:23,219 INFO         RestApiRouter - HTTPS-pool-4-thread-2 Use controller class com.flashphoner.rest.server.rest_v2.RestPullStreamController with path /rest-api/pull/pull
15:22:23,223 INFO  PullStreamController - HTTPS-pool-4-thread-2 handleRequest /rest-api/pull/pull params:{uri=wss://wcs.com:8443, localStreamName=test, remoteStreamName=test}
15:22:23,228 INFO             PullAgent - HTTPS-pool-4-thread-2 Created agent:WebRTCAgentFilter{localMediaSessionId='null', remoteMediaSessionId='null', localStreamName='test', remoteStreamName='test', uri='wss://wcs.com:8443/websocket', status='null', record='false', hasAudio='true', hasVideo='true'}
15:22:23,284 INFO          AgentFactory - HTTPS-pool-4-thread-2 Provide stream initialization result ADDED
15:37:35,942 INFO              WCSAgent - Sessions Agent wss://wcs.com:8443/websocket-f6ddbd68-e011-4001-8a25-cc66a4f32033 changed state to STOPPED
SSL сертификаты и там и там свежие и проходят валидацию.
 
Last edited:

Max

Administrator
Staff member
По-умолчанию wss выключен для агентов (работа между нодами).
Code:
wcs_agent_ssl=true
чтобы включить

Другой способ - делать pull через ws
Code:
ws://wcs.com:8080
Еще один способ - настроить wcs1.com как Edge сервер в CDN
В этом случае pulling будет работать автоматически при попытке проиграть стрим плеером с wcs1.com
 

pride

Member
Огромное спасибо.
А возможно ли сделать pull с другим appKey ?
Дабы получить события создание потока на бекенде и обработать его?
 

pride

Member
Если я пытаюсь передать appKey на Rest получаю следующее:
Code:
[500]
{
"exception": "java.lang.IllegalArgumentException",
"path": "/rest-api/pull/pull",
"error": "Internal Server Error",
"message": "Unrecognized field "appKey" (Class com.flashphoner.server.commons.rmi.data.impl.AgentFilter), not marked as ignorable at [Source: N/A; line: -1, column: -1] (through reference chain: com.flashphoner.server.commons.rmi.data.impl.AgentFilter["appKey"])",
"timestamp": 1573738980169,
"status": 500
}
Так же было бы отлично передавать custom поля, тем самым полностью эмитировать клиента.
 
Last edited:

Max

Administrator
Staff member
Добрый день.
Если я пытаюсь передать appKey на Rest получаю следующее:
Pull с другим appKey по REST выполнить нельзя. Вы можете обрабатывать события на вашем backend, заменив стандартные App в WCS. Примеры обработки REST hook вы можете увидеть в этой теме на форуме.
Утоните, пожалуйста, примерную логику вашего примера при работе с двумя серверами WCS. Какой функционал вы хотели бы реализовать?
Возможно, вам более подойдет пример с CDN, с документированными возможностями добавления Custom полей.
 

pride

Member
У нас имееться два отдельных сервиса, т.е сайта с собственным WCS. Пользователь в них стримит на сервер используя WebSDK. задача в некоторых случаях сделать возможность публикации видео на 2 сервера. Если подходить со стороны физического стрима на два сервера с фронта, огромная просадка в трафике на стороне клиента. Поэтому есть идея использовать pull.
 
Last edited:

pride

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

Max

Administrator
Staff member
В вашем случае подходит реализация схемы CDN (один из серверов Origin, другой Edge). Для авторизации в этом случае используются ключи, организованные в списки контроля доступа (ACL) для каждого из потоков. Подписчик может запросить поток для воспроизведения, только указав правильный ключ.
 

pride

Member
Я смогу прямо на Edge публиковать потоки? Сервисы независимые поэтому возможность полного обеднения невозможна.
 

Max

Administrator
Staff member
Добрый день.
Я смогу прямо на Edge публиковать потоки? Сервисы независимые поэтому возможность полного обеднения невозможна.
Да, на Edge сервере можно опубликовать поток и воспроизвести по CDN поток, опубликованный на Origin. На Origin сервере воспроизвести поток, опубликованный на Edge, нельзя.
Но в случае с серверами, где возможна публикация потока на любом из них, вашу текущая реализация работоспособна (без использования CDN).

Ну и собственно нужно каким то образом авторизовывать этих пользователей. В штатном режиме авторизация проходит передачей кастомных полей в другом аппликейшене.
1. Настройте ваш REST hook на back-end сервере:
Code:
https://<ваш back-end сервер>/hook/connect
2. При POST запросе REST hook вашего back-end должен отдавать 403 Forbidden, если клиент не авторизован для доступа к WSS, если доступ разрешен 200 OK. Для примера создаем php файл, реализующий эту логику:
PHP:
<?php
   header('HTTP/1.1 403 Forbidden',true,403);
?>
3. Проверяем внесенные изменения:
Code:
[root@p16 /]# curl -k -I https://<ваш back-end сервер>/hook/connect
HTTP/1.1 403 Forbidden
Date: Thu, 31 Oct 2019 16:48:39 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.16
X-Powered-By: PHP/5.4.16
Content-Type: text/html; charset=UTF-8
4. Ваш WCS сервер должен быть настроен на работу с REST hook. Подключаемся к CLI WCS (пароль по умолчанию admin):
Code:
ssh -p 2001 admin@localhost
и обновляем приложение defaultApp:
Code:
update app -l https://<ваш back-end сервер>/hook defaultApp
5. Открываем в браузере страницу:
Code:
https://<your WCS IP-address or domain name>:8444/client2/examples/demo/streaming/two_way_streaming/two_way_streaming.html
Подключение к wss://<your WCS IP-address or domain name>:8443 не удалось (статус DISCONNECTED): back-end сервер на ваш запрос ответил "403 Forbidden".

6. Передаем дополнительные параметры для авторизации в функцию createSession (добавляем custom данные; например, usernameTest и passwdTest):
Code:
https://<your WCS IP-address or domain name>:8444/client2/examples/demo/streaming/two_way_streaming/two_way_streaming.js
Code:
function connect() {
  ...
    Flashphoner.createSession({urlServer: url,custom:{usernameTest: "passwdTest"}}).on(SESSION_STATUS.ESTABLISHED,function(session){...})
    ...
}
7. Дополняем php-скрипт, созданный на шаге 2, данными для авторизации пользователя:
PHP:
<?php
$incoming_data = json_decode(file_get_contents('php://input'), true);

if ($incoming_data['custom']['usernameTest'] == 'passwdTest') {
    header('HTTP/1.1 200 OK',true,200);
} else {
    header('HTTP/1.1 403 Forbidden',true,403);
}
?>
8. Открываем в браузере страницу:
Code:
https://<your WCS IP-address or domain name>:8444/client2/examples/demo/streaming/
two_way_streaming/two_way_streaming.html
Подключение к wss://<your WCS IP-address or domain name>:8443 выполнено (статус ESTABLISHED): back-end сервер на ваш запрос ответил "200 OK".
 
Last edited:

pride

Member
при использовании pull/pull на rest hook не приходит событие /connect , хотя в defaulApp был добавлен "add app-rest-method defaulApp connect".
Первым приходит: ConnectionStatusEvent

Так же если ответить 403 заголовком. Поток все равно пройдет и будет опубликован.
 
Last edited:

pride

Member
У нас нет возможности объединить сервера в CDN (так как это разные сервисы и возможно один из них в дальнейшем станет сторонним), поэтому приходиться использовать pull/pull и в принципе он нас полностью устраивает, за исключением проблем описанных ниже:
  1. Из за отсутствия возможности указать appKey, приходиться писать дополнительную прослойку между backend и restHook.
  2. Из за отсутствия возможности указать custom поля при подключении, пришлось передавать в url параметре (так как url используется в формировании sessionId) в прослойке (п.1) с помощью regExp я выгрызаю эти поля. Костыль! Но другой возможности нет.
  3. Первым событием является ConnectionStatusEvent а не connect (как обычно), вообще делает пункты выше бесполезными, ибо авторизация происходит именно в событии connect.
  4. RestHook не риагирут на заголовки 404/403/500, просто игнорируя их, я так понимаю происходит это как раз из за п. 3 и соответственно не удается укзать "restClientConfig".

Нет ли возможности исправить это?
 
Last edited:

Max

Administrator
Staff member
Добрый день.
У нас нет возможности объединить сервера в CDN (так как это разные сервисы и возможно один из них в дальнейшем станет сторонним), поэтому приходиться использовать pull/pull и в принципе он нас полностью устраивает, за исключением проблем описанных ниже:
Вы реализуете авторизацию для публикации потока /pull/pull на другой WCS сервер, не для просмотра или первоначальной публикации трансляции? То есть первым шагом пользователь забирает поток с другого сервера, а затем просматривает её? Опишите, пожалуйста, немного подробнее этот процесс и укажите на каком этапе нужна авторизация.
У нас имееться два отдельных сервиса, т.е сайта с собственным WCS. Пользователь в них стримит на сервер используя WebSDK. задача в некоторых случаях сделать возможность публикации видео на 2 сервера. Если подходить со стороны физического стрима на два сервера с фронта, огромная просадка в трафике на стороне клиента. Поэтому есть идея использовать pull.
Возможно, вам стоит авторизовать пользователя для трансляции на сервере. Например, стрим выполняется на сервер А авторизованным пользователя.
И авторизовать пользователя для её просмотра. Например, пользователь пробует просмотреть трансляцию на сервере Б. Вы авторизуете его. Если трансляция уже есть на сервере (в другой теме на форуме вы реализовывали длительный таймаут проверки активности), пользователь начнет её просмотр. Это все можно реализовать с помощью REST hook, как мы объяснили ранее.
Вам только остается запросить стрим по REST API для авторизованного пользователя в случае, если трансляции нет на сервере Б, а пользователь пытается посмотреть её с сервера Б.
 
Last edited:

pride

Member
Есть 2 отдельных проекта одной тематики принцип следующий: одни публикуют потоки, другие пользователи их смотрят.
На обоих используется WCS.
Теперь из за нехватки паблишеров на втором проекте появилась необходимость публикации потока с сайта1, на два wcs сервера.
Если пустить от клиента 2 потока на wcs1 и wcs2 будет огромная просадка по трафику, ибо с интернетом у паблишеров в большинстве случаев беда.
Было решено по запросу от клиента (через контроллер на бекенде) сайта1 на сайт2 забирать поток напрямую из wcs1 на wcs2.
Но перед тем как опубликовать поток, нужно идентифицировать и привязать его к сложной логике сайта2.
 
Last edited:

pride

Member
Если на сервере где находиться поток включен restAuth, то при запросе rest отвечает 200, а потока и каких либо ошибок в логах/событий на RestHook нет.
Пришлось отключить restAuth и закрыть фаерволом. Но это как то не очень.
 

Max

Administrator
Staff member
Если на сервере где находиться поток включен restAuth, то при запросе rest отвечает 200, а потока и каких либо ошибок в логах/событий на RestHook нет.
пожалуйста, уточните, какой REST запрос вы выполняете на этот сервер.
Есть 2 отдельных проекта одной тематики принцип следующий: одни публикуют потоки, другие пользователи их смотрят.
На обоих используется WCS.
Для вашего случая мы рекомендуем пример с CDN c двумя Origin серверами. В этом случае все ваши требования с авторизацией клиентов, для ограничения доступа к потокам, выполняются. Кроме того, разделение проектов в данном примере легко реализуемо стандартными механизмами WCS.
CDN-4.png
 
Last edited:
Top