Skip to the content.

Contents

1. Environment construction

Before you start, please must read concept and spec

How to set up the Tars C++ environment, please refer to the article tars_install.md.

2. Service naming

The service name of the Tars framework consists of three parts:

APP: Application name. it identifies a small set of service. In the Tars system, the app name must be unique. For example: TestApp.

Server: Service name. A process provides service. It’s named according to the service function and generally named as XXServer. For example: HelloServer.

Servant:The name of provider. An interface or instance that provides a specific service. For example: HelloImp.

Instructions:

A Server can contain multiple Servant, and the system will use App + Server + Servant combination to define the routing name of the service in the system, called routing object. This name must be unique in the whole system, so that would uniquely identify itself when it externally served.

Therefore, when defining an App, you need pay attention to the uniqueness of the App.

For Example:TestApp.HelloServer.HelloObj.

3. Tars management system

When you login successfully, you will enter the Tars management system, as shown below:

tars

Under the menu tree of the Tars management system, the following functions are available:

4. Service deployment

Service deployment can actually be done after service development, but it is recommended to do it first.

As shown below:

tars

Click “Submit”, after success, the TestApp application under the menu will display the name of the HelloServer, and you will see the information of the new service program on the right side, as shown below.

tars

The deployment on the management system is temporarily completed, so far, it just makes your service occupy a position on the management system, the real program has not been released yet.

5. Service development

5.1. Create service

5.1.1. Run Tars script

/usr/local/tars/cpp/script/cmake_tars_server.sh [App] [Server] [Servant]

Executed in this example:/usr/local/tars/cpp/script/cmake_tars_server.sh TestApp HelloServer Hello

After the command is executed, the following file will be generated in the “TestApp/HelloServer/src” of the current directory.

HelloServer.h HelloServer.cpp Hello.tars HelloImp.h HelloImp.cpp CMakeLists.txt
cd build
cmake ..
make -j4

These files already contain the most basic service framework and default test interface implementation.

5.1.2. Tars interface file

For the syntax and usage of the tars interface file, see tars_tup.md.

As follows:

Hello.tars:

module TestApp
{

interface Hello
{
    int test();
};

}; 

Automatically generate C++ files using the tars2cpp tool:

/usr/local/tars/cpp/tools/tars2cpp hello.tars

Running this command will generate a hello.h file containing the client and server code.

5.1.3. HelloImp is the interface implementation class of Servant

Implement the interface test in file Hello.tars, as follows:

HelloImp.h


#ifndef _HelloImp_H_
#define _HelloImp_H_

#include "servant/Application.h"
#include "Hello.h"

/**
 * HelloImp inherits the Hello object defined in hello.h
 *
 */
class HelloImp : public TestApp::Hello
{
public:
    /**
     *
     */
    virtual ~HelloImp() {}

    /**
     * Initialization, Hello's virtual function, called when HelloImp is initialized
     */
    virtual void initialize();

    /**
     * Destructor, Hello's virtual function, called when HelloImp exits
     */
    virtual void destroy();

    /**
     * Implement the test interface defined in the Tars file
     */
    virtual int test(tars::TarsCurrentPtr current) { return 0;};

};
/////////////////////////////////////////////////////
#endif

HelloImp.cpp:


#include "HelloImp.h"
#include "servant/Application.h"

using namespace std;

//////////////////////////////////////////////////////
void HelloImp::initialize()
{
    //initialize servant here:
    //...
}

//////////////////////////////////////////////////////
void HelloImp::destroy()
{
    //destroy servant here:
    //...
}

5.1.4. HelloServer is the implementation class of the service

As follows:

HelloServer.h:

#ifndef _HelloServer_H_
#define _HelloServer_H_

#include <iostream>
#include "servant/Application.h"

using namespace tars;

/**
 * HelloServer inherits from the Application class in the Tars framework
 **/
class HelloServer : public Application
{
public:
    /**
     *
     **/
    virtual ~HelloServer() {};

    /**
     * Service initialization interface
     **/
    virtual void initialize();

    /**
     * Cleanup interface when the service exitsd
     **/
    virtual void destroyApp();
};

extern HelloServer g_app;

////////////////////////////////////////////
#endif

HelloServer.cpp:

#include "HelloServer.h"
#include "HelloImp.h"

using namespace std;

HelloServer g_app;

/////////////////////////////////////////////////////////////////
void
HelloServer::initialize()
{
    //initialize application here:

    //Add the binding relationship between the HelloImp and the route Obj.
    addServant<HelloImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".HelloObj");
}
/////////////////////////////////////////////////////////////////
void
HelloServer::destroyApp()
{
    //destroy application here:
    //...
}
/////////////////////////////////////////////////////////////////
int
main(int argc, char* argv[])
{
    try
    {
        g_app.main(argc, argv);
        g_app.waitForShutdown();
    }
    catch (std::exception& e)
    {
        cerr << "std::exception:" << e.what() << std::endl;
    }
    catch (...)
    {
        cerr << "unknown exception." << std::endl;
    }
    return -1;
}
/////////////////////////////////////////////////////////////////

5.2. Compile

Enter the code directory, first do:

cd build
cmake ..
make -j4
#make HelloServer.tgz
make HelloServer-tar
#upload to web and publish
make HelloServer-upload

5.3. Extensions

The Tars framework provides an interface definition language that can be used in tars files to add interfaces and methods to extend the functionality of the service.

