Пользователь
0,0
рейтинг
17 октября 2011 в 11:22

Разработка → Adobe Flash Player и передача потоковых данных без участия сервера, часть 1-я: организация пирингового вещания из песочницы

    Как известно недавнее обновление продуктов Adobe Flash Player до 10.1 и Adobe AIR до 1.5 версий осуществило целый фурор, презентовав новый протокол связи Real-Time Media Flow Protocol (RTMFP). Заранее попрошу не путать вышеупомянутый с Real-Time Messaging Protocol (RTMP) для использования которого был необходим Adobe Flash Media Server (FMS) на стороне обслуживающего сервера.
    Разработчики обещают, что протокол будет обладать низкой задержкой во времени при пересылке пакетов, но самое главное, протокол ориентирован на организацию пиринговой сети.
    Более ранние версии Flash Player использовали передачу данных в режиме реального времени по протоколу RTMP и требовали серьёзных финансовых затрат. Для функционирования Adobe Flash Media Server (FMS) необходим очень дорогой и прихотливый хостинг (вплоть до аренды физического сервера, т.к. ресурсов всё это дело есть немало, и устанавливается как отдельный программный мод в систему сервера).
    RTMP является оптимальным выбором для потокового мультимедиа, общего доступа к различным данным, или удаленного/одновременного их использования.
    Итак, вернёмся, новый протокол (RTMFP) уже получил прозвание «пиринговый», т.к. для работы AIR и Flex приложений нет строгой необходимости в стороннем медиа-сервере. Почему «строгой», потому, что сервер — таки есть, но не тот который обрабатывает/хранит мультимедиа и другие данные, а тот который лишь контролирует сессии между клиентами (пирами) и распределяет трафик.
    Как говорится в послании Jozsef Vass (Джосефа Васс, старший научный сотрудник компании Adobe/Flash Runtime Foundation ранее работавшего в компании новаторских технологии VoIP) «Cirrus service for developing end-to-end applications using RTMFP in Flash Player 10» (пер. на рус. «Cirrus сервис для разработки конечных приложений с помощью RTMFP в Flash Player 10») для того чтобы использовать RTMFP, Flash Player пира должен подключится к RTMFP-совместимому серверу, например такому как Cirrus (ранее известному под кодовым именем Stratus) или Flash Media Server 4. В статье говорится, что Cirrus это сетевой сервис, который помогает устанавливать связи между клиентами (пирами) через их Flash плееры. Исходя из материалов и приложений статьи, подобный сервер можно организовать и на своём веб-ресурсе, (см. исходники в приложении, файл «reg.cgi»).

    О преимуществах RTMFP
     — протокол не управляется по Transmission Control Protocol (TCP) из-за его привычки повторно досылать потерянные пакеты данных, а базируется на User Datagram Protocol (UDP), что уменьшает время отклика между клиентами (пирами) и сервером. Кроме того, UDP в большинстве случаев не блокируется брандмауэрами, что освобождает от донастройки сетевых экранов;
     — данные пересылаются непосредственно между двумя клиентами Flash Player в режиме реального времени без маршрутизации через центральный сервер;
     — поддерживается передача мультимедиа в высоком качестве, ровно в таком, сколько может позволить себе ширина канала Интернет между двумя клиентами (пирами);
     — наличие своей, т.е. Адобовской службы управления потоком Cirrus, по адресу: rtmfp://p2p.rtmfp.net, которая проверяет возможность использования протокола по ключу-разработчика. Ещё раз повторюсь не имеет ничего общего с Flash Media Server. Cirrus используются исключительно для того, чтобы экземпляры Flash Player смогли найти друг друга в сети.
     — безопасное соединение достигается посредством 128-битного AES с использованием метода обмена ключами Diffie-Hellmann. Поддержка SSL или RTMPS.
     — наличие отдельных классов в ActionScript 3.0.

    Организация пирингового вещания
    Перед использованием Adobe Cirrus Вы должны получить ключ разработчика от Adobe Labs. Пиры могут связаться друг с другом, не используя Cirrus. Для этого требуется, чтобы клиенты были в одной локальной сети, что крайне редко.
    Чтобы соединиться со службой Adobe Cirrus, необходимо создать экземпляр NetConnection. При соединении должно передаваться 2 строковых параметра: Adobe Cirrus URL и Ваш ключ разработчика, как показано ниже:

