blob: 078ad4474bc9770d3cbf029afd8d10d250a8cb16 [file] [log] [blame]
Roger Meier122803b2012-06-18 20:23:58 +00001// ThriftCommon.h : Common includes, namespaces and templates
2// for sample Thrift client and server
3//
4// Add the following paths to the Project's properties:
5//
6// Configuration Properties -> C/C++ -> General-> Additional Include Directories --
7// ../;../../../lib/cpp/src;../../../../boost;../../../../boost/boost/tr1;
8//
9// Configuration Properties -> Linker -> General -> Additional Library Directories --
10// ../../../lib/cpp/$(Configuration);../../../../Boost/lib
11//
12// Configuration Properties -> Linker -> Input -> Additional Dependencies --
13// libthrift.lib
14//
15// ... adjust relative paths as necessary.
16//
17
18#ifdef _WIN32 //thrift is crashing when using boost threads on Mac OSX
Roger Meier122803b2012-06-18 20:23:58 +000019#else
20# include <sys/socket.h>
21# include <netinet/in.h>
22#endif
23
24//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25// Required Includes
26//'server' side #includes
27#include <thrift/concurrency/ThreadManager.h>
cyyca8af9b2019-01-11 22:13:12 +080028#include <thrift/concurrency/ThreadFactory.h>
Roger Meier122803b2012-06-18 20:23:58 +000029#include <thrift/server/TThreadPoolServer.h>
30#include <thrift/server/TSimpleServer.h>
31//'client' side #includes
32#include <thrift/transport/TPipeServer.h>
33#include <thrift/transport/TPipe.h>
34#include <thrift/transport/TBufferTransports.h>
35#include <thrift/transport/TSocket.h>
36#include <thrift/transport/TTransport.h>
37
38#include <thrift/protocol/TBinaryProtocol.h>
39
40
41//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42
43//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44// Required Namespaces
45//'server' side namespaces
46using namespace apache::thrift::server;
47using namespace apache::thrift::concurrency;
48//common namespaces
49using namespace apache::thrift;
50using namespace apache::thrift::protocol;
51using namespace apache::thrift::transport;
52//using namespace boost; //using ns boost can introduce type conflicts
53//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
54
55namespace thriftcommon
56{
57 //----------------------------------------------------------------------------
58 //
59 //Start the thrift 'server' (both server & client side run one for bidir event signaling)
60 // *** This function template will block ***
61 //
62 template <class MyHandler, class MyProcessor>
63 void RunThriftServer (boost::shared_ptr<MyHandler> hndlr,
64 int NumThreads,
65 boost::shared_ptr<TServerTransport> transport,
66 boost::shared_ptr<TServer> &server)
67 {
68#ifdef _WIN32
69 if (!hndlr.get())
70 throw std::exception("RunThriftServer() invalid handler");
71 if (!transport.get())
72 throw std::exception("RunThriftServer() invalid transport");
73#else
74 if ( !hndlr.get() || !transport.get() )
75 throw std::exception();
76#endif
77
78 boost::shared_ptr<MyHandler> handler(hndlr);
79 boost::shared_ptr<TProcessor> processor(new MyProcessor(handler));
80 boost::shared_ptr<TTransportFactory> tfactory(new TBufferedTransportFactory());
81 boost::shared_ptr<TProtocolFactory> pfactory(new TBinaryProtocolFactory());
82
83 if(NumThreads <= 1)
84 { //Single-threaded server
85 server.reset(new TSimpleServer(processor, transport, tfactory, pfactory));
86 }
87 else
88 { //Multi-threaded server
89 boost::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(NumThreads);
cyyca8af9b2019-01-11 22:13:12 +080090 boost::shared_ptr<ThreadFactory> threadFactory = boost::shared_ptr<ThreadFactory>(new ThreadFactory());
Roger Meier122803b2012-06-18 20:23:58 +000091 threadManager->threadFactory(threadFactory);
92 threadManager->start();
93 server.reset(new TThreadPoolServer(processor, transport, tfactory, pfactory, threadManager));
94 }
95
96 printf("Starting the 'server'...\n");
97 server->serve();
98 printf("done.\n");
99 }
100
101 // Thrift server wrapper function that accepts a pipe name.
102 // A handler must be passed in to this version.
103 template <class MyHandler, class MyProcessor>
104 void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, std::string pipename, boost::shared_ptr<TServer> &svr)
105 {
106#ifndef _WIN32 //Mac, *nix
107 unlink(pipename.c_str());
108#endif
109 boost::shared_ptr<TServerTransport> transport(new TPipeServer(pipename, 1024, NumThreads)); //Named pipe
110 RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, svr);
111 }
112
113 // Thrift server wrapper function that accepts a pipe name.
114 // This version instantiates its own handler.
115 template <class MyHandler, class MyProcessor>
116 void RunThriftServer (int NumThreads, std::string pipename)
117 {
118 boost::shared_ptr<MyHandler> handler(new MyHandler());
119 boost::shared_ptr<TServer> server;
120
121 RunThriftServer<MyHandler, MyProcessor>(handler, NumThreads, pipename, server);
122 }
123
124 // Thrift server wrapper function that accepts a socket port number.
125 // A handler must be passed in to this version.
126 template <class MyHandler, class MyProcessor>
127 void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, int Port)
128 {
129 boost::shared_ptr<TServerTransport> transport(new TServerSocket(Port));
130 boost::shared_ptr<TServer> server;
131 RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, server);
132 }
133
134 // Thrift server wrapper function that accepts a socket port number.
135 // This version instantiates its own handler.
136 template <class MyHandler, class MyProcessor>
137 void RunThriftServer (int NumThreads, int Port)
138 {
139 boost::shared_ptr<MyHandler> handler(new MyHandler());
140
141 RunThriftServer<MyHandler, MyProcessor>(handler, NumThreads, Port);
142 }
143
144 //
145 template <class MyHandler, class MyProcessor>
146 void RunThriftServer (boost::shared_ptr<MyHandler> hndlr, int NumThreads, boost::shared_ptr<TServerTransport> transport)
147 {
148 boost::shared_ptr<TServer> server;
149 RunThriftServer<MyHandler, MyProcessor>(hndlr, NumThreads, transport, server);
150 }
151
152 //----------------------------------------------------------------------------
153 //Connect to thrift 'server' - Socket version
154 //(both server & client side run one for bidir event signaling)
155 //
156 template <class MyClient, class MyTransport>
157 void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, int Port)
158 {
159 //Client side connection using sockets transport.
160 boost::shared_ptr<TTransport> socket(new TSocket("localhost", Port));
161 transport.reset(new TBufferedTransport(socket));
162 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
163
164 client.reset(new MyClient(protocol));
165 }
166
167 //Connect to thrift 'server' - Named Pipe version
168 template <class MyClient, class MyTransport>
169 void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, std::string pipename)
170 {
171 //Client side connection using Named Pipe transport.
172 boost::shared_ptr<TTransport> pipe(new TPipe(pipename));
173 transport.reset(new TBufferedTransport(pipe));
174 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
175
176 client.reset(new MyClient(protocol));
177 }
178
179 //Connect to thrift 'server' - Anonymous Pipe version
180 //Currently only supported under Windows
181#ifdef _WIN32
182 template <class MyClient, class MyTransport>
183 void ConnectToServer (boost::shared_ptr<MyClient> &client, boost::shared_ptr<MyTransport> &transport, HANDLE RdPipe, HANDLE WrtPipe)
184 {
185 //Client side connection using sockets transport.
186#ifdef _WIN32
187 boost::shared_ptr<TTransport> pipe(new TPipe((int)RdPipe, (int)WrtPipe));
188 transport.reset(new TBufferedTransport(pipe));
189#else
190 boost::shared_ptr<TTransport> socket(new TSocket("localhost"));
191 transport.reset(new TBufferedTransport(socket));
192#endif
193 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
194
195 client.reset(new MyClient(protocol));
196 }
197#endif
198
199 //----------------------------------------------------------------------------
200 //Launch child process and pass R/W anonymous pipe handles on cmd line.
201 //Currently only supported under Windows
202#ifdef _WIN32
203 bool LaunchAnonPipeChild(std::string app, boost::shared_ptr<TServerTransport> transport);
204#endif
205}