Partilhar via


Infraestrutura de eventos entre pares

A infraestrutura de mesmo nível usa eventos para notificar aplicativos de alterações que ocorreram em uma rede de mesmo nível, por exemplo, um nó que é adicionado ou removido de um gráfico. As infraestruturas de Peer Graphing e Peer Grouping usam a infraestrutura de eventos de mesmo nível.

Recebendo notificação de evento ponto a ponto

Um par pode se registrar para receber notificação quando um atributo de um gráfico ou grupo é alterado ou ocorre um evento de mesmo nível específico. Um aplicativo ponto a ponto chama o PeerGraphRegisterEvent ou função de PeerGroupRegisterEvent e passa um identificador de evento para a infraestrutura de mesmo nível, que é criada anteriormente por uma chamada para CreateEvent. A infraestrutura de mesmo nível usa o identificador para sinalizar a um aplicativo que ocorreu um evento de mesmo nível.

O aplicativo também passa por uma série de estruturas PEER_GRAPH_EVENT_REGISTRATION ou PEER_GROUP_EVENT_REGISTRATION que indicam para a infraestrutura de mesmo nível os eventos de mesmo nível específicos para os quais o aplicativo está solicitando notificação. O aplicativo também deve especificar exatamente quantas estruturas estão sendo passadas.

Eventos de Peer Graphing

Um aplicativo de gráfico de pares pode se registrar para receber notificação para 9 eventos de gráfico de pares. Cada nome de evento é precedido de PEER_GRAPH_EVENT_, por exemplo, PEER_GRAPH_STATUS_CHANGED. Salvo indicação em contrário, as informações sobre uma alteração são recuperadas usando PeerGraphGetEventData.

  • PEER_GRAPH_EVENT_STATUS_CHANGED indica que o status de um gráfico é alterado, por exemplo, um nó foi sincronizado com um gráfico.

  • PEER_GRAPH_EVENT_PROPERTY_CHANGED indica que uma propriedade de um gráfico ou grupo foi alterada, por exemplo, o nome amigável de um gráfico foi alterado.

    Observação

    O aplicativo deve chamar PeerGraphGetProperties para obter as informações alteradas.

     

  • PEER_GRAPH_EVENT_RECORD_CHANGED indica que um registro é alterado, por exemplo, um registro é excluído.

  • PEER_GRAPH_EVENT_DIRECT_CONNECTION indica que uma conexão direta foi alterada, por exemplo, um nó se conectou.

  • PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION indica que uma conexão com um nó vizinho foi alterada, por exemplo, um nó se conectou.

  • PEER_GRAPH_EVENT_INCOMING_DATA indica que os dados foram recebidos de uma conexão direta ou vizinha.

  • PEER_GRAPH_EVENT_CONNECTION_REQUIRED indica que a infraestrutura gráfica requer uma nova conexão.

    Observação

    Uma chamada para PeerGraphConnect se conecta a um novo nó. Uma chamada para PeerGraphGetEventData não retorna dados.

     

  • PEER_GRAPH_EVENT_NODE_CHANGED indica que as informações de presença do nó foram alteradas, por exemplo, um endereço IP foi alterado.

  • PEER_GRAPH_EVENT_SYNCHRONIZED indica que um tipo de registro específico está sincronizado.

Depois que um aplicativo recebe a notificação de que ocorreu um evento de mesmo nível, o aplicativo chama PeerGraphGetEventDatae passa o identificador de evento ponto a ponto retornado por PeerGraphRegisterEvent. A infraestrutura de mesmo nível retorna um ponteiro para uma estrutura de PEER_GRAPH_EVENT_DATA que contém os dados solicitados. Esta função deve ser chamada até que PEER_S_NO_EVENT_DATA seja retornada.

Depois que um aplicativo não requer uma notificação de evento de mesmo nível, o aplicativo chama PeerGraphUnregisterEvente passa o identificador de evento ponto a ponto retornado por PeerGraphRegisterEvent quando o aplicativo foi registrado.

Lidando com referências de conexão de gráfico

Quando PeerGraphConnect é chamado, o correspondente de conexão é notificado de sucesso ou falha por meio do evento PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION assíncrono. Se a conexão falhou devido a um problema de rede específico (como um firewall mal configurado), o evento PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION será gerado, com o status da conexão definido como PEER_CONNECTION_FAILED.

No entanto, quando um par recebe uma referência quando tenta se conectar a um nó ocupado, o PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION é gerado no correspondente de conexão, com o status da conexão definido como PEER_CONNECTION_FAILED. O correspondente de conexão pode ser encaminhado para outro nó que está ocupado e pode enviar uma referência, e o mesmo evento e status são gerados no correspondente de conexão. Essa cadeia de referências que resulta em status de evento PEER_CONNECTION_FAILED pode continuar até que o número máximo de tentativas de conexão tenha sido esgotado. O par não tem um mecanismo para determinar a diferença entre uma tentativa de conexão completa e a referência de conexão.