private const CirrusAddress:String = "rtmfp://p2p.rtmfp.net";
private const DeveloperKey:String = "your-developer-key";
private var netConnection:NetConnection;
netConnection = new NetConnection();
// Добавляем детектор (listener) для получаения информации о статусе соединения
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnectionHandler);
// Соединяемся со Cirrus
netConnection.connect(CirrusAddress, DeveloperKey);

    В случае, если со Cirrus состоялось успешное соединение, у NetStatusEvent.NET_STATUS свойству info.code будет присвоена строка «NetConnection.Connect.Success».
    Примечания: В настоящий момент метод NetConnection.call() не поддерживается при использовании Cirrus. Любой вызов NetConnection.call() будет проигнорирован Cirrus. Разработчики рекомендуют не использовать метод NetConnection.call() при использовании RTMFP со Cirrus, поскольку это будет увеличивать потребление памяти у клиента без необходимого функционального эффекта.
    Как только экземпляр Flash Player успешно соединился со службой Cirrus, он получит уникальный 256-битный peer_ID, который служба Cirrus будет использовать, для привязки его к IP-адресу и номеру порта клиента, чтобы другие клиенты Flash Player имели возможность связаться с ним.
    Новый Cirrus 2 server channel и Flash Player 10.1, теперь может использоваться, чтобы помочь сформировать самоуправляемые P2P сети без необходимости в ручном обмене peer_ID. Это позволяет множеству клиентов Flash Player связаться непосредственно друг с другом наиболее эффективным способом.
    Далее, устанавливается соединение с клиентом (пиром). Прямая потоковая передача достигается с использованием однонаправленного NetStream канала. А если вы хотите двустороннюю передачу данных, каждый клиент Flash Player должен создать NetStream для отправки и NetStream для получения данных:

// для отправки потока данных пиру
private var sendStream:NetStream;
sendStream = new NetStream(netConnection, NetStream.DIRECT_CONNECTIONS);
sendStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
sendStream.publish("media");
sendStream.attachAudio(Microphone.getMicrophone());
sendStream.attachCamera(Camera.getCamera());

// для получения потока данных от пира
private var recvStream:NetStream;
recvStream = new NetStream(netConnection, id_of_publishing_client);
recvStream.addEventListener(NetStatusEvent.NET_STATUS, netStreamHandler);
recvStream.play("media");

    Вещатель потока может осуществлять непосредственный контроль на тем, кто сможет принимать вещаемые им данные. Когда клиент попытается осуществить доступ к опубликованному потоку, вызовется метод onPeerConnect() (по умолчанию реализация просто возвращает true ) на опубликованный NetStream и пир получает доступ к данным), чтобы этого не происходило, можно реализовать проверку клиентов(пиров) на права к данному потоку по объекту "accept":
var o:Object = new Object();
o.onPeerConnect = function(subscriberStream:NetStream):Boolean {
if (accept) {
return true;
} else {
return false;
}
}
sendStream.client = o;

    На стороне вещателя, NetStream.peerStreams свойство присущее всем подписавшимся пирам. Например, с помощью метода sendStream.send() поток будет отсылаться для всех пиров, но можно направить поток и конкретному получателю:
