close

Služba distribuce dat

Přejít na navigaci Přejít na hledání

Služba distribuce dat pro systémy v reálném čase (DDS) je standard vydaný skupinou Object Management Group (OMG), který definuje middleware pro distribuci dat v reálném čase podle paradigmatu publikování/odběru .

Úvod

DDS je middleware pro data -centric systems (z anglosaských data-centric systems ), tedy distribuované systémy, jejichž provoz je založen na výměně dat v reálném čase z více zdrojů do více destinací. Typickými příklady jsou kontrolní systémy, obranné systémy, systémy finančního obchodování atd. Výhody používání DDS v této doméně jsou následující:

Image
Paradigma publikování / odběru, které je základem DDS.
  • Volné propojení mezi entitami a snadné použití díky použití paradigmatu publikovat / přihlásit se v tematické variantě;
  • Flexibilní a adaptabilní architektura díky automatickému zjišťování ;
  • Efektivita díky přímé komunikaci mezi vydavatelem a předplatitelem ;
  • Determinismus v doručování dat;
  • Vysoká škálovatelnost jako důsledek volné vazby mezi entitami;
  • Vysoce parametrizovatelná kvalita služeb ;
  • Nezávislost na platformě jako middlewarové rozhraní je definováno prostřednictvím IDL ;

Díky těmto vlastnostem se DDS rychle prosazuje na trhu middlewaru pro distribuované systémy v reálném čase, zejména v oblasti vojenských aplikací a řízení letového provozu.

Historie standardu

Standard DDS byl vydán OMG pod tlakem dvou výrobců, kalifornských Real Time Innovations a francouzské skupiny Thales , kteří vyvinuli NDDS a SPLICE pro stejný sektor trhu. Specifikace DDS 1.0 tak standardizovala programovací rozhraní těchto dvou produktů a přispěla ke zrodu dalších implementací, jako je OpenDDS by Object Computing, Inc. (OCI), založené na TAO a tedy open-source .

Se specifikací DDS 1.1 (z prosince 2005 ) je k normě přidána řada specifikací, které je třeba respektovat, aby byla zajištěna interoperabilita mezi různými implementacemi.

Aktuální verze standardu je DDS 1.2 a byla schválena v lednu 2007 .

OMG DDS SIG nyní pracuje na verzi DDS 1.3 .

Architektura

Image
Architektura DDS.

Služba Data Distribution Service je koncipována jako infrastrukturní řešení pro programování aplikací zaměřených na data. Jeho účelem je zcela skrýt problémy řízení komunikace při programování datacentrických aplikací.

Standard je reprezentován řadou API rozdělených do dvou úrovní:

  • DCPS , Data C entric Publish / S ubscribe , je nižší úroveň DDS, která definuje entity, role, rozhraní a zásady QoS pro platformu publish/subscribe, stejně jako techniky zjišťování účastníků komunikace . DCPS v podstatě představuje část standardu týkající se síťové komunikace.
  • DLRL , datová místní rekonstrukční vrstva , je vyšší úrovní DDS, která definuje model interakce mezi objektově orientovaným světem aplikace a daty přicházejícími z DCPS . Prostřednictvím DLRL je možné mapovat data vyměňovaná v rámci tématu s objektem aplikační vrstvy tak, aby se aktualizace objektu automaticky a transparentně šířily z aplikace do sítě a naopak. DLRL je v rámci DDS deklarováno jako nepovinné .

Entita DCPS

Image
Entity definované v DCPS.

V DCPS jsou definovány následující entity:

DomainParticipantFactory
Singleton , který funguje jako továrna pro přístup ke komunikačnímu prostoru v DDS, nazývaném Global Data Space (GDS). GDS je rozdělen do domén, z nichž každá je identifikována jménem. V rámci domény můžete mít několik témat. Dvě témata se stejným názvem mohou koexistovat v DDS pouze v různých doménách.
Účastník domény
Přístupový bod pro komunikaci v konkrétní doméně. DomainParticipant lze vytvořit pouze prostřednictvím DomainParticipantFactory . Účastník domény zase funguje jako továrna na vytváření tématu , vydavatele a předplatitele .
Téma
Typový oddíl komunikační domény, ve kterém vydavatelé a předplatitelé publikují a přijímají data. Každé téma je charakterizováno názvem a typem. Název identifikuje téma v rámci domény a typ charakterizuje data vyměňovaná v rámci samotného tématu. Typ spojený s tématem je specifikován prostřednictvím jazyka IDL a lze na něj pohlížet jako na strukturu, která může zahrnovat primitivní i komplexní typy . K rozlišení mezi různými objekty tématu se používá koncept klíče , vypůjčený z modelu Entity-Relationship typického pro relační databáze. Klíč je tedy složen z člena nebo kombinace členů daného typu.
Vydavatel
Subjekt odpovědný za šíření dat od různých DataWriterů, které jsou s ním spojené. Vydavatel funguje jako továrna na vytváření DataWriter.
DataWriter
Přístupový bod pro publikování dat v rámci tématu. DataWriter se vytváří počínaje vydavatelem, který je zase jedinečně přidružen k tématu. Z tohoto důvodu je DataWriter abstraktní entita, která je konkretizována napsáním svého rozhraní s typem dat odpovídajícím tématu, na které DataWriter odkazuje.
Odběratel
Subjekt odpovědný za příjem údajů zveřejněných na téma, ke kterému je přidružen. Funguje jako továrna na vytváření DataReaderů a za běhu se stará o třídění přijatých dat do různých DataReaderů, které jsou s ním spojené.
DataReader
Přístupový bod pro příjem dat v rámci tématu. Stejně jako DataWriter je DataReader také abstraktní entita, která je konkretizována napsáním svého rozhraní s typem dat odpovídajícím tématu, ke kterému DataReader odkazuje.

