Přejít k navigační liště

Zdroják » Různé » Flash: Webová Peer-to-Peer aplikace

Flash: Webová Peer-to-Peer aplikace

Články Různé

Flash není jen animace, reklamy, Flex, reklamy, video a reklamy. Flash player v sobě obsahuje věci, které byste pravděpodobně nečekali, jako je podpora P2P. Ta je ve Flashi od roku 2008 a lze ji použít ve webových aplikacích, kde může ušetřit obrovské množství přenesených dat, a to nejen při streamování videa.

P2P ve Flashi je dokonalou ukázkou jeho technické pokročilosti. I když se podpora datuje do roku 2008 (k termínu uvedení Flash Playeru 10), samotná diskuse na toto téma začala již v roce 2006. Později Adobe koupilo firmu Amicima, která pracovala na pokročilých P2P řešeních.

V kontextu Flashe se jedná o pokročilé téma, které příliš lidí zatím nezná, ale které si postupně získává čím dál větší kredit.

P2P

Když se řekne P2P, tak si většina lidí představí sdílení souborů a možná instant messaging či VoIP. Málokdo si však už představí např. distribuovanou televizi (Joost), distribuci živých streamů či reálný užitek ve webových aplikacích.

Ano – P2P je především obrovská úleva pro poskytovatele obsahu. Uživateli jako takovému je to víceméně jedno (ten pouze konzumuje obsah), ale i on ocení, že mu streamovaná data posílá kolega z vedlejšího domu se silnější linkou – a plynuleji – než přetížený server z USA.

Základní informace o P2P ve Flashi

Stavebním kamenem je protokol RTMFP (Real Time Media Flow Protocol), který je postavený na UDP, což je rozdíl oproti otevřenému protokolu RTMP (Real Time Messaging Protocol) postaveném na TCP. UDP je mnohem vhodnější na aplikace typu VoIP či video přenosy, protože má menší latenci, ale mohou se v něm objevit ztráty. Data jsou v RTMFP šifrována pomocí 128-bit AES. Podporuje také IP Mobility – v případě změny připojení či IP adresy se spojení automaticky znovu naváže. Dále RTMFP podporuje NAT Traversal, tudíž nemusíte mít veřejnou IP adresu.

Typy P2P sítí (Point-to-Point, Swarming, Application-Level-Multicast, DHT):

Flash P2P ilustrace

Zjednodušeně jsou ve Flashi jsou dva základní přístupy pro práci s P2P:

Point-to-Point

Umožňuje propojit 2 klienty mezi sebou a posílat data mezi nimi. Nicméně můžete propojit i více klientů mezi s sebou, ale každé spojení vyžaduje separátní NetConnection, resp. NetStream. Tento přístup je k dispozici ve Flash Playeru 10 a je v praxi složitější než přístup pomocí skupiny.

Skupina

K dispozici od Flash Playeru 10.1. Vytvoříte skupinu klientů (NetGroup), klienti se do ní připojí a můžou přijímat a odesílat data ostatním klientů této skupiny. K dispozici je několik metod:

  • Directed Routing: obdoba DHT (Distributed Hash Table), vyžaduje stabilní síť se správnou topologií a umožňuje posílat zprávy specifickým klientům v síti
  • Posting: odeslání zprávy (objektu) všem klientům ve skupině
  • Multicast: odeslání datového streamu klientům (zpravidla Audio, Video), pro Multicast se používá třída NetStream
  • Object Replication: zajišťuje doručení zpráv, UDP je ztrátový protokol a v případě Postingu nemáte stoprocentně zaručené, že všechny zprávy přijdou

Posting a Multicast jsou si velmi podobné. Posting je však navržený pro odesílání malých dat (chat) velkým množstvím odesilatelů (senders), zatímco multicast je spíš vhodný pro odesílání velkého množství dat (audio/video) menším počtem odesilatelů (broadcasters). Rozdíl je pouze v režii, která zajišťuje odeslání a doručení. Tato režie je v případě multicastu větší.

Unicast vs. Multicast

Většina čtenářů se už s těmito pojmy setkala. Krátce si je přiblížíme v kontextu Flashe.

Unicast je oddělený stream dat pro každého klienta, většinou od serveru ke klientovi. Když váš živý stream s 1 Mbps sleduje 1000 lidí, váš server pak odesílá 1 Gbps. Když vysíláte koncert pro 20.000 lidí (což je tak běžná online sledovanost známějšího koncertu), potřebujete cca 10 serverů + několik backup/peak serverů.