Para resolver esse problema, os desenvolvedores devem considerar o uso dos eventos de alteração de status do gráfico de pares para determinar se a tentativa de conexão foi executada. Se o evento não for recebido dentro de um período de tempo específico, o aplicativo pode assumir que o correspondente de conexão está sendo encaminhado e que o aplicativo par deve considerar a tentativa de conexão uma falha.

Eventos de agrupamento de pares

Um aplicativo de agrupamento de pares pode se registrar para receber notificações para 8 eventos de mesmo nível. Cada nome de evento é precedido de PEER_GROUP_EVENT_; por exemplo, PEER_GROUP_EVENT_STATUS_CHANGED. Salvo indicação em contrário, as informações sobre uma alteração são recuperadas usando PeerGroupGetEventData.

  • PEER_GROUP_EVENT_STATUS_CHANGED indica que o status do grupo foi alterado. Há dois valores de status possíveis: PEER_GROUP_STATUS_LISTENING, que indica que o grupo não tem conexões e está aguardando novos membros; e PEER_GROUP_STATUS_HAS CONEXÕES, que indica que o grupo tem pelo menos uma conexão. Esse valor de status pode ser obtido chamando PeerGroupGetStatus após esse evento ser gerado.
  • PEER_GROUP_EVENT_PROPERTY_CHANGED indica que as propriedades do grupo foram alteradas ou atualizadas pelo criador do grupo.
  • PEER_GROUP_EVENT_RECORD_CHANGED indica que uma operação de registro foi executada. Esse evento é gerado quando um par que participa do grupo publica, atualiza ou exclui um registro. Por exemplo, esse evento é gerado quando um aplicativo de chat envia uma mensagem de bate-papo.
  • PEER_GROUP_EVENT_MEMBER_CHANGED indica que o status de um membro dentro do grupo foi alterado. As alterações de status incluem:
    • PEER_MEMBER_CONNECTED. Um par se conectou ao grupo.
    • PEER_MEMBER_DISCONNECTED. Um par se desconectou do grupo.
    • PEER_MEMBER_JOINED. Novas informações de membros foram publicadas para um par.
    • PEER_MEMBER_UPDATED. Um par foi atualizado com novas informações, como um novo endereço IP.
  • PEER_GROUP_EVENT_NEIGHBOR_CONNECTION. Os colegas que participarão de conexões vizinhas dentro do grupo devem se inscrever para este evento. Observe que o registro para este evento não permite que o par receba dados; O registro para este evento só garante a notificação quando uma solicitação para uma conexão vizinha é recebida.
  • PEER_GROUP_EVENT_DIRECT_CONNECTION. Os pares que participarão em ligações diretas dentro do grupo devem inscrever-se neste evento. Observe que o registro para este evento não permite que o par receba dados; O registro para este evento só garante a notificação quando uma solicitação de conexão direta é recebida.
  • PEER_GROUP_EVENT_INCOMING_DATA. Os pares que receberão dados através de um vizinho ou ligação direta devem registar-se neste evento. Quando esse evento é gerado, os dados opacos transmitidos pelo outro par participante podem ser obtidos chamando PeerGroupGetEventData. Observe que, para receber este evento, o par deve ter se registrado previamente para PEER_GROUP_EVENT_DIRECT_CONNECTION ou PEER_GROUP_EVENT_NEIGHBOR_CONNECTION.
  • PEER_GROUP_EVENT_CONNECTION_FAILED. Uma conexão falhou por algum motivo. Nenhum dado é fornecido quando esse evento é gerado e PeerGroupGetEventData não deve ser chamado.

Depois que um aplicativo recebe notificação de que ocorreu um evento ponto a ponto (excluindo PEER_GROUP_EVENT_CONNECTION_FAILED), o aplicativo chama PeerGroupGetEventDatae passa o identificador de evento ponto a ponto retornado por PeerGroupRegisterEvent. A infraestrutura de mesmo nível retorna um ponteiro para uma estrutura de PEER_GROUP_EVENT_DATA que contém os dados solicitados. Esta função deve ser chamada até que PEER_S_NO_EVENT_DATA seja retornada. Quando um aplicativo não requer mais notificação para um evento de mesmo nível, uma chamada deve ser feita para PeerGroupUnregisterEvent, passando o identificador de evento de mesmo nível retornado por PeerGroupRegisterEvent quando o aplicativo se registrou para o evento específico.

Exemplo de registo para eventos de gráficos entre pares

O exemplo de código a seguir mostra como se registrar com os eventos Peer Graphing.

//-----------------------------------------------------------------------------
// 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;
}