Управление пользователями (серверная сторона)!

pride

Member
Подскажите как программно со стороны сервера, управлять подключениями?
Нужно сделать видео чат между пользователями и отключать пользователя по истечению н-ного промежутка времени.
Так же требуется авторизация на публикование/просмотр трансляции.
 

Max

Administrator
Staff member
Чтобы завершить поток на стороне сервера, нужно выполнить REST-запрос terminate, как показано здесь
Чтобы получить список текущих стримов, нужно выполнить REST-запрос: findStreams
Пример:
Code:
http://streaming.flashphoner.com:9091/RESTCall/findStreams
Body
Code:
{"published":"false"}
Так же требуется авторизация на публикование/просмотр трансляции.
Как настроить авторизацию на connect/publish/play, недавно обсуждали здесь.
 

Max

Administrator
Staff member
Выше в примере используется REST.
Т.е. это должен быть HTTP POST запрос с Content Type application/json и корректным JSON-объектом в теле сообщения.
Потестировать можно с помощью расширения Chrome - Advanced REST Console
 

pride

Member
Подскажите возможно ли заставить "Приложение" при просмотре / вещании стрима, пинговать с периодичностью, например в 1 минуту web-сервер. ?
И при ответе на пинг 403, отключить пользователя.
 

Max

Administrator
Staff member
Да можно это сделать.
Документ по настройке этих пингов доступен здесь.
В результате вашему веб-серверу должен отправляться StreamKeepAliveEvent
Если отвечаете 200 OK, стрим продолжает работу.
Если отвечаете 403 Forbidden, стрим сбрасывается.
 

pride

Member
Сделал все по инструкции, пинги пошли, да вот только если в ответ передать 403. Стрим и просмотр стрима продолжается.
И смотрю по логам apacha, если 3 подключения, то идут они пачкой , а не по интервалу , каждый отдельно.

Скрипт /stream/StreamKeepAliveEvent :
Code:
<?php
header('HTTP/1.1 403 Forbidden');
header('HTTP/1.0 403 Forbidden');
Из логов apache:
Code:
10.10.10.191 - - [21/Feb/2017:12:17:42 +0200] "POST /stream/StreamKeepAliveEvent HTTP/1.1" 403 173 "-" "Java/1.8.0_111"
10.10.10.191 - - [21/Feb/2017:12:17:53 +0200] "POST /stream/StreamKeepAliveEvent HTTP/1.1" 403 173 "-" "Java/1.8.0_111"
10.10.10.191 - - [21/Feb/2017:12:17:53 +0200] "POST /stream/StreamKeepAliveEvent HTTP/1.1" 403 173 "-" "Java/1.8.0_111"


