blob: 45fbef1d8080493f59f4f2e21dff2d9659424210 [file] [log] [blame]
Roger Meier122803b2012-06-18 20:23:58 +00001// client->cpp : Defines the entry point for the console application.
2//
3// sample client command line app using Thrift IPC.
4// Quick n Dirty example, may not have very robust error handling
5// for the sake of simplicity.
6
7#ifdef _WIN32
8# include "stdafx.h"
9#else
10# include "config.h"
11#endif
12
13
14//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
15//Include this before the generated includes
16#include "ThriftCommon.h"
17//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18//Tailor these to your generated files
19#include "../gen-cpp/SampleService.h"
20#include "../gen-cpp/SampleCallback.h"
21
22using namespace Sample; //declared in .thrift file
23//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
25void ClientListenerThreadProc();
26bool bSocket = false;
27bool bAnonPipe = false;
28int srvPort;
29std::string pipename;
30std::string pipename_client;
31#ifdef _WIN32
32 HANDLE hConsole;
33#endif
34
35//Customized version of printf that changes the text color
36//This depends on hConsole global being initialized
37void hlprintf(const char* _Format, ...)
38{
39#ifdef _WIN32
40 SetConsoleTextAttribute(hConsole, 0xE);
41#endif
42 va_list ap;
43 int r;
44 va_start (ap, _Format);
45 r = vprintf (_Format, ap);
46 va_end (ap);
47#ifdef _WIN32
48 SetConsoleTextAttribute(hConsole, 7);
49#endif
50}
51
52//-----------------------------------------------------------------------------
53// Client-side RPC implementations: Called by the server to the client for
54// bidirectional eventing.
55//
56class SampleCallbackHandler : virtual public SampleCallbackIf {
57 public:
58 SampleCallbackHandler() {
59 // initialization goes here
60 }
61
62 void pingclient()
63 {
64 hlprintf("<<<Ping received from server (server-to-client event).\n");
65 }
66
67};
68//-----------------------------------------------------------------------------
69
70
71#ifdef _WIN32
72int _tmain(int argc, _TCHAR* argv[])
73#else
74int main(int argc, char **argv)
75#endif
76{
77 //Process cmd line args to determine named vs anon pipes.
78 bool usage = false;
79#ifdef _WIN32
80 HANDLE ReadPipe, WritePipe;
81 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
82#endif
83
84 //Process command line params
85 if(argc > 1)
86 {
87 if(_tcscmp(argv[1], TEXT("-sp")) == 0)
88 { //Socket Port specified
89 srvPort = _tstoi(argv[2]);
90 bSocket = true;
91 }
92 else if(_tcscmp(argv[1], TEXT("-np")) == 0)
93 { //Named Pipe specified
94#ifdef _WIN32
95 std::wstring wpipe(argv[2]);
96 pipename.resize(wpipe.length());
97 std::copy(wpipe.begin(), wpipe.end(), pipename.begin());
98#else
99 pipename = argv[2];
100#endif
101 pipename_client = pipename + "_client";
102 }
103 else if(argc == 3)
104 { //Anonymous Pipe specified
105#ifdef _WIN32
106 ReadPipe = (HANDLE)_tstoi(argv[1]);
107 WritePipe = (HANDLE)_tstoi(argv[2]);
108 bAnonPipe = true;
109#else
110 printf("Anonymous pipes not (yet) supported under *NIX\n");
111#endif
112 }
113 else
114 usage = true;
115 }
116 else
117 usage = true;
118
119 if(usage)
120 {
121 hlprintf("Thrift sample client usage:\n\n");
122 hlprintf("Socket Port to connect to: -sp <port#>\n");
123 hlprintf("Named Pipe to connect to: -np <pipename> (e.g. affpipe)\n");
124 hlprintf("Anonymous Pipe (must be launched by anon pipe creator):\n");
125 hlprintf(" <Read Handle> <Write Handle>\n");
126 return 0;
127 }
128
129 //Client side connection to server.
130 boost::shared_ptr<SampleServiceClient> client; //Client class from Thrift-generated code.
131 boost::shared_ptr<TTransport> transport;
132
133 if(bSocket)
134 { //Socket transport
135#ifdef _WIN32
136 TWinsockSingleton::create();
137#endif
138 hlprintf("Using socket transport port %d\n", srvPort);
139 thriftcommon::ConnectToServer<SampleServiceClient, TTransport>(client, transport, srvPort);
140 }
141 else if(!bAnonPipe)
142 {
143 hlprintf("Using Named Pipe %s\n", pipename.c_str());
144 thriftcommon::ConnectToServer<SampleServiceClient, TTransport>(client, transport, pipename);
145 }
146 else
147 {
148#ifdef _WIN32
149 hlprintf("Using Anonymous Pipe transport\n");
150 thriftcommon::ConnectToServer<SampleServiceClient, TTransport>(client, transport, ReadPipe, WritePipe);
151#endif
152 }
153
154#ifdef _WIN32
155 //Start a thread to receive inbound connection from server for 2-way event signaling.
156 boost::thread ClientListenerThread(ClientListenerThreadProc);
157#endif
158
159 try {
160 transport->open();
161
162 //Notify server what to connect back on.
163 if(bSocket)
164 client->ClientSideListenPort(srvPort + 1); //Socket
165 else if(!bAnonPipe)
166 client->ClientSidePipeName(pipename_client); //Named Pipe
167
168 //Run some more RPCs
169 std::string hellostr = "Hello how are you?";
170 std::string returnstr;
171 client->HelloThere(returnstr, hellostr);
172 hlprintf("\n>>>Sent: %s\n", hellostr.c_str());
173 hlprintf("<<<Received: %s\n", returnstr.c_str());
174
175 hlprintf("\n>>>Calling ServerDoSomething() which delays for 5 seconds.\n");
176 client->ServerDoSomething();
177 hlprintf(">>>ServerDoSomething() done.\n\n");
178
179 transport->close();
180 } catch (TException &tx) {
181 hlprintf("ERROR: %s\n", tx.what());
182 }
183
184 return 0;
185}
186
187
188//Thread Routine
189void ClientListenerThreadProc()
190{
191 if(bSocket)
192 thriftcommon::RunThriftServer<SampleCallbackHandler, SampleCallbackProcessor>(1, srvPort + 1);
193 else if(!bAnonPipe)
194 thriftcommon::RunThriftServer<SampleCallbackHandler, SampleCallbackProcessor>(1, pipename_client);
195}