Multicast je distribuce streamu v rámci nějaké sítě. Tato síť může mít buď nativní podporu IP Multicastu (většinou v interní síti, na internetu příliš nefunguje), nebo se vytvoří tzv. Application-Level-Multicast (P2P Multicast), a nebo se vytvoří tzv. Fusion (fúze IP Multicastu a P2P Multicastu). IP Multicast je vždy výhodnější, ale musí mít podporu na straně routerů a musí být nastaven.

Distribuce streamu v multicastu pak funguje tak, že z vašeho serveru odešlete 1 Mbps stream, který se rozdistribuuje v rámci multicastové skupiny na klienty. Těch klientů může být i 20 000, ale z vašeho serveru jde pouze a stále jen 1 Mbps.

Jak P2P ve Flashi funguje

O propojení účastníků – peerů – se stará Adobe Stratus – tzv. Hosted Rendezvous Service – jinými slovy služba od Adobe, která zprostředuje „rande“ mezi peery. Peer se nejprve připojí na Stratus a přeloží svou adresu do unikátní informace, tzv. fingerprintu. Pomocí tohoto fingerprintu se pak identifikuje ostatním peerům. Ve Flash Playeru 10 propojujete peery nikoli pomocí IP adres, ale pomocí fingerprintů. V novém Flash Playeru 10.1 vytvoříte pouze skupinu a o fingerprinty se už nestaráte, jejich výměna se zprostředkuje na pozadí.

Základní schéma propojení dvou peerů pak vypadá zhruba takto: Peer si zažádá o fingerprint, ten předá nějakým způsobem druhému peeru, a druhý peer se může k tomuto fingerprintu připojit. Konkrétní forma předání fingerprintu záleží už na vaší vlastní implementaci.

Flash P2P ilustrace

Pavel Šimek vytvořil jednu z prvních P2P her ve Flashi – Mlýn. Můžete si ji zkusit zahrát a ověřit si fungování fingerprintů a P2P v praxi. Zalogujete se pod nějakým jménem, tím se vám vytvoří odkaz obsahující fingerprint, tento odkaz otevřete v druhém okně (v jiném prohlížeči, na druhém počítači doma, předejte jej kamarádovi, …), zadáte jméno a hra se spustí – hru tak hrajete ve dvou oknech prohlížeče (popř. s kamarádem).

P2P prakticky

V následující ukázce vytvoříme jednoduchý P2P chat pomocí skupin – konkrétně použijeme Posting. Budeme tedy cílit už na Flash Player 10.1.

K vytvoření budeme potřebovat

Flash P2P ilustrace

Krok 1: Přípojíme se k serveru

private const SERVER:String = "rtmfp://stratus.adobe.com/";
private const DEVKEY:String = "STRATUS-DEVELOPER-KEY";
private var nc:NetConnection;
private function connect():void{
    nc = new NetConnection();
    nc.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
    nc.connect(SERVER+DEVKEY);
}

Krok 2: Nadefinujeme skupinu

Skupina má jméno a nastavení, výsledkem je řetězec, který vrátí funkce groupspecWithAuthorizations(). K dispozici je i groupspecWithoutAuthorizations(). Rozdíl je, že když nastavíte heslo pro Posting nebo Multicast tak groupspecWithoutAuthorizations je receive-only, nemůže tedy odesílat data,  groupspecWithAuthorizations analogicky může. My data odesílat chceme, proto použijeme  groupspecWithAuthorizations.

private function setupGroup():void{
    var groupspec:GroupSpecifier = new GroupSpecifier("myGroup/g1");
    groupspec.serverChannelEnabled = true;
    groupspec.postingEnabled = true;

    netGroup = new NetGroup(nc,groupspec.groupspecWithAuthorizations());
    netGroup.addEventListener(NetStatusEvent.NET_STATUS,netStatus);

    user = "user"+Math.round(Math.random()*10000);
}

GroupSpecifier

Řetězec definující skupinu. Každá skupina se liší nejenom jménem, ale i nastavením. Můžete nastavit následující vlastnosti:

  • routingEnabled
  • multicastEnabled
  • objectReplica­tionEnabled
  • peerToPeerDisabled – v případě multicastu definuje, že se má použít pouze Native IP Multicast například v nějaké interní síti, ne P2P Multicast či Fusion. Native IP Multicast ma tu výhodu, že nezobrazí dialog, kde musíte potvrdit, že se sdílením v rámci P2P souhlasíte. Stream do Native IP Multicast nelze poslat z Flash Playeru, ale pouze z Flash Media Serveru (budoucí verze). Funguje zde také LAN Discovery, Flash Player si najde nejbližší vhodné klienty a sníží tak latenci streamu.
  • ipMulticastMem­berUpdatesEna­bled
  • serverChannelE­nabled