You can modify the tars file generated by cmake_tars_server.sh. In the following two interface methods, test is generated by default, and testHello is the newly added interface.

module TestApp
{

interface Hello
{
    int test();
    int testHello(string sReq, out string sRsp);
};

}; 

using /usr/local/tars/cpp/tools/tars2cpp hello.tars regenerate hello.h.

Modify HelloImp.h/HelloImp.cpp to implement the new interface code.

The testHello method that inherits the Hello class from HelloImp.h:

virtual int testHello(const std::string &sReq, std::string &sRsp, tars::TarsCurrentPtr current);

HelloImp.cpp implements the testHello method:

int HelloImp::testHello(const std::string &sReq, std::string &sRsp, tars::TarsCurrentPtr current)
{
    TLOGDEBUG("HelloImp::testHellosReq:"<<sReq<<endl);
    sRsp = sReq;
    return 0;
}

Re-execute the following command to compile:

cd build
cmake ..
make -j4
make HelloServer-tar

it will regenerate the HelloServer.tgz release package.

5.4. Client synchronous/asynchronous call service

On the development environment, create the /home/tarsproto/[APP]/[Server] directory.

For the example above:/home/tarsproto/TestApp/HelloServer.

Executing the command:

make release 
or
make HelloServer-release

it will generate .h, .tars files in the /home/tarsproto/TestApp/HelloServer directory.

In this way, when a service needs to access the HelloServer, it directly references the above file, and does not need to copy the .tars file of the HelloServer (that is, the tars file of the HelloServer does not need to be stored in the code directory).

Create a client code directory, like TestHelloClient/

Write file main.cpp, create an instance and call the interface function just written to test.

Synchronously:

#include <iostream>
#include "servant/Communicator.h"
#include "Hello.h"

using namespace std;
using namespace TestApp;
using namespace tars;

int main(int argc,char ** argv)
{
    Communicator comm;

    try
    {
        HelloPrx prx;
        comm.stringToProxy("TestApp.HelloServer.HelloObj@tcp -h 10.120.129.226 -p 20001" , prx);

        try
        {
            string sReq("hello world");
            string sRsp("");

            int iRet = prx->testHello(sReq, sRsp);
            cout<<"iRet:"<<iRet<<" sReq:"<<sReq<<" sRsp:"<<sRsp<<endl;

        }
        catch(exception &ex)
        {
            cerr << "ex:" << ex.what() << endl;
        }
        catch(...)
        {
            cerr << "unknown exception." << endl;
        }
    }
    catch(exception& e)
    {
        cerr << "exception:" << e.what() << endl;
    }
    catch (...)
    {
        cerr << "unknown exception." << endl;
    }

    return 0;
}

Asynchronous:

#include <iostream>
#include "servant/Communicator.h"
#include "Hello.h"

using namespace std;
using namespace TestApp;
using namespace tars;

class HelloCallBack : public HelloPrxCallback
{
public:
    HelloCallBack(){}

    virtual ~HelloCallBack(){}

    virtual void callback_testHello(tars::Int32 ret,  const std::string& sRsp)
    {
        cout<<"callback_testHello ret:"<< ret << "|sRsp:" << sRsp <<endl; 
    }

    virtual void callback_testHello_exception(tars::Int32 ret)
    {
        cout<<"callback_testHello_exception ret:"<< ret <<endl;
    }
};

int main(int argc,char ** argv)
{
    Communicator comm;

    try
    {
        HelloPrx prx;
        comm.stringToProxy("TestApp.HelloServer.HelloObj@tcp -h 10.120.129.226 -p 20001" , prx);

        try
        {
            string sReq("hello world");
            HelloPrxCallbackPtr cb = new HelloCallBack();
            prx->async_testHello(cb, sReq);
            cout<<" sReq:"<<sReq<<endl;
        }
        catch(exception &ex)
        {
            cerr<<"ex:"<<ex.what() <<endl;
        }
        catch(...)
        {
            cerr<<"unknown exception."<<endl;
        }
    }
    catch(exception& e)
    {
        cerr<<"exception:"<<e.what() <<endl;
    }
    catch (...)
    {
        cerr<<"unknown exception."<<endl;
    }

    getchar();

    return 0;
}

Edit the makefile, which contains the mk file in the /home/tarsproto/[APP]/[Server] directory that was just generated by make release, as follows:

#-----------------------------------------------------------------------
APP         :=TestApp
TARGET      :=TestHelloClient
CONFIG      :=
STRIP_FLAG  := N

INCLUDE     += -I/home/tarsproto/TestApp/HelloServer
LIB         +=
#-----------------------------------------------------------------------
include /usr/local/tars/cpp/makefile/makefile.tars
#-----------------------------------------------------------------------

Make the target file, upload it to the environment where you can access the server and run the test.

It is strongly recommended that you use cmake to manage the source code

6. Service release

In the menu tree of the management system, find the service you deployed, click to enter the service page.

first Select “Publish Management”, then select the node to be published, then click “Publish Selected Node”, and finally click “Upload Release Package”, select the compiled package. As shown below:

tars

After the upload is successful, click the “Select Release Version” drop-down box and the service program you uploaded will appear. Select the top one (latest uploaded). As shown below:

tars

Click “Publish”, the service starts to be released, after the release is successful, the following interface appears, as shown below:

tars

If it fails, it may be a naming problem, an upload problem, and other environmental issues.