| // 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()); |
| } |
| } |
| |