Из логов WCS:
Code:
12:00:09,862 INFO  agerRemoteRmiService - RMI TCP Connection(255)-127.0.0.1 SEND REST OBJECT ==>
URL:http://test.domain.com/stream/StreamKeepAliveEvent
OBJECT:
{
  "nodeId" : "pueEbX6MOX7P4aIBxSOlJ0eyFTQcDyxB@10.10.10.191",
  "appKey" : "defaultApp",
  "sessionId" : "/10.10.10.191:38316/10.10.10.191:8443",
  "mediaSessionId" : "6f8293a0-f81c-11e6-b49b-3b7c78b6cd70",
  "name" : "d5579e9e",
  "published" : false,
  "hasVideo" : true,
  "hasAudio" : true,
  "status" : "PLAYING",
  "sdp" : "v=0\r\no=- 1549478119705087262 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio video\r\na=msid-semantic: WMS\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:BfEU\r\na=ice-pwd:Lt0QVy8jFdRe7urDnDroLr/C\r\na=fingerprint:sha-256 31:27:C9:F9:63:1A:64:51:9E:8E:49:47:31:21:49:AF:35:B2:2B:7E:46:54:D3:07:65:97:E4:1B:14:15:49:10\r\na=setup:actpass\r\na=mid:audio\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=recvonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:103 isac/16000\r\na=rtpmap:104 isac/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 cn/32000\r\na=rtpmap:105 cn/16000\r\na=rtpmap:13 cn/8000\r\na=rtpmap:126 telephone-event/8000\r\nm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:BfEU\r\na=ice-pwd:Lt0QVy8jFdRe7urDnDroLr/C\r\na=fingerprint:sha-256 31:27:C9:F9:63:1A:64:51:9E:8E:49:47:31:21:49:AF:35:B2:2B:7E:46:54:D3:07:65:97:E4:1B:14:15:49:10\r\na=setup:actpass\r\na=mid:video\r\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:4 urn:3gpp:video-orientation\r\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:100 VP8/90000\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtpmap:101 VP9/90000\r\na=rtcp-fb:101 ccm fir\r\na=rtcp-fb:101 nack\r\na=rtcp-fb:101 nack pli\r\na=rtcp-fb:101 goog-remb\r\na=rtcp-fb:101 transport-cc\r\na=rtpmap:107 H264/90000\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:116 red/90000\r\na=rtpmap:117 ulpfec/90000\r\na=rtpmap:96 rtx/90000\r\na=fmtp:96 apt=100\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=101\r\na=rtpmap:99 rtx/90000\r\na=fmtp:99 apt=107\r\na=rtpmap:98 rtx/90000\r\na=fmtp:98 apt=116\r\n",
  "info" : "Keep Alive",
  "record" : false,
  "width" : 0,
  "height" : 0,
  "bitrate" : 0,
  "quality" : 0,
  "mediaProvider" : "WebRTC"
}
12:00:09,892 INFO  agerRemoteRmiService - RMI TCP Connection(255)-127.0.0.1 SEND REST OBJECT ==>
URL:http://test.domain.com/stream/StreamKeepAliveEvent
OBJECT:
{
  "nodeId" : "pueEbX6MOX7P4aIBxSOlJ0eyFTQcDyxB@10.10.10.191",
  "appKey" : "defaultApp",
  "sessionId" : "/10.10.10.191:38316/10.10.10.191:8443",
  "mediaSessionId" : "6f6ac5e0-f81c-11e6-b49b-3b7c78b6cd70",
  "name" : "d5579e9e",
  "published" : true,
  "hasVideo" : true,
  "hasAudio" : true,
  "status" : "PUBLISHING",
  "sdp" : "v=0\r\no=- 1514809748180188282 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE audio video\r\na=msid-semantic: WMS ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:a0nE\r\na=ice-pwd:ORulArqBFPZdKcvGgvRvwBIf\r\na=fingerprint:sha-256 8F:54:90:66:E6:7D:72:C7:34:A7:53:9D:86:AA:EE:81:59:2B:5B:11:D8:54:8B:31:09:9F:2B:78:9C:7A:8F:19\r\na=setup:actpass\r\na=mid:audio\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=sendonly\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:3532204240 cname:1gIK2R1rv7SGcNxe\r\na=ssrc:3532204240 msid:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk a0bca7d6-ba1b-4e8b-b0a6-bf10da914c96\r\na=ssrc:3532204240 mslabel:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk\r\na=ssrc:3532204240 label:a0bca7d6-ba1b-4e8b-b0a6-bf10da914c96\r\nm=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:a0nE\r\na=ice-pwd:ORulArqBFPZdKcvGgvRvwBIf\r\na=fingerprint:sha-256 8F:54:90:66:E6:7D:72:C7:34:A7:53:9D:86:AA:EE:81:59:2B:5B:11:D8:54:8B:31:09:9F:2B:78:9C:7A:8F:19\r\na=setup:actpass\r\na=mid:video\r\na=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:4 urn:3gpp:video-orientation\r\na=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=sendonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:100 VP8/90000\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtpmap:101 VP9/90000\r\na=rtcp-fb:101 ccm fir\r\na=rtcp-fb:101 nack\r\na=rtcp-fb:101 nack pli\r\na=rtcp-fb:101 goog-remb\r\na=rtcp-fb:101 transport-cc\r\na=rtpmap:107 H264/90000\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:116 red/90000\r\na=rtpmap:117 ulpfec/90000\r\na=rtpmap:96 rtx/90000\r\na=fmtp:96 apt=100\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=101\r\na=rtpmap:99 rtx/90000\r\na=fmtp:99 apt=107\r\na=rtpmap:98 rtx/90000\r\na=fmtp:98 apt=116\r\na=ssrc-group:FID 3312749268 2262839535\r\na=ssrc:3312749268 cname:1gIK2R1rv7SGcNxe\r\na=ssrc:3312749268 msid:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk 7c632de7-042b-47de-ad66-b71a42473e4a\r\na=ssrc:3312749268 mslabel:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk\r\na=ssrc:3312749268 label:7c632de7-042b-47de-ad66-b71a42473e4a\r\na=ssrc:2262839535 cname:1gIK2R1rv7SGcNxe\r\na=ssrc:2262839535 msid:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk 7c632de7-042b-47de-ad66-b71a42473e4a\r\na=ssrc:2262839535 mslabel:ARXZtIyb8qqRcyyz8QMrROUmfjanFaazS5Mk\r\na=ssrc:2262839535 label:7c632de7-042b-47de-ad66-b71a42473e4a\r\n",
  "info" : "Keep Alive",
  "record" : false,
  "width" : 0,
  "height" : 0,
  "bitrate" : 0,
  "quality" : 0,
  "mediaProvider" : "WebRTC"
}
 
