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