Kvalita služeb

Služba Data Distribution Service nabízí širokou škálu parametrů týkajících se kvality služby, které lze nastavit na základě jediného subjektu zapojeného do komunikace. Díky této volbě designu je DDS jediným aktuálně dostupným standardem pro komunikaci v reálném čase.

Parametry týkající se kvality služeb v DDS lze rozdělit do tří širokých kategorií:

  • Spolehlivost komunikace
  • Perzistence dat
  • Načasování a priorita

Na základě této klasifikace jsou níže uvedeny parametry většího koncepčního významu s uvedením entit, kterých se parametr týká.

Spolehlivost komunikace

SPOLEHLIVOST (platí pro Topic, DataReader, DataWriter)
Určuje, zda je spojení mezi autory a čtenáři spolehlivé (bez ztráty zpráv) nebo ne (nejlepší úsilí). Pokud je tato zásada nastavena na maximální úsilí (výchozí nastavení), nedochází k opětovnému přenosu zpráv. Pokud je naopak nastaven na spolehlivý, je možné určit maximální dobu blokování zápisu () v případě, že jsou fronty opakovaného přenosu plné. Všimněte si, že prostřednictvím tohoto parametru QoS je možné zajistit spolehlivé doručování dat i při použití nespolehlivého transportního protokolu (typ UDP).
OBJEDNÁVKA CÍLE (platí pro Topic, DataReader)
Určuje, jak se musí příchozí data v účastníkovi třídit, tedy v jakém pořadí musí být aplikaci prezentována. Řazení lze provádět na základě času zveřejnění (časové razítko zapisovače) nebo času upozornění (časové razítko čtenáře, výchozí nastavení).
VLASTNICTVÍ A SÍLA (platí pro téma (vlastnictví), DataWriter (síla))
Vlastnictví určuje, zda lze téma aktualizovat jedním (Exclusive) nebo více DataWriter (Shared). V případě Exclusive je téma aktualizováno autorem s nejvyšším parametrem Síla. Tímto způsobem lze implementovat mechanismus odolnosti proti chybám: když primární zapisovač (s vyšší silou) selže, téma je nadále aktualizováno sekundárním zapisovačem (s nižší silou).
ŽIVOST (platí pro Topic, DataReader, DataWriter)
Určuje, jak infrastruktura DDS (konkrétně služba Discovery) určuje přítomnost účastníků komunikace. Z hlediska implementace představuje časový interval, ve kterém musí entita projevit svou přítomnost prostřednictvím signálu (HEARTBEAT), jinak je považována za nepřítomnou. Jsou možné tři hodnoty: automatická, ruční nastavení na účastníka a ruční nastavení na téma. V automatickém případě (výchozí) je definován dílčí parametr udávající, jak často je vysílán signál přítomnosti entity. V případě manuálního účastníka nebo tématu je subjekt považován za aktivní, pokud je aktivní účastník nebo téma, na které odkazuje.

Příklady použití

V následujících příkladech vydavatel zveřejňuje data související s tématem „Příklad HelloWorld“ v jednosekundových intervalech. Na druhou stranu předplatitel shromažďuje data, jakmile je obdrží, a vytiskne je na obrazovku. Datový typ spojený s tématem "Příklad HelloWorld" je definován prostřednictvím jazyka IDL takto:

struct HelloWorld {
     název řetězce < 64 > ;
    string msg < 256 > ;
}

Specifikace IDL je poté přeložena do jazyka používaného pro vývoj aplikací. V C a C++ to dá vzniknout struktuře jako:

struct  HelloWorld { 
    char * jméno ; 
    char * zpráva ; 
}

zatímco v Javě budete mít následující třídu:

public  class  HelloWorld  { 
    public  String  name ; 
    public  String  msg ; 
}

Typ IDL také generuje typovaná rozhraní pro čtení a zápis dat k tématu, jmenovitě HelloWorldDataReader a HelloWorldDataWriter.

Pro jednoduchost diskuse jsou v následujících příkladech pro každou entitu použity výchozí zásady QoS. Další informace o parametrizaci QoS naleznete ve standardu.

C ++

Strana vydavatele

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> // potřebné pro spánek () 

#include <dds_cpp.h> 
pomocí DDS ; 

