This section describes browse matchmaking.
For more information about leaving sessions, see 6.8.. Basic Features - Leaving Sessions.
This process creates a new session with the local device as the session host. Creating a session is an asynchronous process. Calling the CreateSessionAsync() function starts the asynchronous process. The end of that process can be detected with the IsCompletedCreateSession() function. The GetCreateSessionResult() function returns a result of true for IsSuccess() when a session is successfully created.
You can set an index from 0 through 5 for session attributes.
For Internet communications, use nn::pia::inet::NexCreateSessionSetting to specify the settings for the sessions you create.
For local communications, use nn::pia::local::UdsCreateSessionSetting to specify the settings for the sessions you create.
// Settings for the session to create.
if (networkType == INTERNET) { nn::pia::inet::NexCreateSessionSetting createSessionSetting; createSessionSetting.SetGameMode(MATCHMAKE_GAME_MODE); // Game mode. createSessionSetting.SetMaxParticipants(SAMPLE_MAX_ENTRY); // Maximum number of participants. createSessionSetting.SetAttribute(MATCHMAKE_ATTR_INDEX, MATCHMAKE_ATTR_VAL); // The session attribute. createSessionSetting.SetOpenParticipation(true); // Create a session that is ready to join immediately. // You can configure application-defined data. for (u32 i = 0; i < SAMPLE_APPLICATION_DATA_BUFFER_SIZE; i++) { g_applicationDataBuffer[i] = i; } createSessionSetting.SetApplicationData(g_applicationDataBuffer, sizeof(g_applicationDataBuffer)); } else if (networkType == LOCAL) { nn::pia::local::UdsCreateNetworkSetting createNetworkSetting; { createNetworkSetting.m_SubId = SAMPLE_SUB_ID; createNetworkSetting.m_MaxEntry = SAMPLE_MAX_ENTRY; createNetworkSetting.m_LocalCommunicationId = nn::pia::local::LocalNetwork::GetInstance()->CreateLocalCommunicationId(SAMPLE_TITLE_ID); memcpy(createNetworkSetting.m_Passphrase, const_cast<char*>(SAMPLE_PASSPHRASE), sizeof(SAMPLE_PASSPHRASE)); createNetworkSetting.m_PassphraseLength = sizeof(SAMPLE_PASSPHRASE); // The encryption key to use for local communication. } nn::pia::local::UdsCreateSessionSetting createSessionSetting; createSessionSetting.SetLocalCreateNetworkSetting(createNetworkSetting); createSessionSetting.SetMaxParticipants(SAMPLE_MAX_ENTRY); // The maximum number of participants. result = createSessionSetting.SetSignatureKey(SIGNATURE_KEY_DATA, sizeof(SIGNATURE_KEY_DATA)); PIA_ASSERT(result.IsSuccess()); } // Creation of the session. (The start of the asynchronous process.) result = nn::pia::session::Session::GetInstance()->CreateSessionAsync(createSessionSetting); if (result.IsFailure()) { // Error processing. } // If the asynchronous process has started successfully, you must call the dispatch function periodically and wait for the asynchronous process to proceed. while (nn::pia::session::Session::GetInstance()->IsCompletedCreateSession() == false) { nn::pia::common::Scheduler::GetInstance()->Dispatch(); if ( networkType == INTERNET) { // If you are using Internet communication, you must call the NEX Scheduler::Dispatch function for keep-alive communications with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } } // Check the result of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetCreateSessionResult(); if (result.IsFailure()) { // Error processing. } /* If successful, the session enters a state where it is receptive to other stations joining as clients. */ |
When joining an existing session, you first search for sessions to join. Searching for a session is an asynchronous process. Calling the BrowseSessionAsync() function starts the asynchronous process. The end of that process can be detected with the IsCompletedBrowseSession() function.
The GetBrowseSessionResult() function returns a result of true for IsSuccess() when the search process is successful. When the search process succeeds, you can get the search results list with the GetBrowsedSessionInfoList() function. Scan the information in the list with ISessionInfoList::Iterator, and access the information with the ISessionInfo interface.
When using Internet communications, you can cast to inet::NexSessionInfo to get the matchmaking session settings. When using local communications, you can cast to local::LocalSessionInfo to get the signal strength, the user names of the stations that have joined the session, and information that can be converted into local friend codes.
Canceling the session search process is not currently supported, but there are plans to support it in the future.
// Create the search criteria.
nn::pia::inet::NexSessionSearchCriteria searchSettingList[SEARCH_SETTING_NUM]; // Specifying a single attribute. searchSettingList[0].SetGameMode(MATCHMAKE_GAME_MODE); // Game mode. searchSettingList[0].SetMaxParticipants(SAMPLE_MAX_ENTRY); // Maximum number of participants. searchSettingList[0].SetAttribute(MATCHMAKE_ATTR_INDEX, MATCHMAKE_ATTR_VAL); // The matchmaking attribute. // Specifying multiple attributes (less strict than the first criteria). searchSettingList[1].SetGameMode(MATCHMAKE_GAME_MODE); // Game mode. searchSettingList[1].SetMaxParticipantsRange(SAMPLE_MIN_ENTRY, SAMPLE_MAX_ENTRY); // Maximum number of participants. const size_t ARRAY_SIZE = 5; u32 attributeArray[ARRAY_SIZE] = {2, 4, 6, 11, 72}; searchSettingList[1].SetAttribute(MATCHMAKE_ATTR_INDEX, attributeArray, ARRAY_SIZE); // Specify the range of matchmake attributes. // The session search process. (One search criterion can be specified by BrowseSessionAsync) result = nn::pia::session::Session::GetInstance()->BrowseSessionAsync(&searchSettingList[0]); if (result.IsFailure()) { // Error processing. } // If the asynchronous process has started successfully, you must call the dispatch function periodically and wait for the asynchronous process to proceed. while (nn::pia::session::Session::GetInstance()->IsCompletedBrowseSession() == false) { if (networkType == INTERNET) { // If you are using Internet communication, you must call the NEX Scheduler::Dispatch function for keep-alive communications with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the result of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetBrowseSessionResult(); if (result.IsFailure()) { // Error processing. } // Get the list of search results. nn::pia::session::ISessionInfoList* sessionInfoList = nn::pia::session::Session::GetInstance()->GetBrowsedSessionInfoList(); nn::pia::session::ISessionInfoList::Iterator it = sessionInfoList->Begin(); for ( ; it != sessionInfoList->End(); ++it) { // Output the information in the list to a log. PIA_SAMPLE_PRINT(" Mode=%d GID=%08X [%02d/%02d] [%s]", (*it)->GetGameMode(), (*it)->GetSessionId(), (*it)->GetCurrentParticipants(), (*it)->GetMaxParticipants(), (*it)->IsOpened() ? "Opened" : "Closed" ); if (networkType == INTERNET) { // If you are using Internet communication, you can cast to inet::NexSessionInfo and get the information for the matchmaking session settings. nn::pia::inet::NexSessionInfo* pNexSessionInfo = static_cast<nn::pia::inet::NexSessionInfo*>(*it); PIA_SAMPLE_PRINT(" IsUserPasswordRestricted:%d", pNexSessionInfo->IsRestrictedByUserPassword()); } else { // If you are using local communication, you can cast to local::LocalSessionInfo and get information such as the radio signal strength. nn::pia::local::LocalSessionInfo* pLocalSessionInfo = static_cast<nn::pia::local::LocalSessionInfo*>(*it); u8 radioStrength; if (pLocalSessionInfo->GetRadioStrength(&radioStrength).IsSuccess()) { PIA_SAMPLE_PRINT(" RadioStrength:%d", radioStrength); } } } |
This section describes the process for when the local device joins a session as a client. Joining a session is an asynchronous process. Calling the JoinSessionAsync() function starts the asynchronous process. The end of that process can be detected with the IsCompletedJoinSession() function. When connection with all stations in the session has succeeded, the GetJoinSessionResult() function returns a result of true for IsSuccess(), and communication with other stations is possible.
Run the function when you have found a session in advance, and are in a state where it is possible to join a session.
For Internet communication, a pointer to the ISessionInfo instance obtained from the search must be set in the NexJoinSessionSetting instance. For local communication, the pointer must be set in the UdsJoinSessionSetting instance.
// Run the search process and get ISessionInfo.
nn::pia::session::ISessionInfo* pTargetSessionInfo; // Set the pointer to ISessionInfo. if (networkType == INTERNET) { nn::pia::inet::NexJoinSessionSetting joinSessionSetting; joinSessionSetting.SetSessionInfoPtr(pTargetSessionInfo); } else if (networkType == LOCAL) { nn::pia::local::UdsJoinSessionSetting joinSessionSetting; joinSessionSetting.SetSessionInfoPtr(pTargetSessionInfo); result = joinSessionSetting.SetPassphrase(const_cast<char*>(SAMPLE_PASSPHRASE), sizeof(SAMPLE_PASSPHRASE)); PIA_ASSERT(result.IsSuccess()); result = joinSessionSetting.SetSignatureKey(SIGNATURE_KEY_DATA, sizeof(SIGNATURE_KEY_DATA)); PIA_ASSERT(result.IsSuccess()); } // Joining the session. result = nn::pia::session::Session::GetInstance()->JoinSessionAsync(&joinSessionSetting); if (result.IsFailure()) { // Error processing. } // If the asynchronous process has started successfully, you must call the dispatch function periodically and wait for the asynchronous process to proceed. while (nn::pia::session::Session::GetInstance()->IsCompletedJoinSession() == false) { if (networkType == INTERNET) { // If you are using Internet communication, you must call the NEX Scheduler::Dispatch function for keep-alive communications with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the result of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetJoinSessionResult(); if (result.IsFailure()) { // Error processing. } /* If the asynchronous process succeeds, communication with other stations is now possible. */ |
You can use GetBrowsedSessionInfoList() to get the list of session data that you searched with BrowseSessionAsync(). That list is cleared, however, when you call Session::Cleanup(). When you set the session data acquired using GetBrowsedSessionInfoList() to JoinSessionSetting to join a session, you must perform another session search before attempting to rejoin a session because the list of session data is cleared with Session::Cleanup() if the join process fails for some reason.
You must create an object for saving session data on the application to avoid a session search when attempting to rejoin. For Internet communication, that object is inet::NexSessionInfo; for local communication, it is local::UdsSessionInfo. Copy the session data acquired using GetBrowsedSessionInfoList() to the object and then set that object to JoinSessionSetting.
nn::pia::inet::NexSessionInfo s_NexSessionInfoBufferArray[SESSION_LIST_MAX]; // Array for saving search results when using Internet communication.
nn::pia::local::UdsSessionInfo s_UdsSessionInfoBufferArray[SESSION_LIST_MAX]; // Array for saving search results when using local communication. u8 s_SessionInfoHistoryNum = 0; // The number of saved search results. nn::pia::session::ISessionInfoList* sessionInfoList = nn::pia::session::Session::GetInstance()->GetBrowsedSessionInfoList(); for (nn::pia::session::ISessionInfoList::Iterator it = sessionInfoList->Begin(); it != sessionInfoList->End(); ++it) { if (s_SessionInfoHistoryNum < SESSION_LIST_MAX) { if (g_NetworkType == TYPE_LOCAL) { nn::pia::local::UdsSessionInfo* pInfo = static_cast<nn::pia::local::UdsSessionInfo*>(*it); s_UdsSessionInfoBufferArray[s_SessionInfoHistoryNum].Copy(*pInfo); } else { nn::pia::inet::NexSessionInfo* pInfo = static_cast<nn::pia::inet::NexSessionInfo*>(*it); s_NexSessionInfoBufferArray[s_SessionInfoHistoryNum].Copy(*pInfo); } ++s_SessionInfoHistoryNum; } } |