Last edited:

Max

Administrator
Staff member
По-умолчанию, 403 игнорируется.
Поэтому в методе connect, нужно явно задать конфигурацию для StreamKeepAliveEvent
В этом топике обсуждалось как это сделать:
http://forum.flashphoner.com/threads/Пароль-для-публикации-потока.10760/
Т.е. нужно явно передать такое поле в ответе на connect:
Code:
...
"restClientConfig":{ 
  "StreamKeepAliveEvent":{ 
    "restExclude":"",
    "clientExclude":"",
    "restOnError":"FAIL",
    "restPolicy":"NOTIFY",
    "restOverwrite":""
  }
}
...
Здесь
Code:
"restOnError":"FAIL"
означает, что WCS будет сбрасывать стрим если получит ошибку 4xx с REST.
 

Max

Administrator
Staff member
Code:
если 3 подключения, то идут они пачкой , а не по интервалу , каждый отдельно
StreamKeepAliveEvent отправляется в отдельном внутреннем потоке исполнения thread и вызывается для всех стримов приложения (app).
Т.е. при проходе запросы будут идти один за другим без каких-либо интервалов. И если у вас 1 стрим публикует и 5 стримов играют, то за цикл будет проходить 6 вызовов для каждого из них.
 

pride

Member
Выше в примере используется REST.
Т.е. это должен быть HTTP POST запрос с Content Type application/json и корректным JSON-объектом в теле сообщения.
Потестировать можно с помощью расширения Chrome - Advanced REST Console
А где найти список всех доступных методов API, в частности нужно получить список всех (published/PLAYING) активных стримов?
Нашел здесь:
Code:
 https://flashphoner.com/docs/wcs5/wcs_docs/html/ru/wcs-user-guide/
Но неужели у API всего два метода?
 
Last edited:

Max

Administrator
Staff member
Вся информация об активных стримах приходит через REST Hooks, т.е. вам на стороне сервера нужно реализовать бэкенд, который будет ее обрабатывать.
В прямом REST API действительно не много методов и все они сейчас разбросаны по документации.
В аттаче PDF файл. Там перечислены все действующие на данный момент методы REST API.
Если нужно что-то еще, сообщите. Мы планируем прямое REST API скоро расширять и нормально документировать.
 

Attachments

pride

Member
Вся информация об активных стримах приходит через REST Hooks, т.е. вам на стороне сервера нужно реализовать бэкенд, который будет ее обрабатывать.
В прямом REST API действительно не много методов и все они сейчас разбросаны по документации.
В аттаче PDF файл. Там перечислены все действующие на данный момент методы REST API.
Если нужно что-то еще, сообщите. Мы планируем прямое REST API скоро расширять и нормально документировать.
А app-rest-method типа Disconnect нет? Или как можно отследить на стороне WEB сервера что пользователь отвалился?
 
