Udostępnij za pośrednictwem


Infrastruktura zdarzeń równorzędnych

Infrastruktura równorzędna używa zdarzeń do powiadamiania aplikacji o zmianach, które wystąpiły w sieci równorzędnej, na przykład węzła, który został dodany lub usunięty z grafu. Infrastruktury tworzenia grafów równorzędnych i grupowania równorzędnych używają infrastruktury zdarzeń równorzędnych.

Odbieranie powiadomienia o zdarzeniu elementu równorzędnego

Element równorzędny może zarejestrować się, aby otrzymywać powiadomienia, gdy wystąpi atrybut grafu lub grupy albo wystąpi określone zdarzenie równorzędne. Aplikacja równorzędna wywołuje funkcję PeerGraphRegisterEvent lub PeerGroupRegisterEvent i przekazuje dojście zdarzeń do infrastruktury równorzędnej utworzonej wcześniej przez wywołanie CreateEvent. Infrastruktura równorzędna używa uchwytu, aby zasygnalizować aplikację, że wystąpiło zdarzenie komunikacji równorzędnej.

Aplikacja przekazuje również serię struktur PEER_GRAPH_EVENT_REGISTRATION lub PEER_GROUP_EVENT_REGISTRATION, które wskazują na infrastrukturę równorzędną określone zdarzenia równorzędne, dla których aplikacja żąda powiadomienia. Aplikacja musi również określić dokładnie, ile struktur jest przekazywanych.

Zdarzenia grafu równorzędnego

Aplikacja peer Graphing może zarejestrować się w celu otrzymywania powiadomień dotyczących zdarzeń grafu równorzędnego 9. Każda nazwa zdarzenia jest poprzedzona PEER_GRAPH_EVENT_, na przykład PEER_GRAPH_STATUS_CHANGED. O ile nie określono inaczej, informacje o zmianie są pobierane przy użyciu PeerGraphGetEventData.

  • PEER_GRAPH_EVENT_STATUS_CHANGED wskazuje, że stan grafu został zmieniony, na przykład węzeł został zsynchronizowany z grafem.

  • PEER_GRAPH_EVENT_PROPERTY_CHANGED wskazuje, że właściwość grafu lub grupy została zmieniona, na przykład przyjazna nazwa grafu uległa zmianie.

    Nuta

    Aby uzyskać zmienione informacje, aplikacja musi wywołać PeerGraphGetProperties.

     

  • PEER_GRAPH_EVENT_RECORD_CHANGED wskazuje, że rekord zostanie zmieniony, na przykład rekord zostanie usunięty.

  • PEER_GRAPH_EVENT_DIRECT_CONNECTION wskazuje, że połączenie bezpośrednie zostało zmienione, na przykład węzeł nawiązał połączenie.

  • PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION wskazuje, że połączenie z węzłem sąsiada zostało zmienione, na przykład węzeł został połączony.

  • PEER_GRAPH_EVENT_INCOMING_DATA wskazuje, że dane zostały odebrane z połączenia bezpośredniego lub sąsiada.

  • PEER_GRAPH_EVENT_CONNECTION_REQUIRED wskazuje, że infrastruktura grafu wymaga nowego połączenia.

    Nuta

    Wywołanie PeerGraphConnect nawiązuje połączenie z nowym węzłem. Wywołanie metody PeerGraphGetEventData nie zwraca danych.

     

  • PEER_GRAPH_EVENT_NODE_CHANGED wskazuje, że informacje o obecności węzła zostały zmienione, na przykład zmieniono adres IP.

  • PEER_GRAPH_EVENT_SYNCHRONIZED wskazuje, że określony typ rekordu jest synchronizowany.

Po otrzymaniu przez aplikację powiadomienia o wystąpieniu zdarzenia elementu równorzędnego aplikacja wywołuje PeerGraphGetEventDatai przekazuje dojście zdarzeń równorzędnych zwrócone przez PeerGraphRegisterEvent. Infrastruktura równorzędna zwraca wskaźnik do struktury PEER_GRAPH_EVENT_DATA zawierającej żądane dane. Ta funkcja powinna być wywoływana do momentu zwrócenia PEER_S_NO_EVENT_DATA.

Gdy aplikacja nie wymaga powiadomienia o zdarzeniu elementu równorzędnego, aplikacja wywołuje PeerGraphUnregisterEventi przekazuje dojście zdarzeń równorzędnych zwrócone przez PeerGraphRegisterEvent po zarejestrowaniu aplikacji.

