This document describes the procedures and cautions when using PiaInet.
When using PiaInet, initialize the modules in the following order.
For more information about each of these processes, see the appropriate pages of the programming manual.
When using PiaInet, finalize the modules in the following order.
For more information about each of these processes, see the appropriate pages of the programming manual.
When initializing PiaInet, you must allocate work memory from PiaCommon, so initialize PiaCommon before initializing PiaInet.
Because some NEX classes are used within PiaInet, initialize NEX before initializing PiaInet. In practical terms, nn::nex::MemoryManager::SetBasicMemoryFunctions and nn::nex::GlobalVariables::AcquireInstance must be called in advance.
Also generate the nn::nex::NgsFacade instance at this time. If PiaInet or PiaSession is initialized before this instance is generated, an extra call to nn::nex::GlobalVariables::AcquireInstance() is made, which results in a memory leak in NEX because the instance is not freed even if nn::nex::GlobalVariables::ReleaseInstance() is called in the NEX finalization process.
After the advance procedures have been correctly executed, you can initialize the PiaInet module. Settings for Internet communication are specified when calling the inet::Initialize function.
You can specify an MTU size anywhere from inet::MIN_MTU_SIZE to inet::MAX_MTU_SIZE. We recommend using inet::DEFAULT_MTU_SIZE, however, unless you have a specific reason to use a different size. When an out-of-range value is specified for the MTU size, the ResultInvalidArgument error is returned. When that happens, revise your application.
Create a singleton of the NexFacade class to perform NAT traversal. After PiaInet initialization is complete, pass nn::pia::inet::NexNetworkFactory to PiaTransport to initialize that module. For more information about initializing the PiaTransport module, see the 5. PiaTransport Guide.
/*
Initialize PiaCommon and NEX in advance. */ // Prepare the settings to pass to Initialize. nn::pia::inet::Setting setting; setting.mtuSize = nn::pia::inet::DEFAULT_MTU_SIZE; // Initialize PiaInet. result = nn::pia::inet::Initialize(setting); PIA_ASSERT(result.IsSuccess()); // Begin creating the singletons that PiaInet needs. result = nn::pia::inet::BeginSetup(); PIA_ASSERT(result.IsSuccess()); // Create a singleton of the NexFacade class. result = nn::pia::inet::NexFacade::CreateInstance(); PIA_ASSERT(result.IsSuccess()); // Finish creating the singletons that PiaInet needs. result = nn::pia::inet::EndSetup(); PIA_ASSERT(result.IsSuccess()); /* Specify the nn::pia::inet::NexNetworkFactory pointer in nn::pia::transport::Transport::Setting.pFactory and initialize PiaTransport. Afterwards, it initializes PiaSession. */ |
Establish a connection to the Internet using the CTR-SDK's AC and socket libraries.
When initializing the socket library, specify the send/receive buffer size, the number of threads using sockets, and the pointer to and size of working memory specified by the socket library.
Set the send/receive buffer size to 64 KB. Depending on the NEX thread mode used, the number of threads is as follows.
PiaTransport calls sockets from three threads. With NEX, sockets are called from two threads in unsafe transport buffer thread mode and from one thread in unsafe user thread mode.
Accordingly, if threadNum is set as the number of threads, you can get the required size of working memory with nn::socket::GetRequiredMemorySize(64*1024, threadNum).
Specify the value in the nn::socket::Initialize function and initialize the socket library.
Log in to the friend server using the friend library of the CTR-SDK.
Call NEX as you normally would for server services such as logging in to the game server and matchmaking. Use nn:nex::NgsFacade to log in to the game server.
After you successfully log in to the game server, call the Bind() function, which takes a pointer to nn::pia::inet::NexFacade::LoginInfo as a parameter, to set the game server information. The inet::NexFacade::LoginInfo passed as an argument is only accessed when making the API function call. The instance can safely be destroyed after the API function call.
nn::pia::inet::NexFacade::LoginInfo loginInfo;
loginInfo.gameServerId = MATCHMAKE_GAME_ID; // The game server ID specified when logging in to the game server. loginInfo.pNgsFacade = pNgsFacade; // The nn::nex::NgsFacade instance that logged in to the game server. nn::pia::inet::NexFacade::GetInstance()->Bind(&loginInfo); |
After successfully logging in, you call PiaSession API functions to create or join sessions. For more information, see 6.4. Basic Features - Browse Matchmaking and 6.5. Basic Features - Random Matchmaking.
During the asynchronous processes for creating or joining session::Session sessions, Pia calls inet::NexFacade::Startup and inet::NexFacade::StartNatSessionAsync to start a NAT session (P2P communication). Pia also calls inet::NexFacade::Cleanup and inet::NexFacade::StopNatSession to end the NAT session during the asynchronous processes for destroying or leaving sessions.
To advance the inet::NexFacade::StartNatSessionAsync asynchronous processing, call the NEX dispatch function and the Pia dispatch function at a frequency of once or twice per game frame. This process is handled in a background thread in Pia. Other threads must be put to sleep as necessary to ensure that this background thread gets sufficient CPU time.
Server DNS name resolution is done to determine the NAT type only the first time after the application starts. This name resolution runs in the background. If the WAN cable on the router is unplugged before name resolution is complete, this process may take 30 or more seconds to finish because the router waits for name resolution to time out. You cannot cancel this name resolution process.
While a station is joining a P2P mesh network, NAT traversal is performed automatically. (NAT traversal enables P2P communication between stations.) If all stations are EIMs, NAT traversal completes quickly. If the local station or a peer is an EDM station, NAT traversal takes longer because port detection is needed. Because port detection cannot be done in parallel, NAT traversal completion time takes longer in proportion to the number of operations being performed.
If NAT traversal fails because of failure to detect an EDM port or similar reasons, the result is a NAT traversal failure error (such as ResultNatTraversalFailedLocalEimRemoteEdm).
For more information about the session joining process, see 6.4. Basic Features - Browse Matchmaking and 6.5. Basic Features - Random Matchmaking in the Programming Manual.
Call the Pia dispatch function (pia::common::Scheduler) during a NAT session (between the start of the session and session cleanup). (For more information about dispatching with Pia, see 5. PiaTransport Guide.)
You must call the NEX dispatch function to communicate with a server while using NEX. There is no issue with regard to calling order. When using PiaInet, all P2P communication occurs on the P2P side. NEX dispatching is only needed for communication with the server. You can lighten the load on the CPU by calling the NEX dispatch function less frequently, but you might interfere with server operations if the interval is too long, so keep the interval between calls to within about 100 milliseconds.
Dispatching for NEX and Pia must be called in the same thread.
nn::pia::common::Scheduler* pScheduler = nn::pia::common::Scheduler::GetInstance();
if (pScheduler) { result = pScheduler->Dispatch(PIA_DISPATCH_TIMEOUT); } s_NexDispatchPeriod = NEX_DISPATCH_PERIOD_IN_P2P_SESSION; if ((nn::pia::framework::Framework::GetInstance()->GetFrameCount() % s_NexDispatchPeriod) == 0) { nn::nex::Scheduler::GetInstance()->Dispatch(NEX_DISPATCH_TIMEOUT); } |
After the NexFacade cleanup process and before logging out from the NEX game server, call the NexFacade::Unbind() function to delete the game server setting information.