Nastavením těchto vlastností změníte specifikaci skupiny a jelikož je GroupSpecifier řetězec, změní se i tento řetězec, a vy se tak ocitnete v jiné skupině.

Krok 3: Zachycení stavových událostí

private function netStatus(event:NetStatusEvent):void{
    trace(event.info.code);

    switch(event.info.code){

        case "NetConnection.Connect.Success":
        // Uspesne jsme se pripojili k serveru
            setupGroup();
            break;

        case "NetGroup.Connect.Success":
        // Uspesne jsme se pripojili ke skupine
            connected = true;

            break;

        case "NetGroup.Posting.Notify":
        // Prisla nam zprava
            receiveMessage(event.info.message);
            break;
    }
}

Krok 4: Odeslání zprávy

Vytvoříme objekt, do kterého zabalíme zprávu. Každá zpráva by měla mít nějaký unikátní identifikátor (sequence). Pokud odešleme stejnou zprávu bez unikátního identifikátoru, tak se podruhé nedoručí, všichni klienti už si totiž budou myslet, že tuto zprávu obdrželi – vzhledem k distribuci (přeposílání) v rámci P2P sítě je to logické.

var sequence:Number = 0;
private function sendMessage():void{
    var message:Object = new Object();
    message.sender = netGroup.convertPeerIDToGroupAddress(nc.nearID);
    message.user = txtUser.text;
    message.text = txtMessage.text;
    sequence++
    message.sequence = sequence;

    netGroup.post(message);
    receiveMessage(message);

    txtMessage.text = "";
}

private function receiveMessage(message:Object):void{
    write(message.user+": "+message.text);
}

private function write(txt:String):void{
    txtHistory.text += txt+"n";
}

Krok 5: Vytvoříme uživatelské rozhraní

<s:TextArea left="10" right="10" top="10" bottom="40" id="txtHistory"/>
<s:TextInput x="10" id="txtUser" text="{user}" bottom="10"/>
<s:TextInput left="145" right="88" id="txtMessage" bottom="10" enter="sendMessage()"/>
<s:Button label="Send" click="sendMessage()" enabled="{connected}" bottom="10" right="10"/>

Aplikace je tímto hotová, můžeme si ji vyzkoušet.

Bootstrapping

V kontextu P2P označuje zjednodušeně přidávání peerů do skupiny. Můžete jej provádět manuálně, anebo nastavit serverChannelEnabled na true a využít tzv. auto-bootstrapping, díky kterému se klienti do skupiny přidají automaticky.

Nic není tak růžové, jak se zdá

Ačkoliv je P2P velmi účinná technika, tak bohužel ne vždy funguje, protože může být blokována na firewallu. Hodně firem, zejména těch větších, blokuje UDP a nestandardní porty. Z mé vlastní zkušenosti zpravidla běžní uživatelé s ADSL či využívající kabelového připojení mají P2P povolené, zatímco zaměstnanci ve firmách blokované. Tenhle fakt je potřeba brát v úvahu a uvědomit si jej při rozhodování o tom, na koho je vaše aplikace zacílena. V každém případě je možné vytvořit aplikaci, která bude fungovat přes P2P, pokud to podmínky umožní – pokud ne, lze udělat failover přes RTMPT či HTTP s větší latencí. Budoucí verze Flash Media Serveru bude obsahovat API, které umožní Flash Media Serveru ovládat P2P skupiny a propojit tak oba světy – RTMP a RTMFP.

Poznámka: Diskutoval jsem s inženýry RTMFP, proč nelze vyřešit P2P ve Flashi tak, aby fungovalo i přes firewally – např. podobným způsobem jako funguje Skype – pomocí super-nodů. Odpověděli, že to lze, a dokonce je možné tento způsob přidat do Flash Playeru. Adobe se ovšem rozhodlo tento způsob zatím neimplementovat, protože nechce, aby se z Flash Playeru stal P2P software typu Torrent, který je ve spoustě firem zakázán z bezpečnostních důvodů. Adobe aktuálním přístupem dává provozovatelům sítě volbu – P2P protokol pro Flash povolit nebo zakázat na firewallu. Pokud si přejete explicitně povolit supernode P2P ve vašem Flash Playeru, můžete zeditovat mms.cfg a nastavit RTMFPTURNProxy. Viz diskuse zde. – pozn.aut.

