SmartFoxServer 3 C++ Client API 3.1.0-beta
Client API for SmartFoxServer 3
Loading...
Searching...
No Matches
SmartFoxServer 3 C++ Client API

This is the reference documentation of the C++ client API for SmartFoxServer 3.

The API connects a C++ application to a SmartFoxServer 3 instance, keeps the state of the User and Rooms in sync, and reports what happens on the server as events. It targets game engines, so it uses no RTTI and lets no exception escape through its boundary. The base language level is C++17.

The session model

A sfs3::SmartFox instance models one session cycle:

Connect -> Play -> Disconnect

Once the TCP connection is closed the instance is spent. Discard it and create a new one for another session. The API is not designed to be reused across a disconnection.

The standard setup sequence is:

  1. Connect over TCP with sfs3::SmartFox::connect. It falls back to BlueBox (HTTP tunnel) if a direct connection is not possible. If this fails the server is unreachable, and the current instance is invalid. You can dispose of it and build a new one, if you want to try again.
  2. Log in with sfs3::requests::LoginRequest, to join a Zone (one of the server's applications/games)
  3. Start UDP with sfs3::SmartFox::connectUdp, if the application needs it. This step is optional.

If UDP fails to start, it is unusable on the current device. There is no automatic retry, and calling connectUdp() again is refused. The choices are to tell the player that a hard requirement is unmet, to set sfs3::ConfigData::useTcpFallback so UDP traffic is silently re-routed over TCP, or to restart the whole session from scratch with a new instance. A UDP connection that started and then dropped in mid-game is a different case: there, a manual retry is allowed in place.

Sending requests, receiving events

You send a request and you get an event back. Requests live in the sfs3::requests namespace and all go through sfs3::SmartFox::send:

sfs.send(sfs3::requests::LoginRequest("zoneName", "userName"));

Events are the sfs3::event::SFSEvent enumeration. You register one handler per event type with addEventListener. The handler receives a sfs3::event::ApiEvent reference, which you cast to the payload struct that belongs to the type you registered for; sfs3::event::SFSEvent lists which struct goes with which type.

By default the API queues the events instead of dispatching them right away. Call sfs3::SmartFox::processEvents from your game loop: it empties the queue and calls your handlers on the thread that called it. This is what a game engine needs, since game objects can only be touched from the main thread.

Turn sfs3::ConfigData::threadSafeMode off if you want the opposite. The API then calls your handlers itself, on its own network thread, as soon as an event happens, and sfs3::SmartFox::processEvents does nothing.

A first connection

This connects to a SmartFoxServer 3 instance on the same machine and, once the connection is up, logs in the Playground Zone. Every standard installation has that Zone, and the defaults of sfs3::ConfigData already point at a local server on port 9977, so nothing has to be configured.

#include "ConfigData.h"
#include "SmartFox.h"
#include "event/SFSEvent.h"
#include "log/Log.h"
#include "requests/LoginRequest.h"
using namespace sfs3;
int main()
{
SmartFox sfs;
ConfigData cfg; // host 127.0.0.1, port 9977, zone "Playground"
{
auto& evt = static_cast<const event::Connection&>(e);
if (!evt.success)
{
// The server is unreachable. This SmartFox instance is now spent:
// to try again, discard it and build a new one.
log::warn("Connection failed: {}", evt.errMessage.value_or("unknown reason"));
return;
}
log::info("Connected to {}:{}", cfg.host, cfg.port);
sfs.send(requests::LoginRequest { "myUserName" });
});
{
auto& evt = static_cast<const event::Login&>(e);
// The server has the last word on the name: it can change the one you
// asked for, and a Zone with a guest system assigns one on its own.
log::info("Logged in zone {} as {}", evt.zoneName, evt.mySelf->getName());
});
{
auto& evt = static_cast<const event::LoginError&>(e);
log::error("Login failed ({}): {}", evt.errorCode, evt.errorMessage);
});
// Start the connection. It is made in the background, so a failed Result here
// means the settings are not valid, not that the server refused the connection.
auto res = sfs.connect(cfg);
if (!res.ok)
{
log::error("Cannot start the connection: {}", res.error.value_or("unknown reason"));
return 1;
}
bool running = true;
while (running)
{
// Events are queued, so the loop must drain them. This is where the
// handlers above are called.
// ... the rest of the game loop
}
}
Doxygen only documents namespace-scope entities (enums, aliases, constants, free functions) in a head...
@ LOGIN
The login in a Zone succeeded.
Definition SFSEvent.h:60
@ LOGIN_ERROR
The login in a Zone failed.
Definition SFSEvent.h:63
@ CONNECTION
The result of a connection attempt.
Definition SFSEvent.h:42
The main class of the SmartFoxServer 3 API.
Definition SmartFox.h:42
Result connect(ConfigData cfgData)
Attempts to connect to the server.
Definition SmartFox.cpp:64
void processEvents()
Processes all the queued events and calls the related handlers, in the current thread.
Definition SmartFox.cpp:456
Result send(core::BaseRequest &req)
Sends a request to the server.
Definition SmartFox.cpp:116
void addEventListener(EventType evtType, event::EventListener listener)
Adds a listener that handles one event type.
Definition Listenable.h:35
Logs the current user in one of the server Zones.
Definition LoginRequest.h:29
Holds all the settings for the connection.
Definition ConfigData.h:16
std::string host
The host to connect to.
Definition ConfigData.h:35
int port
The TCP port used for the connection.
Definition ConfigData.h:38
The base of every event dispatched by the API.
Definition SFSEvent.h:219
Dispatched when a connection to a SmartFoxServer 3 instance is attempted.
Definition SFSEvent.h:258
Dispatched when the login fails.
Definition SFSEvent.h:409
Dispatched after a successful login in a Zone.
Definition SFSEvent.h:370

The login name is the only value the example supplies. A Zone with a custom login system also takes a password and a set of parameters; see sfs3::requests::LoginRequest.

The sfs3::log calls above are the API's own logger, which your application can use as well. It takes {} placeholders, in the order of the arguments that follow. A message below the current level costs almost nothing, because the text is only built when the level is on; the level starts at Info, so the debug messages of the API are hidden until you call sfs3::log::setLevel. Output goes to the console by default. To send it somewhere else — the log of a game engine, for one — install your own function with sfs3::log::setSink.

Where things are

Namespace Holds
sfs3 sfs3::SmartFox, sfs3::ConfigData — the entry point and its settings
sfs3::entities Rooms, Users, Buddies, Variables, and the data types sfs3::entities::SFSObject and sfs3::entities::SFSArray
sfs3::entities::match The matching expressions used to search Rooms and Users
sfs3::requests Everything you can ask the server to do
sfs3::event The event types and their payloads
sfs3::core The Room, User and Buddy managers
sfs3::net Transport-level types, such as sfs3::net::TransportType

The layers below these — the BitSwarm client, the IO handlers, the protocol codec and the RDP transport — are internal and are left out of this documentation, along with any member tagged @internal.

Learn more

To learn more about SmartFoxServer 3 and of all of its features we highly recommend to visit the official documentation website, where you can find lots of examples, code recipes and detailed guides.