Libpitaya is currently under development and is not yet ready for production use. We are working on tests and better documentation and we'll update the project as soon as possible.
Libpitaya C# binding for 4.0.0 and above require Unity 2019.3 to work.
Libpitaya is a SDK for building clients for projects using the pitaya game server framework and is built on top of libpomelo2
Libpitaya is build using CMake. A standard build for linux could be something like:
cd libpitaya
cmake -H. -B_builds/linux -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release
cmake --build _builds/linux
Below we show how to build for all major platforms.
NOTE: In the Makefile
there are helper targets that allow you to build for different platforms. Libpitaya is primarly developed to be used from other programming languages aside from C and C++, however, it should be possible to include the libpitaya CMake target from another CMake project using add_subdirectory
.
# Pick the correct setup for your platform
make setup-android-mac
make setup-android-linux
# Build
make build-android
The Android binary will be under _builds/android/libpitaya-android.so
make setup-mac
make build-mac
The Mac binary will be under _builds/mac/libpitaya-mac.bundle
make setup-mac
make build-ios
The iOS binary will be under _builds/ios/libpitaya-ios.a
On iOS, this library will be compiled statically which means you must include in your project the dependencies libz.a
,libuv_a.a
,libssl.a
and libcrypto.a
as well.
make setup-mac
make build-ios-simulator
The iOS binary will be under _builds/ios-simulator/libpitaya-ios.a
As for physical device build, this library will be compiled statically, and other dependencies must be included manually.
make setup-mac
make build-ios-xcframework
The xcframework will be under _builds/ios-xcframework-libpitaya
You can also build openssl xcframeworks using make build-openssl-ios-xcframework
make build-windows
The binaries for windows will then be located at _builds/windows/pitaya-windows.dll
and _builds/windows/pitaya-windows.lib
.
make build-linux
The binaries for windows will then be located at _builds/linux/pitaya-linux.so
.
- Note, however, that the chosen options can be changed if you need a different combination. For example, you can easily build statically on linux if you want. Take the Make target as an example.
Build the mac-tests image
make build-mac-tests
Build the binaries for the test Go servers
make docker-build
Start the test Go servers and their dependencies
docker compose up
In order to run the tests, you need node installed. Running the tests are done by running the following script in the root folder:
# The tests executable path are always placed alongside the pitaya library.
./run-tests.py --tests-dir <tests-executable-directory.. e.g. _builds/mac-tests>
You can also pass command line options, for example:
# Lists all of the tests
./run-tests.py --tests-dir <tests-executable-directory> --list
# Runs one test by name
./run-tests.py --tests-dir <tests-executable-directory> /compression/enabled
# Runs one suite of tests
./run-tests.py --tests-dir <tests-executable-directory> /tls
You can also run the tests directly through the executable. The problem is that the mock servers will not be started, therefore some tests will fail. You can avoid that by manually starting the servers located in test/mock-servers
using ./run-tests.py --only-deps
.
Libpitaya contributions should be done by making a Pull Request from a different branch.
In order to run, edit and debug the code, you can generate native projects with CMake. For example, to create an XCode project, you can run the following commands:
git clone https://github.com/topfreegames/libpitaya
cd libpitaya
cmake -H. -B_builds/xcode
# The previous command has created an xcode project inside _builds/xcode.
# You can build with the command line if you want to:
cmake --build _builds/xcode --config Release
cmake --build _builds/xcode --config Debug
# Or you can open the project with xcode and use it through the IDE
open _builds/xcode/pitaya.xcodeproj
After you have edited, and builded the code, you should run the tests and make sure that they pass and also add a test for your specific change. The tests are separated in suites (a suite is a group of related tests). Each suite is located in its own source file under the test directory with names in the format test_.c. If the addition is related to an existing suite, you can just create the new test and add it to the suite (it is just a function). However, if the functionality belongs in a new suite, you have to create the file and add it to cmake under the following block of code in CMakeLists.txt:
add_executable(pitaya_tests
# Sources
test/main.c
test/test_compression.c
test/test_kick.c
test/test_notify.c
test/test_pc_client.c
#==== Add your file here ====
test/test_my_new_suite.c
#============================
)
Having added the file, you need to tell test/main.c that there is a new suite to be run, this can be done in the test/main.c source file:
static const int SUITES_START = __LINE__;
extern const MunitSuite pc_client_suite;
extern const MunitSuite tcp_suite;
extern const MunitSuite tls_suite;
extern const MunitSuite session_suite;
extern const MunitSuite reconnection_suite;
extern const MunitSuite compression_suite;
extern const MunitSuite kick_suite;
extern const MunitSuite request_suite;
extern const MunitSuite notify_suite;
extern const MunitSuite stress_suite;
extern const MunitSuite protobuf_suite;
extern const MunitSuite push_suite;
extern const MunitSuite my_new_suite; // ==> Add your new suite here. Do NOT add new lines
static const int SUITES_END = __LINE__;
...
static MunitSuite *
make_suites()
{
...
suites_array[i++] = pc_client_suite;
suites_array[i++] = tcp_suite;
suites_array[i++] = tls_suite;
suites_array[i++] = session_suite;
suites_array[i++] = reconnection_suite;
suites_array[i++] = compression_suite;
suites_array[i++] = kick_suite;
suites_array[i++] = request_suite;
suites_array[i++] = notify_suite;
suites_array[i++] = stress_suite;
suites_array[i++] = protobuf_suite;
suites_array[i++] = push_suite;
suites_array[i++] = my_new_suite;
...
}
Having done this, you can now run the tests using the run-tests.py script. If the tests pass, you should open a pull request.
NOTE: In most cases, you can just add the changes to the native library and it should be fine. However, if you change the interface of the library, you have to also update the csharp library.
Use it like the following:
# Android armv7
./build-openssl.py --prefix /tmp/build_dir/android --compile-threads 32 --openssl-tar deps/openssl-1.1.1q.tar.gz android --ndk-dir /home/...path to.../android-ndk-r25b --arch armv7a
# Android aarch64
./build-openssl.py --prefix /tmp/build_dir/android --compile-threads 32 --openssl-tar deps/openssl-1.1.1q.tar.gz android --ndk-dir /home/...path to.../android-ndk-r25b --arch aarch64
# Linux
CC=gcc ./build-openssl.py --prefix /tmp/build_dir/linux --compile-threads 32 --openssl-tar deps/openssl-1.1.1q.tar.gz linux
# Mac and iOS
For these we use the project at https://github.com/tfgco/OpenSSL
For more information, please look in this document.
When using libpitaya on mobile, it is important to understand some aspects of its behaviour on Android and iOS. A pitaya client will always create a background thread that runs a libuv instance. The behaviour of this thread is different on iOS and Android.
When the application minimizes (goes to background), the pitaya thread will completely stop. This means that it will stop checking for hearbeats and also stop sending heartbeats. It will also stop any kind of pending requests for example. When the app goes back into foreground, the thread will start again. Since the thread stops, the server will stop receiving heartbeats from the client and may disconnect it if the heartbeat timeout passes, so depending on the heartbeat timeout configured by the server, making the app go to background may force the server to disconnect the client.
The same scenario on Android does not block the thread, but it's quite the opposite. When the app is minimized the thread will continue running even though the app is in background. Since the thread is still sending heartbeats, the connection will not be dropped by the server. This could be a problem since the user might not wish to have the thread still alive while the app is in background.
If a consistent behaviour for Android and iOS is meant to be achieved, the default behaviour for both platforms will not make this possible. A possible solution is to force a disconnect when the app minimizes regardless of the platform. This disconnection can be triggered instantly or after X amount of seconds, for example. When the app is again in foreground a new connection can be created.