EzyFox C++ Client SDK
Updated at 16998042940001. Introduce
EzyFox C++ SDK is a C/C++ client library of EzyFox Server. It supports TCP and UDP protocol and use MessagePack for data transportation. You can use this SDK for every projects use C/C++ (i.e android, iOS, desktop apps). It's free available and open source on Github2. Installation
Clone ezyfox-server-cpp-client to your project:
    git clone https://github.com/youngmonkeys/ezyfox-server-cpp-client.git
For Android JNI, you need add this line to Android.mk file
import-module, ezyfox-client)
For Android use cmake, you need add two lines to CMakeLists.txt file
add_subdirectory(ezyfox-client)
    target_link_libraries(${APP_NAME} ezyfox-client)
For iOS, you just need add ezyfox-client.xcodeproj to your project:
 
 
3. Coding
Completed source code avalable on Space Game example, class SocketClientProxy
3.1 Import
    #include "EzyHeaders.h"
3.2 Create a configuration
Please take a look EzyClientConfig class if you want to see more configurable fields.
    auto config = config::EzyClientConfig::create();
    config->setClientName(ZONE_NAME);
3.2 Create a Client
After create the configuration, you can create a client like this. Take a look EzyClient and EzyClients to get more information.
    mSocketClient = EzyUTClient::create(config);
    EzyClients::getInstance()->addClient(mSocketClient);
3.3 Setup the Client
After create the client, let's setup it, 'setup' mean add event handlers and data handlers to the client. List of event handlers include:
- ConnectionSuccess: Fire when the client connected to server
- ConnectionFailure: Fire when the client connect to server failed
- Disconnection: Fire when the client was disconnected from server
- LostPing: Fire when client send ping but didn't received pong command from server
- TryConnect: Fire when the client connect to server failed and retry to connect again
Take a look EzyEventType class to get more information. List of data commands include:
- Error: Fire when the client received and error from server
- Handshake: Client send and receive handshake command
- Ping: Client send ping command to keep connection
- Pong: Fire when client received pong response from server
- Login: Client send and receive login command if login successfully
- LoginError: Fire when received login error response from server
- AppAccess: Client send this command to join to an application and receive when join successfully
- AppRequest: Client send data to an application on server and receive if there is any response
- AppExit: Client send to server to exit from an application
- AppAccessError: Fire when received join an application failed from server,
- AppRequestError: Fire when received an error response from application on server,
- PluginInfo: Client send to get information of a plugin and receive response from server,
- PluginRequest: lient send data to an plugin on server and receive if there is any response
Take a look constant package, EzyCommand class, EzyEventHandler class and EzyDataHandler class to get more information and you can setup the client like this:
    auto setup = mSocketClient->setup();
    setup->addEventHandler(event::ConnectionSuccess, new handler::EzyConnectionSuccessHandler());
    setup->addEventHandler(event::ConnectionFailure, new handler::EzyConnectionFailureHandler());
    setup->addEventHandler(event::Disconnection, new DisconnectionHandler());
    setup->addDataHandler(constant::Handshake, new HandshakeHandler());
    setup->addDataHandler(constant::Login, new LoginSuccessHandler());
    setup->addDataHandler(constant::LoginError, new handler::EzyLoginErrorHandler());
    setup->addDataHandler(constant::AppAccess, new AppAccessHandler());
    setup->addDataHandler(constant::UdpHandshake, new UdpHandshakeHandler());
For TCP we need follow by the authenticaiton flow:
 
For UDP we need follow by the authenticaiton flow:
 
3.4 Customer an event handler
You can custom to do everything you want, please take a look EzyEventHandler and EzyEventHandlers to see default event handlers and take a look to this file for full example.
    class DisconnectionHandler : public handler::EzyDisconnectionHandler {
    protected:
        bool shouldReconnect(event::EzyDisconnectionEvent* event) override {
            return true;
        }
        void postHandle(event::EzyDisconnectionEvent* event) override {
            SocketClientProxy::getInstance()->emitDisconnected();
        }
    };
3.5 Custom a data handler
You must custom to handle list of commands:
- Handshake: to send Login command
- Login: to send AppAccess or PluginInfo command
You should custom to handle list of commands:
- LoginError: Maybe to show a notification to user
- AppAccess: Maybe to trigger something and allow user interact your application
Please take a look EzyDataHandler and EzyDataHandlers to get default data handlers and this file for full example
    class HandshakeHandler : public handler::EzyHandshakeHandler {
    protected:
        request::EzyRequest* getLoginRequest() {
            auto request = request::EzyLoginRequest::create();
            request->setZoneName(ZONE_NAME);
            request->setUsername(SocketClientProxy::getInstance()->getUsername());
            request->setPassword(SocketClientProxy::getInstance()->getPassword());
            auto data = new entity::EzyArray();
            data->addString(GAME_NAME);
            request->setData(data);
            return request;
        };
    };
    class LoginSuccessHandler : public handler::EzyLoginSuccessHandler {
    protected:
        void handleLoginSuccess(entity::EzyValue* responseData) {
            mClient->udpConnect(2611);
            if(SocketClientProxy::getInstance()->isFirstLogin())
                SocketClientProxy::getInstance()->setFirstLogin(false);
        }
    };
3.6 Setup an App
To listen and process response data of an application received from server you need setup to register handler mapped to command like this:
    auto appSetup = setup->setupApp(APP_NAME);
    appSetup->addDataHandler("reconnect", new ReconnectResponseHandler());
    appSetup->addDataHandler("getGameId", new GetGameIdResponseHandler());
    appSetup->addDataHandler("startGame", new StartGameResponseHandler());
3.7 Connect to server
After setup the client and an app, it's time to connect to server
    mSocketClient->connect("127.0.0.1", 3005); // replace by your server address and port
3.8 Send a request to server
After connect to server and access an app successfully (you need ensure by handle APP_ACCESS response), you can allow interact and send a request to server
Send a TCP request
    auto request = new entity::EzyObject();
    request->setString("gameName", GAME_NAME);
    mSocketClient->getApp()->send("getGameId", request);
Send an UDP request
    auto position = new entity::EzyObject();
    position->setDouble("x", x);
    position->setDouble("y", y);
    position->setDouble("z", 0);
    auto request = new entity::EzyObject();
    request->setString("gameName", GAME_NAME);
    request->setInt("gameId", gameId);
    request->setInt("objectId", objectId);
    request->setString("objectName", objectName);
    request->setBool("visible", visible);
    request->setObject("position", position);
    auto app = mSocketClient->getApp();
    if(app) {
        app->udpSend("syncPosition", request);
    }
And if you have accessed many application in the client, you must get the app you want to send a request:
    auto zone = mSocketClient->getZone();
    auto appManager = zone->getAppManager();
    auto app1 = appManager->getAppByName("appName");
    app1->send("requestCommand", request);
Please take a look EzyApp class to see how an app send a request to server, look EzyAppManager to see how to get an app. For full example please take a look this file
Start event loop
If you application has no loop update, you need add:
    socket::EzyMainEventsLoop* eventsLoop = new socket::EzyMainEventsLoop();
    eventsLoop->start();
If your application has a loop update, you just need to call:
    mSocketClient->processEvents();