sendStream.peerStreams[i].send();

    Необходимо упомянуть ещё об двух свойствах, это — NetConnection.maxPeerConnections и NetConnection.unconnectedPeerStreams.
    NetConnection.maxPeerConnections — определяет число пиров, которым разрешено подключаться к вещателю. По умолчанию это свойство имеет значение 8, но на практике, может быть и больше. Каждый клиент Flash Player отправляет и получает два потока, создавая тем самым полноценную сеть. Так как ширина канала Интерент по download`у, как правило, намного выше, чем upload`у, необходимо быть очень осторожным, чтобы не перегрузить входящий канал от подписавшегося пира.
    NetConnection.unconnectedPeerStreams свойство, которые содержит в массиве пиров ещё не подписанных на вещаемый поток данных. При подписании на вещание патока имя пира переходит из данного массива в массив NetStream.peerStreams.

    Все, пока на этом всё. Единственное, что ещё хотелось бы добавить это то, что как и любой любопытный человек, решил проверить все описанные выше возможности протокола.
    Проверка осуществлялась на предмет зависимости Приложений от Сервера Сирруса.
    На сайте Лаборатории Адоба, есть неплохой пример: «Cirrus Sample Application». Исходники можно скачать и разобрать по костям здесь: http://download.macromedia.com/pub/labs/cirrus/cirrus_app_assets_v5.zip
    Так, вот, тестирование проводилось в домашней сети. Сначала заходил с ноутбука подключенному к сети Интернет через стационарный ПК, регистрировался в этой демке от Адоб Лаба, потом тоже самое на делал на стационарном ПК, делал коннект по зарегистрированным именам, а потом отключал доступ к сети Интрнет. Вердикт, 15 минут (видимо столько живет сессия вещания потоковых данных по peer_ID) отличной связи между двумя веб-камерами установленными на разных машинах. Такой себе локальный сам-себе-месенджер на коленке.
    Всё, всем желаю удачи. Жду приглашение в армию Хабра-воинов. Часто постить не обещаю, но все же… люблю поделиться интересным.
