blob: dba8368b7fc9976bdfee0e77f6252558465c15dd [file] [log] [blame]
// server.cpp : Defines the entry point for the console application.
//
// sample server command line app using Thrift IPC.
//
// This is a simple demonstration of full duplex RPC. That is, each
// side runs both a client and server to enable bidirectional event
// signaling.
//
#ifdef _WIN32
# include "stdafx.h"
#else
# include "config.h"
#endif
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Include this before the generated includes
#include "ThriftCommon.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Tailor these to your generated files
#include "../gen-cpp/SampleService.h"
#include "../gen-cpp/SampleCallback.h"
using namespace Sample; //declared in .thrift file
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int16_t ClientPort_;
std::string ClientPipeName_;
void S2CThreadProc();
//-----------------------------------------------------------------------------
// RPC implementations
//
class SampleServiceHandler : virtual public SampleServiceIf {
public:
SampleServiceHandler() {
// Your initialization goes here
}
void HelloThere(std::string& _return, const std::string& HelloString) {
// Your implementation goes here
printf("<<<HelloThere() received string: %s\n", HelloString.c_str());
_return = "Good thank you.";
}
void ServerDoSomething() {
// Your implementation goes here
printf("ServerDoSomething(): Simulating work for 5 seconds\n");
Sleep(5000);
printf("ServerDoSomething(): Done\n");
}
void ClientSideListenPort(const int16_t ClientListenPort)
{
ClientPort_ = ClientListenPort;
ClientPipeName_ = "";
#ifdef _WIN32
printf(">>>Connecting to client on port %d\n", ClientPort_);
boost::thread Connect2ClientThread(S2CThreadProc);
#endif
}
void ClientSidePipeName(const std::string& ClientPipeName)
{
ClientPipeName_ = ClientPipeName;
ClientPort_ = 0;
#ifdef _WIN32
printf(">>>Connecting to client pipe %s\n", ClientPipeName_.c_str());
boost::thread Connect2ClientThread(S2CThreadProc);
#endif
}
};
//-----------------------------------------------------------------------------
#ifdef _WIN32
int _tmain(int argc, _TCHAR* argv[])
#else
int main(int argc, char **argv)
#endif
{
int port;
std::string pipename; //e.g. "affpipe"
bool usage = false;
//Process command line params
if(argc > 1)
{
if(_tcscmp(argv[1], TEXT("-sp")) == 0)
{ //Socket Port specified
port = _tstoi(argv[2]);
#ifdef _WIN32
TWinsockSingleton::create();
#endif
// Start the thrift server which is a blocking call.
thriftcommon::RunThriftServer<SampleServiceHandler, SampleServiceProcessor>(10, port);
}
else if(_tcscmp(argv[1], TEXT("-np")) == 0)
{ //Named Pipe specified
#ifdef _WIN32
std::wstring wpipe(argv[2]);
pipename.resize(wpipe.length());
std::copy(wpipe.begin(), wpipe.end(), pipename.begin());
#else
pipename = argv[2];
#endif
printf("Using Named Pipe %s\n", pipename.c_str());
//Thrift over Named Pipe.
thriftcommon::RunThriftServer<SampleServiceHandler, SampleServiceProcessor>(10, pipename);
}
else if(_tcscmp(argv[1], TEXT("-ap")) == 0)
{ //Anonymous Pipe specified
//This is more involved because the child needs to be launched
//after the transport is created but before the blocking server
//call.
#ifdef _WIN32
boost::shared_ptr<TServerTransport> transport(new TPipeServer()); //Anonymous pipe
thriftcommon::LaunchAnonPipeChild(".\\client.exe", transport);
boost::shared_ptr<SampleServiceHandler> handler(new SampleServiceHandler());
thriftcommon::RunThriftServer<SampleServiceHandler, SampleServiceProcessor>(handler, 10, transport);
#else
printf("Anonymous pipes not (yet) supported under *NIX\n");
#endif
}
else
usage = true;
}
else
usage = true;
if(usage)
{
printf("Thrift sample server usage:\n\n");
printf("Socket Port : -sp <port#>\n");
printf("Named Pipe : -np <pipename> (e.g. affpipe)\n");
printf("Anonymous Pipe: -ap\n");
}
return 0;
}
//Thread Routine that connects to the 'client'.
void S2CThreadProc()
{
//Master server's connection to client-side's server.
boost::shared_ptr<SampleCallbackClient> clientsrv; //Client class from Thrift-generated code.
boost::shared_ptr<TTransport> transport;
if(ClientPort_ != 0)
thriftcommon::ConnectToServer<SampleCallbackClient, TTransport>(clientsrv, transport, ClientPort_);
if(!ClientPipeName_.empty())
thriftcommon::ConnectToServer<SampleCallbackClient, TTransport>(clientsrv, transport, ClientPipeName_);
try {
transport->open();
clientsrv->pingclient();
Sleep(1500);
clientsrv->pingclient();
Sleep(1500);
clientsrv->pingclient();
transport->close();
} catch (TException &tx) {
printf("ERROR: %s\n", tx.what());
}
}