Obsługa odwołań połączeń programu Graph

Po wywołaniu PeerGraphConnect komunikacja równorzędna jest powiadamiana o powodzeniu lub niepowodzeniu za pośrednictwem zdarzenia asynchronicznego PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION. Jeśli połączenie nie powiodło się z powodu określonych problemów z siecią (takich jak nieprawidłowo skonfigurowana zapora), zostanie zgłoszone zdarzenie PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION z ustawionym stanem połączenia na wartość PEER_CONNECTION_FAILED.

Jednak gdy element równorzędny odbiera odwołanie podczas próby nawiązania połączenia z węzłem zajętym, PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION jest wywoływana na komunikacji równorzędnej, a stan połączenia jest ustawiony na PEER_CONNECTION_FAILED. Komunikacja równorzędna połączenia może być skierowana do innego węzła, który sam jest zajęty i może wysłać odwołanie, a to samo zdarzenie i stan są wywoływane w komunikacji równorzędnej. Ten łańcuch odwołań, które powodują PEER_CONNECTION_FAILED stanami zdarzeń, może być kontynuowany do momentu wyczerpania maksymalnej liczby prób połączenia. Element równorzędny nie ma mechanizmu określania różnicy między pełną próbą połączenia a odwołaniem do połączenia.

Aby rozwiązać ten problem, deweloperzy powinni rozważyć użycie zdarzeń zmiany stanu grafu równorzędnego, aby ustalić, czy próba połączenia zakończyła się pomyślnie. Jeśli zdarzenie nie zostanie odebrane w określonym czasie, aplikacja może założyć, że komunikacja równorzędna jest odwoływana i że aplikacja równorzędna powinna rozważyć próbę nawiązania połączenia.

Zdarzenia grupowania równorzędnego

Aplikacja do grupowania elementów równorzędnych może zarejestrować się w celu otrzymywania powiadomień o zdarzeniach komunikacji równorzędnej 8. Każda nazwa zdarzenia jest poprzedzona PEER_GROUP_EVENT_; na przykład PEER_GROUP_EVENT_STATUS_CHANGED. O ile nie określono inaczej, informacje o zmianie są pobierane przy użyciu PeerGroupGetEventData.

  • PEER_GROUP_EVENT_STATUS_CHANGED wskazuje, że stan grupy został zmieniony. Możliwe są dwie wartości stanu: PEER_GROUP_STATUS_LISTENING, co wskazuje, że grupa nie ma połączeń i oczekuje na nowych członków; i PEER_GROUP_STATUS_HAS POŁĄCZENIA, co wskazuje, że grupa ma co najmniej jedno połączenie. Tę wartość stanu można uzyskać, wywołując PeerGroupGetStatus po wystąpieniu tego zdarzenia.
  • PEER_GROUP_EVENT_PROPERTY_CHANGED wskazuje, że właściwości grupy zostały zmienione lub zaktualizowane przez twórcę grupy.
  • PEER_GROUP_EVENT_RECORD_CHANGED wskazuje, że wykonano operację rekordu. To zdarzenie jest zgłaszane, gdy element równorzędny uczestniczący w grupie publikuje, aktualizuje lub usuwa rekord. Na przykład to zdarzenie jest zgłaszane, gdy aplikacja czatu wysyła wiadomość czatu.
  • PEER_GROUP_EVENT_MEMBER_CHANGED wskazuje, że stan członka w grupie uległ zmianie. Zmiany stanu obejmują:
    • PEER_MEMBER_CONNECTED. Element równorzędny nawiązał połączenie z grupą.
    • PEER_MEMBER_DISCONNECTED. Element równorzędny odłączył się od grupy.
    • PEER_MEMBER_JOINED. Nowe informacje o członkostwie zostały opublikowane dla elementu równorzędnego.
    • PEER_MEMBER_UPDATED. Element równorzędny został zaktualizowany o nowe informacje, takie jak nowy adres IP.
  • PEER_GROUP_EVENT_NEIGHBOR_CONNECTION. Osoby równorzędne, które będą uczestniczyć w połączeniach sąsiadów w grupie, muszą zarejestrować się na potrzeby tego zdarzenia. Należy pamiętać, że rejestracja dla tego zdarzenia nie umożliwia elementu równorzędnego odbierania danych; rejestracja dla tego zdarzenia zapewnia tylko powiadomienie, gdy zostanie odebrane żądanie połączenia sąsiada.
  • PEER_GROUP_EVENT_DIRECT_CONNECTION. Osoby równorzędne, które będą uczestniczyć w połączeniach bezpośrednich w grupie, muszą zarejestrować się na potrzeby tego zdarzenia. Należy pamiętać, że rejestracja dla tego zdarzenia nie umożliwia elementu równorzędnego odbierania danych; rejestracja dla tego zdarzenia zapewnia powiadomienie tylko wtedy, gdy zostanie odebrane żądanie połączenia bezpośredniego.
  • PEER_GROUP_EVENT_INCOMING_DATA. Osoby równorzędne, które będą odbierać dane za pośrednictwem sąsiada lub bezpośredniego połączenia, muszą zarejestrować się na potrzeby tego zdarzenia. Po wywołaniu tego zdarzenia nieprzezroczyste dane przesyłane przez inny uczestniczący element równorzędny można uzyskać, wywołując PeerGroupGetEventData. Należy pamiętać, że aby odebrać to zdarzenie, element równorzędny musi być wcześniej zarejestrowany dla PEER_GROUP_EVENT_DIRECT_CONNECTION lub PEER_GROUP_EVENT_NEIGHBOR_CONNECTION.
  • PEER_GROUP_EVENT_CONNECTION_FAILED. Połączenie nie powiodło się z jakiegoś powodu. Nie są dostarczane żadne dane, gdy to zdarzenie jest zgłaszane, a PeerGroupGetEventData nie powinny być wywoływane.