Last edited:

Max

Administrator
Staff member
Есть rest-method ConnectionStatusEvent
Если клиент закрыл браузер, то придет http://appurl/ConnectionStatusEvent и в теле будет поле status=DISCONNECTED
Дисконнект подробно описан в документации Call Flow
 

pride

Member
Есть rest-method ConnectionStatusEvent
Если клиент закрыл браузер, то придет http://appurl/ConnectionStatusEvent и в теле будет поле status=DISCONNECTED
Дисконнект подробно описан в документации Call Flow
Спасибо. Возник еще один вопрос:
- Как с WEB сервера вернуть (к примеру) описание ошибки клиенту в браузер ?? Что бы выдать пользователю сообщение по какой причине он был отключен.
 

Max

Administrator
Staff member
На стороне браузера будет так
Code:
session.createStream(...).on(STREAM_STATUS.FAILED, streamFailedHandler).play();
function streamFailedHandler(stream){
   trace(stream);
}
Web-сервер возврашает например 403 Forbidden, тогда объект stream в обработчике ошибок будет содержать поля:
Code:
status = 403;
info = "Forbidden";
Слово Forbidden можете заменить на кастомное, например Authentication failed, тогда будет
Code:
status = 403;
info = "Authentication failed";
Т.е. php-скрипт должен отдать HTTP статус и кастомный Reason Phrase
 

pride

Member
Чтобы завершить поток на стороне сервера, нужно выполнить REST-запрос terminate, как показано здесь
Чтобы получить список текущих стримов, нужно выполнить REST-запрос: findStreams
Пример:
Code:
http://streaming.flashphoner.com:9091/RESTCall/findStreams
Body
Code:
{"published":"false"}
Как настроить авторизацию на connect/publish/play, недавно обсуждали здесь.
Возможно ли передать какой то параметр при REST-запросе terminate, чтобы оповестить фронтенд (js) по какой причине была убита медиасессия ?
Пример :
Code:
{

   "sessionId" : "/10.10.10.10:50159/10.10.10.10:8080",
   "mediaSessionId" : "41c3f621-a847-4639",
   "published" : true,
   "info" : "Bad input params"
}
 

Max

Administrator
Staff member
Можно следом отправить пользователю сообщение
http://host:9091/RESTCallback/sendData
Code:
{ 
"nodeId":"wdqwdqwdqwd",
"sessionId":"/10.10.10.10:50159/10.10.10.10:8080",
"operationId":"myCustomOperation",
"payload": {"info":"Not enough balance"}
}
В последнем JS API это придет как
Code:
session.on(SESSION_STATUS.APP_DATA, function (data){...});
 

pride

Member
Можно следом отправить пользователю сообщение
http://host:9091/RESTCallback/sendData
Code:
{
"nodeId":"wdqwdqwdqwd",
"sessionId":"/10.10.10.10:50159/10.10.10.10:8080",
"operationId":"myCustomOperation",
"payload": {"info":"Not enough balance"}
}
В последнем JS API это придет как
Code:
session.on(SESSION_STATUS.APP_DATA, function (data){...});
И еще вопрос. Можно ли при событии "streamStatusEvent" вернуть ошибку, чтобы пользователь отвалился ?
 

Max

Administrator
Staff member
StreamStatusEvent - это событие, которое не является прямым вызовом вроде publishStream или playStream и следовательно его отбой не должен влиять на исполнение.
У нас по-дизайну заложена возможность вернуть, например, 403 Forbidden на такое событие, и получить SESSION_STATUS.WARN на клиенте, но это пока не реализовано. А когда будет реализовано, это будет простой нотификацией, опять же не влияющей на выполнение. Если нужно явно прервать поток, нужно это делать с помощью вызова terminate.
 

Max

Administrator
Staff member
чтобы пользователь отвалился ?
Для этого нам нужно добавить REST-функцию disconnect() - чтобы совсем отцепить пользователя.
 
Top