C++ Client Guide #
The official C++ client handles all communication in real-time with the server. It implements all features in the server and is written with C++11.
The C++ client is open source on GitHub. Please report issues and contribute code to help us improve it.
Full API documentation #
For the full API documentation please visit the API docs.
The client can be downloaded from the GitHub releases. You can download
For upgrades you can see changes and enhancements in the CHANGELOG before you update to newer versions.
When you’ve downloaded the Nakama C++ archive and extracted it to
NAKAMA_CPP_SDK folder, you should include it in your project.
We don’t recommend to copy Nakama C++ SDK to your project because it’s quite big in size (~1 Gb).
Setup for Mac and iOS projects #
Build Settings > Header Search Paths
- Add libs folder in
Build Settings > Library Search Paths:
NAKAMA_CPP_SDK/libs/ios- for iOS
NAKAMA_CPP_SDK/libs/mac- for Mac
- Add all
.afiles located in libs folder and
General > Frameworks, Libraries, and Embedded Content
Setup for Android projects #
If you use
CMake then see Setup for CMake projects section.
If you use
ndk-build then add following to your
Initialize Nakama SDK #
For most NativeActivity projects, if you have an entry point like:
Add the following code at the top of the
Be aware that the client shared library size is approximately 100MB. After final target device compilation, the size will be drastically reduced to only a few megabytes.
Android permissions #
Android uses a permissions system which determines which platform services the application will request to use and ask permission for from the user. The client uses the network to communicate with the server so you must add the “INTERNET” permission.
Setup for CMake projects #
To link Nakama’s static lib add following to your
To link Nakama’s shared lib add following to your
Setup for Visual Studio projects #
Project Settings add following:
C/C++ > General > Additional Include Directories
- Add libs folder in
Linker > General > Additional Library Directories:
NAKAMA_COCOS2D_SDK/libs/win32/v140- for VS 2015 x86
NAKAMA_COCOS2D_SDK/libs/win64/v140- for VS 2015 x64
NAKAMA_COCOS2D_SDK/libs/win32/v141- for VS 2017 x86
NAKAMA_COCOS2D_SDK/libs/win64/v141- for VS 2017 x64
NAKAMA_COCOS2D_SDK/libs/win32/v142- for VS 2019 x86
NAKAMA_COCOS2D_SDK/libs/win64/v142- for VS 2019 x64
- Add all
.libfiles located in libs folder in
Linker > Input > Additional Dependencies
Custom setup #
- add define:
NLOGS_ENABLED- define it if you want to use Nakama logger. See Logging section
- add include directory:
- add link directory:
- add all libraries for linking from link directory
For Mac and iOS:
Include nakama header.
Use nakama namespace.
The client object is used to execute all logic against the server.
createDefaultClient will create HTTP/1.1 client to use REST API.
tick method pumps requests queue and executes callbacks in your thread. You must call it periodically (recommended every 50ms) in your thread.
Without this the default client and real-time client will not work, and you will not receive responses from the server.
To authenticate you should follow our recommended pattern in your client code:
- Build an instance of the client:
- Authenticate a user. By default Nakama will try and create a user if it doesn’t exist:
It’s good practice to cache a device identifier on Android when it’s used to authenticate because they can change with device OS updates.
In the code above we use
authenticateDevice() but for other authentication options have a look at the code examples.
When authenticated the server responds with an auth token (JWT) which contains useful properties and gets deserialized into a
It is recommended to store the auth token from the session and check at startup if it has expired. If the token has expired you must reauthenticate. The expiry time of the token can be changed as a setting in the server.
A full example class with all code above is here.
Send requests #
When a user has been authenticated a session is used to connect with the server. You can then send messages for all the different features in the server.
All requests are sent with a session object which authorizes the client.
Have a look at other sections of documentation for more code examples.
Real-time client #
The client can create one or more real-time clients. Each real-time client can have it’s own event listener registered for responses received from the server.
The socket is exposed on a different port on the server to the client. You’ll need to specify a different port here to ensure that connection is established successfully.
Don’t forget to call
tick method. See Tick section for details.
To join a chat channel and receive messages:
There are more examples for chat channels here.
Handle events #
A real-time client has event handlers which are called on various messages received from the server.
Event handlers only need to be implemented for the features you want to use.
|onDisconnect||Received when the client is disconnected from the server.|
|onNotification||Receives live in-app notifications sent from the server.|
|onChannelMessage||Receives real-time chat messages sent by other users.|
|onChannelPresence||Receives join and leave events within chat.|
|onMatchState||Receives real-time multiplayer match data.|
|onMatchPresence||Received join and leave events within real-time multiplayer.|
|onMatchmakerMatched||Received when the matchmaker has found a suitable match.|
|onStatusPresence||Receives status updates when subscribed to a user status feed.|
|onStreamPresence||Receives stream join and leave event.|
|onStreamState||Receives stream data sent by the server.|
Initializing Logger #
Client logging is off by default.
To enable logs output to console with debug logging level:
To enable logs output to custom sink with debug logging level:
To use logging macroses you have to define
Using Logger #
To log string with debug logging level:
NLOG(NLogLevel::Info, "This is string: %s", "yup I'm string"); NLOG(NLogLevel::Info, "This is int: %d", 5);
Changing logging level boundary:
NLogger behavior depending on logging level boundary:
Debugwrites all logs.
Infowrites logs with
Warnwrites logs with
Errorwrites logs with
Fatalwrites only logs with
The server and the client can generate logs which are helpful to debug code.
To enable client logs see Initializing Logger section.
In every request in the client you can set error callback. It will be called when request fails. The callback has
NError structure which contains details of the error:
The client writes all errors to logger so you don’t need to do this.
Full C++ example #
An example class used to manage a session with the C++ client.
Client reference #
You can find the C++ Client Reference here.