На Хабре уже была отличная статья по теме, но в ней нет ничего о классе NetGroup, о котором я и хочу поведать. Так же подробно расскажу о подключении, но передача данных через NetGroup будет осуществляться другим способом. Помимо потоковых данных вы научитесь передавать любые сообщения.
Итак, что же такое P2P во Flash? Осуществлять прямые подключения между экземплярами Flash Player позволяет RTMFP — Real-Time Media Flow Protocol. Суть его в том, что клиент лишь единожды обращается к серверу для установления подключения с другими клиентами сети, после чего, получив уникальный Peer ID, клиент может пересылать любые данные напрямую.
Adobe предоставляет бесплатный сервис Adobe Cirrus (подробнее о нем можно почитать на странице Adobe Labs), который предназначен, скорее, для демонстрации возможностей RTMFP, поэтому мы не сможем выполнять свой код или изменить что-то на стороне сервера. Конечно же, ничто не мешает нам поднять собственный сервер, совместимый с протоколом RTMFP, но для наших скромных целей подходит Cirrus.
Для доступа к возможностям сервиса нам необходимо, в первую очередь, получить ключ разработчика, который привязывается к аккаунту Adobe. Он понадобится нам в дальнейшем для подключения к сервису.
Думаю, лучшим способом познакомиться с возможностями является написание своего класса, который было бы удобно использовать в будущем.
Процесс организации пиринговой сети с использованием Cirrus выглядит в следующим образом:
1. Подключаемся к Cirrus и получаем ID клиента (peerID).
2. Настраиваем нашу группу (NetGroup).
NetGroup — класс, который предоставляет информацию о группе, в которой находится клиент. Чтобы обмениваться сообщениями, нам понадобится собрать всех наших клиентов в одной такой группе.
3. Обрабатываем событие NetStatusEvent.NET_STATUS.
NetStatusEvent.NET_STATUS — событие, происходящее при любых изменениях внутри группы.
4. Добавляем базовые возможности для отправки сообщений.
Теперь перейдем к написанию класса…
Для этого нам нужен класс flash.net.NetConnection, создающий соединение между клиентом и сервером.
Функцию connect(), инициализирующую подключение я реализовал так:
Итак, что же такое P2P во Flash? Осуществлять прямые подключения между экземплярами Flash Player позволяет RTMFP — Real-Time Media Flow Protocol. Суть его в том, что клиент лишь единожды обращается к серверу для установления подключения с другими клиентами сети, после чего, получив уникальный Peer ID, клиент может пересылать любые данные напрямую.
Сервер
Adobe предоставляет бесплатный сервис Adobe Cirrus (подробнее о нем можно почитать на странице Adobe Labs), который предназначен, скорее, для демонстрации возможностей RTMFP, поэтому мы не сможем выполнять свой код или изменить что-то на стороне сервера. Конечно же, ничто не мешает нам поднять собственный сервер, совместимый с протоколом RTMFP, но для наших скромных целей подходит Cirrus.
Для доступа к возможностям сервиса нам необходимо, в первую очередь, получить ключ разработчика, который привязывается к аккаунту Adobe. Он понадобится нам в дальнейшем для подключения к сервису.
План действий
Думаю, лучшим способом познакомиться с возможностями является написание своего класса, который было бы удобно использовать в будущем.
Процесс организации пиринговой сети с использованием Cirrus выглядит в следующим образом:
1. Подключаемся к Cirrus и получаем ID клиента (peerID).
2. Настраиваем нашу группу (NetGroup).
NetGroup — класс, который предоставляет информацию о группе, в которой находится клиент. Чтобы обмениваться сообщениями, нам понадобится собрать всех наших клиентов в одной такой группе.
3. Обрабатываем событие NetStatusEvent.NET_STATUS.
NetStatusEvent.NET_STATUS — событие, происходящее при любых изменениях внутри группы.
4. Добавляем базовые возможности для отправки сообщений.
Теперь перейдем к написанию класса…
Написание класса
1. Подключаемся к Cirrus
Для этого нам нужен класс flash.net.NetConnection, создающий соединение между клиентом и сервером.
Функцию connect(), инициализирующую подключение я реализовал так:
// Подключение
public function connect()
{
netConnection = new NetConnection(); // переменная netConnection объявлена в теле класса
// Событие NET_STATUS нужно для отслеживания состояния подключения к серверу
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
// Пример: "rtmfp://p2p.rtmfp.net/abcdefghijklmnopqrstu-ads12asfv"
netConnection.connect("rtmfp://p2p.rtmfp.net/" + "Ваш ключ разработчика");
}
// Функция прослушивания событий NetStatusEvent
private function netStatusHandler( e:NetStatusEvent ):void
{
switch ( e.info.code )
{
case "NetConnection.Connect.Success":
trace ("Успешное подключение к серверу!")
// Подключились к Cirrus'у - переходим к настройке нашей группы
setupNetGroup();
break;
case "NetGroup.Posting.Notify":
// Событие получения сообщения
messageReceived(e.info.message);
break;
}
}
// Настройка группы
private function setupNetGroup ():void
{
}
// Обработка входящих сообщений
private function messageReceived (message:Object):void
{
}
* This source code was highlighted with Source Code Highlighter.
Так же я заранее объявил еще три функции:
netStatusHandler — прослушивание событий от NetConnection.
setupNetGroup — вызывается при успешном подключении к серверу для настройки группы.
messageReceived — вызывается при получении сообщения от другого клиента.
2. Настраиваем класс NetGroup
Для отправки сообщений другим пользователям в сети нам нужно создать группу, в которую эти сообщения и будут отправляться.
В нашем классе за настройку группы отвечает функция setupNetGroup().
Класс GroupSpecifier позволяет задать параметры группы для ее создания. Так как и netConnection и netGroup для оповещения о своем состоянии используют события NetStatusEvent, то для прослушивания событий будет использоваться та же функция, что и для netConnection — netStatusHandler:
// Настройка группы
private function setupNetGroup ():void
{
var groupSpecifier:GroupSpecifier = new GroupSpecifier("НазваниеГруппы");
groupSpecifier.serverChannelEnabled = true; // Для обмена с сервером
groupSpecifier.postingEnabled = true; // Разрешаем отправку сообщений в группе
// переменная netGroup объявлена в теле класса
netGroup = new NetGroup(netConnection, groupSpecifier.groupspecWithAuthorizations() );
netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); // Прослушка событий группы
}
* This source code was highlighted with Source Code Highlighter.
3. Обрабатываем NetStatusEvent
Теперь нам необходимо понять, для чего нужны события NetStatusEvent. Рассмотрим функцию netStatusHandler:
// Функция прослушивания событий NetStatusEvent
private function netStatusHandler( e:NetStatusEvent ):void
{
trace(e.info.code);
switch ( e.info.code )
{
case "NetConnection.Connect.Success":
trace ("Успешное подключение к серверу!")
// Подключились к Cirrus'у - переходим к настройке нашей группы
setupNetGroup();
break;
case "NetGroup.Posting.Notify":
// Событие получения сообщения
messageReceived(e.info.message);
break;
}
}
* This source code was highlighted with Source Code Highlighter.
Событие NetStatusEvent.NET_STATUS возвращает в e.info.code строку, обозначающую событие NET_STATUS.
Нам понадобились только два события (на самом деле их намного больше, можно посмотреть здесь):
«NetConnection.Connect.Success» — успешное подключение netConnection к серверу Cirrus.
«NetGroup.Posting.Notify» — получение входящих сообщений, обработку которых мы рассмотрим далее.
4. Обмен сообщениями.
При получении нового сообщения вызывается функция messageRecieved, в которую передается сообщение. Из этой функции мы просто вызовем внешнюю функцию, в которой и будет происходить обработка…
// Обработка входящих сообщений
public var callback_messageReceived:Function; // callback
private function messageReceived (message:Object):void
{
if (callback_messageReceived)
callback_messageReceived ( message );
}
* This source code was highlighted with Source Code Highlighter.
Осталось написать функцию отправки сообщения. Всё, что она должна делать, — вызывать netGroup.post():
public function sendMessage( message:Object ):void
{
if (!message)
return;
netGroup.post(message); // Отправляем сообщение в группу
}
* This source code was highlighted with Source Code Highlighter.
Заключение
Я считаю, что P2P во Flash — очень интересная возможность! Было бы великолепно, если бы ее использовали в играх, ведь пинг при подключении напрямую намного меньше, да и не нужен огромный сервер, синхронизирующий всех игроков между собой.
В общем, спасибо за прочтение, надеюсь, статья хоть немного заинтересовала вас ;)
Конечно же, ссылка на сам класс: P2PConnection.as