Как стать автором
Обновить

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

Время на прочтение6 мин
Количество просмотров18K
    Как известно недавнее обновление продуктов 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) отличной связи между двумя веб-камерами установленными на разных машинах. Такой себе локальный сам-себе-месенджер на коленке.
    Всё, всем желаю удачи. Жду приглашение в армию Хабра-воинов. Часто постить не обещаю, но все же… люблю поделиться интересным.
Теги:
Хабы:
+39
Комментарии30

Публикации