RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
TransportFactories.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 #ifndef INCLUDE_RCF_TEST_TRANSPORTFACTORIES_HPP
20 #define INCLUDE_RCF_TEST_TRANSPORTFACTORIES_HPP
21
22 #include <iostream>
23 #include <typeinfo>
24 #include <utility>
25 #include <vector>
26
27 #include <sys/stat.h>
28
29 #include <boost/config.hpp>
30 #include <boost/shared_ptr.hpp>
31 #include <boost/version.hpp>
32
33 #include <RCF/ClientStub.hpp>
34 #include <RCF/InitDeinit.hpp>
35 #include <RCF/ThreadLibrary.hpp>
36
37 #include <RCF/TcpAsioServerTransport.hpp>
38 #include <RCF/Asio.hpp>
39 #include <RCF/Config.hpp>
40
41 #ifdef RCF_HAS_LOCAL_SOCKETS
42 #include <RCF/UnixLocalClientTransport.hpp>
43 #include <RCF/UnixLocalServerTransport.hpp>
44 #endif
45
46 #if RCF_FEATURE_NAMEDPIPE==1
47 #include <RCF/Win32NamedPipeClientTransport.hpp>
48 #include <RCF/Win32NamedPipeEndpoint.hpp>
49 #include <RCF/Win32NamedPipeServerTransport.hpp>
50 #endif
51
52 #include <RCF/TcpClientTransport.hpp>
53 #include <RCF/UdpClientTransport.hpp>
54 #include <RCF/UdpServerTransport.hpp>
55
56 #include <RCF/ObjectFactoryService.hpp>
57
58 template<typename Interface>
59 inline bool tryCreateRemoteObject(
60 RCF::I_RcfClient &rcfClient,
61 std::string objectName = "")
62 {
63 try
64 {
65 rcfClient.getClientStub().createRemoteObject(objectName);
66 return true;
67 }
68 catch (const RCF::Exception &e)
69 {
70 RCF_LOG_1()(e);
71 return false;
72 }
73 }
74
75
76 namespace RCF {
77
78 typedef boost::shared_ptr<ClientTransportAutoPtr> ClientTransportAutoPtrPtr;
79
80 typedef std::pair<ServerTransportPtr, ClientTransportAutoPtrPtr> TransportPair;
81
82 class I_TransportFactory
83 {
84 public:
85 virtual ~I_TransportFactory() {}
86 virtual TransportPair createTransports() = 0;
87 virtual TransportPair createNonListeningTransports() = 0;
88 virtual bool isConnectionOriented() = 0;
89 virtual bool supportsTransportFilters() = 0;
90 virtual std::string desc() = 0;
91 };
92
93 typedef boost::shared_ptr<I_TransportFactory> TransportFactoryPtr;
94
95 typedef std::vector<TransportFactoryPtr> TransportFactories;
96
97 static TransportFactories &getTransportFactories()
98 {
99 static TransportFactories transportFactories;
100 return transportFactories;
101 }
102
103 static TransportFactories &getIpTransportFactories()
104 {
105 static TransportFactories ipTransportFactories;
106 return ipTransportFactories;
107 }
108
109 //**************************************************
110 // transport factories
111
112 static std::string loopBackV4 = "127.0.0.1";
113 static std::string loopBackV6 = "::1";
114
115 #if RCF_FEATURE_NAMEDPIPE==1
116
117 class Win32NamedPipeTransportFactory : public I_TransportFactory
118 {
119 public:
120 TransportPair createTransports()
121 {
122 typedef boost::shared_ptr<Win32NamedPipeServerTransport> Win32NamedPipeServerTransportPtr;
123 Win32NamedPipeServerTransportPtr serverTransportPtr(
124 new Win32NamedPipeServerTransport(RCF_T("")));
125
126 tstring pipeName = serverTransportPtr->getPipeName();
127
128 ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
129 new ClientTransportAutoPtr(
130 new Win32NamedPipeClientTransport(pipeName)));
131
132 return std::make_pair(
133 ServerTransportPtr(serverTransportPtr),
134 clientTransportAutoPtrPtr);
135
136 }
137
138 TransportPair createNonListeningTransports()
139 {
140 return std::make_pair(
141 ServerTransportPtr( new Win32NamedPipeServerTransport( RCF_T("")) ),
142 ClientTransportAutoPtrPtr());
143
144 }
145
146 bool isConnectionOriented()
147 {
148 return true;
149 }
150
151 bool supportsTransportFilters()
152 {
153 return true;
154 }
155
156 std::string desc()
157 {
158 return "Win32NamedPipeTransportFactory";
159 }
160 };
161
162 #endif
163
164 #if RCF_FEATURE_TCP==1
165
166 class TcpAsioTransportFactory : public I_TransportFactory
167 {
168 public:
169
170 TcpAsioTransportFactory(IpAddress::Type type = IpAddress::V4)
171 {
172 switch (type)
173 {
174 case IpAddress::V4: mLoopback = loopBackV4; break;
175 case IpAddress::V6: mLoopback = loopBackV6; break;
176 default: RCF_ASSERT(0);
177 }
178 }
179
180 TransportPair createTransports()
181 {
182 typedef boost::shared_ptr<TcpAsioServerTransport> TcpAsioServerTransportPtr;
183 TcpAsioServerTransportPtr tcpServerTransportPtr(
184 new TcpAsioServerTransport( IpAddress(mLoopback, 0)));
185
186 tcpServerTransportPtr->open();
187 int port = tcpServerTransportPtr->getPort();
188
189 ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
190 new ClientTransportAutoPtr(
191 new TcpClientTransport( IpAddress(mLoopback, port))));
192
193 return std::make_pair(
194 ServerTransportPtr(tcpServerTransportPtr),
195 clientTransportAutoPtrPtr);
196 }
197
198 TransportPair createNonListeningTransports()
199 {
200 return std::make_pair(
201 ServerTransportPtr( new TcpAsioServerTransport( IpAddress(mLoopback, 0)) ),
202 ClientTransportAutoPtrPtr());
203 }
204
205 bool isConnectionOriented()
206 {
207 return true;
208 }
209
210 bool supportsTransportFilters()
211 {
212 return true;
213 }
214
215 std::string desc()
216 {
217 return "TcpAsioTransportFactory (" + mLoopback + ")";
218 }
219
220 private:
221
222 std::string mLoopback;
223
224 };
225
226 #endif
227
228 #if RCF_FEATURE_LOCALSOCKET==1
229
230 class UnixLocalTransportFactory : public I_TransportFactory
231 {
232 public:
233
234 UnixLocalTransportFactory() : mIndex(0)
235 {
236 }
237
238 private:
239
240 TransportPair createTransports()
241 {
242 std::string pipeName = generateNewPipeName();
243
244 RCF_LOG_2()(pipeName) << "Creating unix local socket transport pair";
245
246 return std::make_pair(
247 ServerTransportPtr( new UnixLocalServerTransport(pipeName) ),
248 ClientTransportAutoPtrPtr(
249 new ClientTransportAutoPtr(
250 new UnixLocalClientTransport(pipeName))));
251 }
252
253 TransportPair createNonListeningTransports()
254 {
255 return std::make_pair(
256 ServerTransportPtr( new UnixLocalServerTransport("") ),
257 ClientTransportAutoPtrPtr());
258 }
259
260 bool isConnectionOriented()
261 {
262 return true;
263 }
264
265 bool supportsTransportFilters()
266 {
267 return true;
268 }
269
270 private:
271
272 bool fileExists(const std::string & path)
273 {
274 struct stat stFileInfo = {};
275 int ret = stat(path.c_str(), &stFileInfo);
276 return ret == 0;
277 }
278
279 std::string generateNewPipeName()
280 {
281 std::string tempDir = RCF::getRelativeTestDataPath();
282
283 std::string candidate;
284
285 while (candidate.empty() || fileExists(candidate))
286 {
287 std::ostringstream os;
288 os
289 << tempDir
290 << "TestPipe_"
291 << ++mIndex;
292
293 candidate = os.str();
294 }
295
296 return candidate;
297 }
298
299 std::string desc()
300 {
301 return "UnixLocalTransportFactory";
302 }
303
304 int mIndex;
305
306 };
307
308 #endif // RCF_HAS_LOCAL_SOCKETS
309
310 #if RCF_FEATURE_UDP==1
311
312 class UdpTransportFactory : public I_TransportFactory
313 {
314 public:
315
316 UdpTransportFactory(IpAddress::Type type = IpAddress::V4)
317 {
318 switch (type)
319 {
320 case IpAddress::V4: mLoopback = loopBackV4; break;
321 case IpAddress::V6: mLoopback = loopBackV6; break;
322 default: RCF_ASSERT(0);
323 }
324 }
325
326 TransportPair createTransports()
327 {
328 typedef boost::shared_ptr<UdpServerTransport> UdpServerTransportPtr;
329 UdpServerTransportPtr udpServerTransportPtr(
330 new UdpServerTransport( IpAddress(mLoopback, 0) ));
331
332 udpServerTransportPtr->open();
333 int port = udpServerTransportPtr->getPort();
334
335 ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
336 new ClientTransportAutoPtr(
337 new UdpClientTransport( IpAddress(mLoopback, port) )));
338
339 return std::make_pair(
340 ServerTransportPtr(udpServerTransportPtr),
341 clientTransportAutoPtrPtr);
342 }
343
344 TransportPair createNonListeningTransports()
345 {
346 return std::make_pair(
347 ServerTransportPtr( new UdpServerTransport( IpAddress(mLoopback, 0) ) ),
348 ClientTransportAutoPtrPtr());
349 }
350
351 bool isConnectionOriented()
352 {
353 return false;
354 }
355
356 bool supportsTransportFilters()
357 {
358 return false;
359 }
360
361 std::string desc()
362 {
363 return "UdpTransportFactory (" + mLoopback + ")";
364 }
365
366 private:
367
368 std::string mLoopback;
369 };
370
371 #endif
372
373 typedef TcpAsioTransportFactory TcpTransportFactory;
374
375 void initializeTransportFactories()
376 {
377
378 #if RCF_FEATURE_IPV6==1
379 const bool compileTimeIpv6 = true;
380 ExceptionPtr ePtr;
381 IpAddress("::1").resolve(ePtr);
382 const bool runTimeIpv6 = (ePtr.get() == NULL);
383 #else
384 const bool compileTimeIpv6 = false;
385 const bool runTimeIpv6 = false;
386 #endif
387
388 #if RCF_FEATURE_NAMEDPIPE==1
389
390 getTransportFactories().push_back(
391 TransportFactoryPtr( new Win32NamedPipeTransportFactory()));
392
393 #endif
394
395 #if RCF_FEATURE_TCP==1
396
397 getTransportFactories().push_back(
398 TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));
399
400 getIpTransportFactories().push_back(
401 TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));
402
403 if (compileTimeIpv6 && runTimeIpv6)
404 {
405 getTransportFactories().push_back(
406 TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
407
408 getIpTransportFactories().push_back(
409 TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
410 }
411
412 #endif
413
414 #if RCF_FEATURE_LOCALSOCKET==1
415
416 getTransportFactories().push_back(
417 TransportFactoryPtr( new UnixLocalTransportFactory()));
418
419 #endif
420
421 #if RCF_FEATURE_UDP==1
422
423 getTransportFactories().push_back(
424 TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));
425
426 getIpTransportFactories().push_back(
427 TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));
428
429 if (compileTimeIpv6 && runTimeIpv6)
430 {
431 getTransportFactories().push_back(
432 TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
433
434 getIpTransportFactories().push_back(
435 TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
436 }
437
438 #endif
439
440 }
441
442 } // namespace RCF
443
444 #endif // ! INCLUDE_RCF_TEST_TRANSPORTFACTORIES_HPP