Depending on the settings when a session is created, it can be either open (an open invitation to participants to join) or closed.
The API for changing the session invitation state works automatically to synchronize processes between host and client. (There is also a way for the application to directly manage synchronization between the host and client. This is discussed below.)
To change the state, all stations call either OpenSessionAsync() or CloseSessionAsync(). The process continues automatically and all stations reflect the changed invitation state, even if new stations join or leave the session or host migration occurs during the asynchronous process.
To change the state to an open invitation, call OpenSessionAsync(). To close the session and stop inviting participants, call CloseSesssionAsync(). PiaSession automatically performs the appropriate process subsequent to the state change, and the asynchronous process ends after this is completed. The application only needs to wait for the asynchronous process to end after it has called the API.
If the calling station was the host, it follows through with the process to open or close the matchmaking session to invitations. If the calling station was a client, it does nothing for the matchmaking session. The asynchronous process then continues until the following conditions are met.
Make sure that the host and the clients all call the same API. If the host calls OpenSessionAsync() and the clients call CloseSessionAsync() (or vice versa), ResultSessionInvalidState is returned either when the API is called or as the result of the asynchronous process.
Make sure that all stations call the API within a set period of time (60 seconds). If clients call the API more than 60 seconds after the host has called the API, synchronization fails and ResultSessionInvaidState is returned.
ResultSessionInconsistentState is returned if the asynchronous process stalls for a long time due to the communications environment after all participants in the session have called the API to change the invitation state.
// The number of participants must align, and the same API must be called among all stations with the same timing, like during the sequence before the game starts.
result = nn::pia::session::Session::GetInstance()->CloseSessionAsync(); if (result == nn::pia::ResultSessionInconsistentState()) { // The host has called OpenSessionAsync() already. This causes implementation problems, so correct it. } else if (result.IsFailure()) { // Error handling. } // When the asynchronous process starts successfully, you must periodically call the dispatch function to wait on the progress of the asynchronous process. while( nn::pia::session::Session::GetInstance()->IsCompletedCloseSession() == false ) { if ( networkType == INTERNET ) { // When using Internet communications, you must call the Scheduler::Dispatch function of NEX for keep-alive communication with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the results of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetCloseSessionResult(); if (result == nn::pia::ResultSessionInvalidState()) { // An error is returned for any of these reasons. This causes implementation problems, so correct it. // - The host has called OpenSessionAsync(). // - Not all stations called CloseSessionAsync() within a specific period of time. } else if (result == nn::pia::ResultSessionInconsistentState()) { // The asynchronous process takes a long time after all stations have called CloseSessionAsync(). } else if ( result.IsFailure() ) { // Error handling. } |
When the application directly performs the synchronous process for the session invitation state, the host calls the APIs for changing the state (OpenParticipationAsync() and CloseParticipationAsync()).
The clients cannot perceive the session invitation state. When host migration occurs, the invitation state becomes unknown. If any station is connecting at the time, it joins the session after the asynchronous processing of these APIs has completed. To deal with this situation, the application must perform a synchronous communications process. Note that this makes the program more complicated.
To change the state to open invitation, call OpenParticipationAsync() and start the asynchronous process. To learn when the asynchronous process has completed, use IsCompletedOpenParticipation(). If the state has been successfully changed, GetOpenParticipationResult() returns the result that IsSuccess()is true.
result = nn::pia::session::Session::GetInstance()->OpenParticipationAsync();
if(result.IsFailure()) { // Error handling. } // When the asynchronous process starts successfully, you must periodically call the dispatch function to wait on the progress of the asynchronous process. while( nn::pia::session::Session::GetInstance()->IsCompletedOpenParticipation() == false ) { if ( networkType == INTERNET ) { // When using Internet communications, you must call the Scheduler::Dispatch function of NEX for keep-alive communication with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the results of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetOpenParticipationResult(); if ( result.IsFailure() ) { // Error handling. } |
To change the state to close the session to invitations, call CloseParticipationAsync() and start the asynchronous process. To learn when the asynchronous process has completed, use IsCompletedCloseParticipation(). If the state has been successfully changed, GetCloseParticipationResult() returns the result that IsSuccess()is true.
The process of closing the session to invitations proceeds as follows.
If the process times out, GetCloseParticipationResult() returns ResultNegligibleFault. At this point, the matchmaking session has been closed successfully, but there is a possibility that new participants will join the mesh after the end of the asynchronous process. Handle this appropriately in the application. For example:
result = nn::pia::session::Session::GetInstance()->CloseParticipationAsync();
if (result.IsFailure()) { // Error handling. } // When the asynchronous process starts successfully, you must periodically call the dispatch function to wait on the progress of the asynchronous process. while (nn::pia::session::Session::GetInstance()->IsCompletedCloseParticipation() == false) { if (networkType == INTERNET) { // When using Internet communications, you must call the Scheduler::Dispatch function of NEX for keep-alive communication with the server. nn::nex::Scheduler::GetInstance()->DispatchAll(); } nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the results of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetCloseParticipationResult(); if (result.IsFailure()) { if (result == ResultNegligibleFault()) { // The asynchronous process timed out. // The matchmaking session is closed, but there may be newly joining participants. // Implement the application to correctly handle the situation in one of the following ways: continue the process, call CloseParticipationAsync() // again, or deny the join session request and return an error to the newly joining participant. } else { // Error handling. } } |