Po otrzymaniu przez aplikację powiadomienia o wystąpieniu zdarzenia elementu równorzędnego (z wyłączeniem PEER_GROUP_EVENT_CONNECTION_FAILED) aplikacja wywołuje PeerGroupGetEventDatai przekazuje dojście zdarzeń elementu równorzędnego zwrócone przez PeerGroupRegisterEvent. Infrastruktura równorzędna zwraca wskaźnik do struktury PEER_GROUP_EVENT_DATA zawierającej żądane dane. Ta funkcja musi być wywoływana do momentu zwrócenia PEER_S_NO_EVENT_DATA. Gdy aplikacja nie wymaga już powiadomienia o zdarzeniu elementu równorzędnego, należy wykonać wywołanie PeerGroupUnregisterEvent, przekazując dojście zdarzeń równorzędnych zwrócone przez PeerGroupRegisterEvent, gdy aplikacja zarejestrowana dla określonego zdarzenia.

Przykład rejestrowania dla zdarzeń grafu równorzędnego

Poniższy przykładowy kod pokazuje, jak zarejestrować się za pomocą zdarzeń grafu równorzędnego.

//-----------------------------------------------------------------------------
// Function: RegisterForEvents
//
// Purpose:  Registers the EventCallback function so it can be called for only
//           the events that are specified.
//
// Returns:  HRESULT
//
HRESULT RegisterForEvents()
{
    HPEEREVENT  g_hPeerEvent = NULL;        // The one PeerEvent handle
    HANDLE      g_hEvent = NULL;            // Handle signaled by Graphing when we have an event
    HRESULT hr = S_OK;
    PEER_GRAPH_EVENT_REGISTRATION regs[] = {
        { PEER_GRAPH_EVENT_RECORD_CHANGED, 0 },
        { PEER_GRAPH_EVENT_NODE_CHANGED,   0 },
        { PEER_GRAPH_EVENT_STATUS_CHANGED, 0 },
        { PEER_GRAPH_EVENT_DIRECT_CONNECTION, 0 },
        { PEER_GRAPH_EVENT_INCOMING_DATA, 0 },
    };

    g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (g_hEvent == NULL)
    {
        wprintf(L"CreateEvent call failed.\n");
        hr = E_OUTOFMEMORY;
    }
    else
    {
        hr = PeerGraphRegisterEvent(g_hGraph, g_hEvent, celems(regs), regs,  &g_hPeerEvent);
        if (FAILED(hr))
        {
           wprintf(L"PeerGraphRegisterEvent call failed.\n");
            CloseHandle(g_hEvent);
            g_hEvent = NULL;
        }
    }

    if (SUCCEEDED(hr))
    {
        if (!RegisterWaitForSingleObject(&g_hWait, g_hEvent, EventCallback, NULL, INFINITE, WT_EXECUTEDEFAULT))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            wprintf(L"Could not set up event callback.\n");
            CloseHandle(g_hEvent);
            g_hEvent = NULL;
        }
    }

    return hr;
}