W.D.M.Group @WDMGroup
карма
6,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (30)

  • 0
    Спасибо! Очень интересная статья.
    В следующей серии хотелось бы услышать о NetGroup и о методе post(), а конкретно — почему при соединении NetGroup не сразу возможно вызывать метод post()
  • –2
    Хорошая статья! Жду часть 2!
  • +7
    недавнее обновление продуктов Adobe Flash Player до 10.1 и Adobe AIR до 1.5

    С недавним вы загнули) Этому обновлению уже третий год) Ныне актуальны версии 11 и 3 соответственно)
    Тем не менее статья у вас отличная, ждем продолжения. Я вот недавно убил не мало времени на поднятие сервера для подобных целей…
    • 0
      Вот это как раз самое и интересное как поднять соединения на собственном сервере, а в статье пусто.
      • +1
        Если локально, можно попробовать скачать исходник из статьи (ссылка в посте), установить Денвер или УСБВебсервер, залить это всё в РООТ, создать БД, настроить reg.cgi и дело в шляпе.
        • 0
          Нее, мой интерес глубже — расшифровка того, что возвращает в XML скрипт флешке.
  • –1
    | — протокол не управляется по Transmission Control Protocol (TCP) из-за его привычки повторно досылать потерянные пакеты данных, а базируется на User Datagram Protocol (UDP)

    Что то не ладно в этом мире… tcp в противовес udp содержит механизмы предотвращения потери данных из-за потери пакетов и отсутствия необходимости контролировать это на верхних уровнях… а udp — нет
    • +2
      Для медиапотоков часто более приемлемо потерять пакеты, чем тратить время на ретрансмит.
  • +3
    Порадовало использование домена macromedia. Прям аж в груди защемило.
  • +1
    Для RTMP не обязателен Adobe Flash Media Server, есть альтернативы в виде Red5, rtmpd, Wowza и другие…

    В качестве RTMFP совместимого сервиса, точнее регистратора потоков, может выступать не только FMS4 или Cirrus, мы используем простой сервис Cumulus. В нем есть ряд проблем, но для передачи видео потоков между пользователями напряму более чем подходит.

    В целом RTMFP местами сильно упрощает разработку сложных сервисов, но целиком без централизованного управления не обойтись. Простой пример: есть централизированный сервис видео конф. и есть два филиала, которые к нему подключены, общение между филиалами удобнее делать через центральный сервис, а обмен внутри офиса выгоднее делать через пиринговую сеть.

    • 0
      Из (печального) опыта использования: примерно в 10% случаев соединения не устанавливается — не может пробиться через NAT. В этом случае FP начиная с 10.2 и Adobe Flash Media Server позволяют прозрачно откатиться на обмен через сервер. В этом плане вариант с Cumulus подходит для корпоративных видеоконференций, а для широкой публики — не слишком.
      • 0
        UDP Hole они вроде внедрили и используют, если я не ошибаюсь.
        • 0
          Это помогает не всегда, к сожалению. Сами столкнулись с довольно распространённой траблок у клиентов — тупо подключиться к игрушкам не могли ибо в офисах злые админы всё режут :-)
    • 0
      Если я не ошибаюсь, то протокол закрытый и его эмулируют по reversengineering`у, так что адоб всеравно не прав.
      Попробуйте erlyvideo.org — как любят говорить, отечественная разработка.
      • 0
        Ерли требует сервера. Не всегда это оправдано, очень часто для минимизации задержки намного удобнее быстрее и проще юзать именно RTMFP, проверено на собссной шкуре.
        • 0
          Так, я предлагал erlyvideo для замены Red5, rtmpd, Wowza, а не для замены протокола.
          • 0
            Ааа, по сравнению с ними конеш эрли рулит. Я вот после проверки всяких разных серверов в итоге к rtmpd и к ерли и пришёл, ими двумя и пользуюсь.
  • +2
    Вообще-то уже более года этому «новшеству», его уже даже вконтакт и прочие используют.
    • 0
      При этом почему-то статей о нём крайне мало. Хотя фича очень интересная. Вот любопытно, хоть когда-нибудь в HTML5 что-то подобное будет? Кстати, краем уха слышал (сейчас искать не с руки), что с 10.2 Flash Player умеет и файлы через P2P слать…
  • 0
    Как-то не освещен вопрос о досутпе к потоку посторонних лиц. Если узнать ид потока, то, как я понял, поднимая однажды свою пиринговую раздачу видео, к потоку сможет подключиться любой клиент.

    В статье есть o.onPeerConnect = function(subscriberStream:NetStream):Boolean, но не сказано, откуда берется объект accept и с чего вдруг он будет знать, что кому-то можно, а кому-то нет.
    • 0
      На серверной стороне достаточно сделать ограничение по домену и практически ноу проблем.
      • 0
        Спасибо :)
    • 0
      accept — параметр который, я палагаю, можно взять другим методом, может отдельной проверкой по базе MySQL или как-то иначе.
    • +1
      Вопрос о доступе к потоку посторонних лиц будет освещён во 2-ой части про Группы пиринговых сетей и безопасность.
  • +1
    «недавнее обновление продуктов Adobe Flash Player до 10.1 и Adobe AIR до 1.5 версий осуществило целый фурор, презентовав новый протокол связи Real-Time Media Flow Protocol (RTMFP)»

    Ээээ, собссно RTMFP аж с начала весны доступен. Мы его с конца марта юзаем как основной протокол для наших машинок, так что насчёт недавнего обновления вы немного погорячились :-)
    • 0
      эх, сорри, верхние комменты не прочёл, там уже аналогично высказывались
  • 0
    К огромному сожалению, флэш не позволяет никаким макаром с ip-камерами общаться. Так что и рад бы в текущем проекте RTMFP использовать, а не могу ибо ip-камеры. Вот и приходится с ерливидео мудрить :-(
    • 0
      апдейт: MJPG можно но коряво и только в AIR, а вот RTSP хрен там :-( Когда ж Адоб это наконец-то реализует

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.