피어 이벤트 인프라
피어 인프라는 이벤트를 사용하여 애플리케이션에 피어 네트워크 내에서 발생한 변경 내용(예: 그래프에서 추가 또는 제거된 노드)을 알립니다. 피어 그래프 및 피어 그룹화 인프라는 피어 이벤트 인프라를 사용합니다.
피어 이벤트 알림 받기
그래프 또는 그룹의 특성이 변경되거나 특정 피어 이벤트가 발생할 때 피어가 등록하여 알림을 받을 수 있습니다. 피어 애플리케이션은 PeerGraphRegisterEvent 또는 PeerGroupRegisterEvent 함수를 호출하고 이전에 CreateEvent를 호출하여 만든 피어 인프라에 이벤트 핸들을 전달합니다. 피어 인프라는 핸들을 사용하여 피어 이벤트가 발생했음을 애플리케이션에 알릴 수 있습니다.
애플리케이션은 또한 애플리케이션이 알림을 요청하는 특정 피어 이벤트를 피어 인프라에 나타내는 일련의PEER_GRAPH_EVENT_REGISTRATION 또는 PEER_GROUP_EVENT_REGISTRATION 구조를 전달합니다. 또한 애플리케이션은 전달되는 구조체 수를 정확히 지정해야 합니다.
피어 그래프 이벤트
피어 그래프 애플리케이션은 9개의 피어 그래프 이벤트에 대한 알림을 수신하도록 등록할 수 있습니다. 각 이벤트 이름 앞에는 PEER_GRAPH_EVENT_(예: PEER_GRAPH_STATUS_CHANGED)가 있습니다. 달리 명시되지 않는 한, 변경에 대한 정보는 PeerGraphGetEventData를 사용하여 검색됩니다.
PEER_GRAPH_EVENT_STATUS_CHANGED 그래프의 상태 변경되었음을 나타냅니다(예: 노드가 그래프와 동기화됨).
PEER_GRAPH_EVENT_PROPERTY_CHANGED 그래프 또는 그룹의 속성이 변경되었음을 나타냅니다. 예를 들어 그래프의 식별 이름이 변경되었습니다.
참고
애플리케이션은 PeerGraphGetProperties 를 호출하여 변경된 정보를 가져와야 합니다.
PEER_GRAPH_EVENT_RECORD_CHANGED 레코드가 변경되었음을 나타냅니다(예: 레코드가 삭제됨).
PEER_GRAPH_EVENT_DIRECT_CONNECTION 직접 연결이 변경되었음을 나타냅니다(예: 노드가 연결됨).
PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION 인접 노드에 대한 연결이 변경되었음을 나타냅니다(예: 노드가 연결됨).
PEER_GRAPH_EVENT_INCOMING_DATA 직접 또는 인접 연결에서 데이터를 수신했음을 나타냅니다.
PEER_GRAPH_EVENT_CONNECTION_REQUIRED 그래프 인프라에 새 연결이 필요했음을 나타냅니다.
참고
PeerGraphConnect에 대한 호출은 새 노드에 연결됩니다. PeerGraphGetEventData에 대한 호출은 데이터를 반환하지 않습니다.
PEER_GRAPH_EVENT_NODE_CHANGED 노드 현재 상태 정보가 변경되었음을 나타냅니다(예: IP 주소가 변경됨).
PEER_GRAPH_EVENT_SYNCHRONIZED 특정 레코드 형식이 동기화되었음을 나타냅니다.
애플리케이션이 피어 이벤트가 발생했다는 알림을 받은 후 애플리케이션은 PeerGraphGetEventData를 호출하고 PeerGraphRegisterEvent에서 반환된 피어 이벤트 핸들을 전달합니다. 피어 인프라는 요청된 데이터를 포함하는 PEER_GRAPH_EVENT_DATA 구조체에 대한 포인터를 반환합니다. PEER_S_NO_EVENT_DATA 반환될 때까지 이 함수를 호출해야 합니다.
애플리케이션에 피어 이벤트 알림이 필요하지 않으면 애플리케이션은 PeerGraphUnregisterEvent를 호출하고 애플리케이션이 등록될 때 PeerGraphRegisterEvent 에서 반환된 피어 이벤트 핸들을 전달합니다.
그래프 연결 조회 처리
PeerGraphConnect가 호출되면 비동기 PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION 이벤트를 통해 연결 피어에 성공 또는 실패 알림이 표시됩니다. 특정 네트워킹 문제(예: 잘못 구성된 방화벽)로 인해 연결이 실패하면 연결 상태 PEER_CONNECTION_FAILED 설정된 PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION 이벤트가 발생합니다.
그러나 피어가 사용 중인 노드에 연결하려고 할 때 조회를 받으면 연결 상태 PEER_CONNECTION_FAILED 설정된 연결 피어에서 PEER_GRAPH_EVENT_NEIGHBOR_CONNECTION 발생합니다. 연결 피어는 자체 사용량이 많고 조회를 보낼 수 있는 다른 노드를 참조할 수 있으며 연결 피어에서 동일한 이벤트 및 상태 발생합니다. PEER_CONNECTION_FAILED 이벤트 상태를 초래하는 이 조회 체인은 최대 연결 시도 횟수가 소진될 때까지 계속될 수 있습니다. 피어에는 전체 연결 시도와 연결 조회 간의 차이를 확인하는 메커니즘이 없습니다.
이 문제를 해결하려면 개발자는 피어 그래프 상태 변경 이벤트를 사용하여 연결 시도가 처리되었는지 확인해야 합니다. 이벤트가 특정 시간 내에 수신되지 않는 경우 애플리케이션은 연결 피어가 참조되고 있으며 피어 애플리케이션이 연결 시도 실패를 고려해야 한다고 가정할 수 있습니다.
피어 그룹화 이벤트
피어 그룹화 애플리케이션은 8개의 피어 이벤트에 대한 알림을 수신하도록 등록할 수 있습니다. 각 이벤트 이름 앞에는 PEER_GROUP_EVENT_; 예를 들어 PEER_GROUP_EVENT_STATUS_CHANGED. 달리 명시되지 않는 한 PeerGroupGetEventData를 사용하여 변경 내용에 대한 정보를 검색합니다.
- PEER_GROUP_EVENT_STATUS_CHANGED 그룹 상태 변경되었음을 나타냅니다. 가능한 두 가지 상태 값은 PEER_GROUP_STATUS_LISTENING, 즉 그룹에 연결이 없고 새 멤버를 기다리고 있음을 나타내며, PEER_GROUP_STATUS_HAS CONNECTIONS는 그룹에 하나 이상의 연결이 있음을 나타냅니다. 이 상태 값은 이 이벤트가 발생한 후 PeerGroupGetStatus를 호출하여 가져올 수 있습니다.
- PEER_GROUP_EVENT_PROPERTY_CHANGED 그룹 작성자가 그룹 속성을 변경하거나 업데이트했음을 나타냅니다.
- PEER_GROUP_EVENT_RECORD_CHANGED 레코드 작업이 수행되었음을 나타냅니다. 이 이벤트는 그룹에 참여하는 피어가 레코드를 게시, 업데이트 또는 삭제할 때 발생합니다. 예를 들어 이 이벤트는 채팅 애플리케이션이 채팅 메시지를 보낼 때 발생합니다.
-
PEER_GROUP_EVENT_MEMBER_CHANGED 그룹 내 멤버의 상태 변경되었음을 나타냅니다. 상태 변경 내용은 다음과 같습니다.
- PEER_MEMBER_CONNECTED. 피어가 그룹에 연결되었습니다.
- PEER_MEMBER_DISCONNECTED. 피어가 그룹에서 연결이 끊어졌습니다.
- PEER_MEMBER_JOINED. 피어에 대한 새 멤버 자격 정보가 게시되었습니다.
- PEER_MEMBER_UPDATED. 피어가 새 IP 주소와 같은 새 정보로 업데이트되었습니다.
- PEER_GROUP_EVENT_NEIGHBOR_CONNECTION. 그룹 내의 인접 연결에 참여할 피어는 이 이벤트에 등록해야 합니다. 이 이벤트에 등록해도 피어가 데이터를 수신할 수 없습니다. 이 이벤트에 등록하면 인접 연결에 대한 요청이 수신될 때만 알림이 보장됩니다.
- PEER_GROUP_EVENT_DIRECT_CONNECTION. 그룹 내에서 직접 연결에 참여할 피어는 이 이벤트에 등록해야 합니다. 이 이벤트에 등록해도 피어가 데이터를 수신할 수 없습니다. 이 이벤트에 대한 등록은 직접 연결 요청이 수신될 때만 알림을 보장합니다.
- PEER_GROUP_EVENT_INCOMING_DATA. 인접 또는 직접 연결을 통해 데이터를 수신할 피어는 이 이벤트에 등록해야 합니다. 이 이벤트가 발생하면 PeerGroupGetEventData를 호출하여 다른 참여 피어가 전송하는 불투명 데이터를 가져올 수 있습니다. 이 이벤트를 수신하려면 피어가 이전에 PEER_GROUP_EVENT_DIRECT_CONNECTION 또는 PEER_GROUP_EVENT_NEIGHBOR_CONNECTION 등록해야 합니다.
- PEER_GROUP_EVENT_CONNECTION_FAILED. 어떤 이유로 연결에 실패했습니다. 이 이벤트가 발생할 때 데이터가 제공되지 않으며 PeerGroupGetEventData 를 호출하면 안 됩니다.
애플리케이션이 피어 이벤트가 발생했다는 알림을 받은 후( PEER_GROUP_EVENT_CONNECTION_FAILED 제외) 애플리케이션은 PeerGroupGetEventData를 호출하고 PeerGroupRegisterEvent에서 반환된 피어 이벤트 핸들을 전달합니다. 피어 인프라는 요청된 데이터를 포함하는 PEER_GROUP_EVENT_DATA 구조체에 대한 포인터를 반환합니다. PEER_S_NO_EVENT_DATA 반환될 때까지 이 함수를 호출해야 합니다. 애플리케이션에 피어 이벤트에 대한 알림이 더 이상 필요하지 않은 경우 PeerGroupUnregisterEvent를 호출하여 애플리케이션이 특정 이벤트에 등록될 때 PeerGroupRegisterEvent 에서 반환한 피어 이벤트 핸들을 전달해야 합니다.
피어 그래프 이벤트 등록 예제
다음 코드 샘플에서는 피어 그래프 이벤트에 등록하는 방법을 보여 줍니다.
//-----------------------------------------------------------------------------
// 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;
}