Závěr

V článku jsme se seznámili se základy P2P technik ve Flashi, a to konkrétně ve verzi 10.1. (Pokud si chcete zkusit programovat P2P aplikace pro Flash Player 10, začněte tímto videotutoriálem). Pokročilejší věci, jako jsou multicast či zabezpečení, si necháme v případě zájmu na další díl.

Další zdroje

Komentáře

Subscribe
Upozornit na
guest
17 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Tom5

Jak moc je tato implementace odolná vůči různým scénářům uživatelů a NATů.
Dík.

none_

Zajímavý článek. Moc díky. Ať si, kdo chce, co chce, říká, já mám tenhle seriál rád.:) Doufám, že budou další články…

kvas

plne suhlasim, naozaj dobry clanok.

Tom5

Nikdy jsem v ActionScriptu nedělal a tím spíš neznám interně ani Flash, tak omluvte základní dotaz. Navíc asi předbíhám díl (pokud bude, budu rád).

Záměrně se budu z důvodu větší obecnosti odkazovat na Flash plugin, nikoli na ActionScript jako jazyk.
Myslel jsem, že TCP spojení Flash navazuje skrz sockety/deskriptory web browseru (kvůli bezpečnosti, nastavení proxy apod.) Je to tak nebo není? (Tím myslím bez ohledu na API v ActionScriptu.)

Jak je to s UDP resp. RTMFP? Jak definuje Flash omezení na UDP spojení, aby se mi nekontrolovaně nenavazovala spojení v lokální síti? Četl jsem, že zatím v ActionScriptu není API pro obecný UDP socket. Jak je to ale s Flashem jako interpreterem SWF? Je to spíš v rovině, že nikdo neví (nemyslím to jako výtku)?

Tom5

Díky. Myslel jsem UDP v kontextu RTMFP. Získá potenciální autor vhodně vytvořeného flash objektu seznam lokálních IP adres strojů, které jsou online? (např. z rychlosti a stavu odpovědi volání RTMFP API)

Lze vhodným nastavením celého flash pluginu (nezávisle na objektu) omezit datové toky RTMFP?

pas2007

Ne, v RTMFP API se IP adresy nikde vůbec neobjevují.

V konfiguraci Flash Playeru se dá RTMFP úplně vypnout nebo nastavit TURN proxy, ale jestli nějak víc konfigurovat, to nevím, aspoň tedy v momentálně zdokumentovaných nastaveních nic není.

pas2007

K tomu TCP: Ano, requesty z Flashe se zobrazují např. ve Firebugu, takže přes browser jdou. Ale určitě má Flash Player tu funkčnost i sám o sobě, může běžet samostatně, jako AIR, na mobilech to je také kdovíjak… asi se to nedá jednoznačně říct, ostatně jako u každé crossplatformní černé skříňky.

Tom5

Je dostupný rendezvous server jako produkt nebo jen jako služba? Jak vypadá budoucnost?

Adobe Stratus je potřeba nejen k vygenerování fingerprintu, ale i pro asistenci při vlastním navazování spojení? Nebo asistuje Flash Media Server?

pas2007

Stratus asistuje i při vlastním navazování spojení, žádný jiný server není potřeba. Jeho budoucnost by mě taky zajímala… Prý to je experimentální služba, která nikdy nebude samostatným produktem (asi je třeba počítat s tím, že ho kdykoliv můžou vypnout). Rendezvous funkčnost bude zakomponována do serverů (FMS) a služeb (LCCS) od Adobe a doufejme, že i do alternativních produktů, i když protokol RTMFP zatím ještě nebyl oficiálně otevřen, nebo se pletu, Tome?

jobas

Zdravim,
bohuzel jsem se k clanku dostal az ted, tak uz asi ani necekam ze by mi nekdo odpovedel:-(…

Stejne to zkusim. Mohl by mi nekdo rict nejaky priklad flashove zalozene videokonference pracujici na principu peer-to-peer? (nejlepe open source) Hledanim jsem stravil nekolik dni a nic jsem nenasel, ale mozna jsem hledal spatne…

Diky moc:-)…
MJ

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.