int main ( int argc , char * argv [])    
{
    int domainId = 0 ;   
    int pocet_vzorku = 100 ;   
    Účastník domény * účastník = NULL ;   
    Vydavatel * vydavatel = NULL ;   
    Téma * téma = NULL ;   
    DataWriter * Writer = NULL ;   
    HelloWorldDataWriter * helloWriter = NULL ;   
    instance HelloWorld ; 
    InstanceHandle_t instance_handle = HANDLE_NIL ;   
    const char * název_typu = NULL ;    
    int pocet = 0 ;   

    účastník = TheParticipantFactory -> create_participant (  
        domainId , PARTICIPANT_QOS_DEFAULT , NULL / * posluchač * / , STATUS_MASK_NONE );    
        

    vydavatel = účastník -> vytvořit_vydavatel (  
        PUBLISHER_QOS_DEFAULT , NULL / * posluchač * / , STATUS_MASK_NONE );   
        

    type_name = HelloWorldTypeSupport :: get_type_name ();  
    HelloWorldTypeSupport :: register_type (
        účastník , jméno_typu ); 

    topic = účastník -> create_topic (  
        "Příklad HelloWorld" ,
        type_name , TOPIC_QOS_DEFAULT , NULL / * posluchač * / ,   
        STATUS_MASK_NONE );

    spisovatel = vydavatel -> create_datawriter (  
        téma , DATAWRITER_QOS_DEFAULT , NULL / * posluchač * / ,   
        STATUS_MASK_NONE );
    helloWriter = HelloWorldDataWriter :: úzký ( writer );  

    strcpy ( instance . name , "MyName" ); 
    instance_handle = HelloWorld_writer -> register_instance ( instance );  

    / * Hlavní smyčka * /
    for ( count = 0 ; ( sample_count == 0 ) || ( count < sample_count ); ++ count ) {          
        sprintf ( instance . msg , "Hello World! (count% d)" , count );   
        printf ( "Zápis:% s" , instance . msg ); 
        helloWriter -> write ( * instance , instance_handle ); 
        spánek ( 1 );
    }

    účastník -> delete_contained_entities ();
    TheParticipantFactory -> delete_participant ( účastník );
}

Strana předplatitele

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> // potřebné pro spánek () 

#include <dds_cpp.h> 

pomocí DDS ; 

/ * Posluchač používaný k přijímání upozornění na aktualizace dat * /
class  HelloWorldListener : public DataReaderListener {    
  veřejnost :
    virtuální void on_data_available ( DataReader * reader );   
};

void HelloWorldListener :: on_data_available ( DataReader * reader )  
{
    HelloWorldDataReader * HelloWorld_reader = NULL ;   
    HelloWorldSeq data_seq ; 
    SampleInfoSeq info_seq ; 

    HelloWorld_reader = HelloWorldDataReader :: úzký ( čtenář );  

    retcode = HelloWorld_reader -> take (  
        data_seq , info_seq , LENGTH_UNLIMITED ,  
        ANY_SAMPLE_STATE , ANY_VIEW_STATE , ANY_INSTANCE_STATE );  

    for ( i = 0 ; i < data_seq . length (); ++ i ) {        
        if ( info_seq [ i ]. platná_data ) {  
            printf ( "Od% s:% s \ n " , datová_sekv [ i ]. jméno , datová_sekv [ i ]. msg );  
        }
    }

    retcode = HelloWorld_reader -> return_loan ( data_seq , info_seq );   
}

int main ( int argc , char * argv [])    
{
    int domainId = 0 ;   

    Účastník domény * účastník = NULL ;   
    Předplatitel * předplatitel = NULL ;   
    Téma * téma = NULL ;   
    HelloWorldListener * reader_listener = NULL ; DataReader * reader = NULL ;    
       
    ReturnCode_t retcode ; 
    const char * název_typu = NULL ;    

    účastník = TheParticipantFactory -> create_participant (  
        domainId , participant_qos , NULL / * posluchač * / , STATUS_MASK_NONE );    

    odběratel = účastník -> vytvořit_předplatitele (  
        SUBSCRIBER_QOS_DEFAULT , NULL / * posluchač * / , STATUS_MASK_NONE );   

    type_name = HelloWorldTypeSupport :: get_type_name ();  
    retcode = HelloWorldTypeSupport :: register_type (  
        účastník , jméno_typu ); 

    topic = účastník -> create_topic (  
        "Příklad HelloWorld" ,
        type_name , TOPIC_QOS_DEFAULT , NULL / * posluchač * / ,   
        STATUS_MASK_NONE );

    / * Vytvořit posluchače čtečky dat * /
    reader_listener = nový HelloWorldListener ();   

    čtenář = předplatitel -> create_datareader (  
        téma , DATAREADER_QOS_DEFAULT , čtenář_posluchač ,  
        STATUS_MASK_ALL );

    / * Hlavní smyčka. Nic nedělá. Akce provedená v posluchači * /
    for ( count = 0 ; ( sample_count == 0 ) || ( count < sample_count ); ++ count ) {          
        printf ( "Předplatitel HelloWorld spí % d s ... \ n " ,
               příjem_období . sec );
        spánek ( 10 );
    }

    účastník -> delete_contained_entities ();
    TheParticipantFactory -> delete_participant ( účastník );
}

Další projekty

Externí odkazy