RCFProto
 All Classes Functions Typedefs
AsioServerTransport.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_ASIOSERVERTRANSPORT_HPP
20 #define INCLUDE_RCF_ASIOSERVERTRANSPORT_HPP
21 
22 #include <set>
23 #include <vector>
24 
25 #include <boost/shared_ptr.hpp>
26 #include <boost/weak_ptr.hpp>
27 
28 #include <RCF/Asio.hpp>
29 #include <RCF/AsioBuffers.hpp>
30 #include <RCF/Enums.hpp>
31 #include <RCF/Export.hpp>
32 #include <RCF/IpAddress.hpp>
33 #include <RCF/IpServerTransport.hpp>
34 #include <RCF/ServerTransport.hpp>
35 #include <RCF/Service.hpp>
36 #include <RCF/ThreadLibrary.hpp>
37 
38 namespace RCF {
39 
40  class RcfServer;
41  class TcpClientTransport;
42  class AsioNetworkSession;
43  class AsioServerTransport;
44 
45  typedef boost::shared_ptr<AsioNetworkSession> AsioNetworkSessionPtr;
46  typedef boost::weak_ptr<AsioNetworkSession> AsioNetworkSessionWeakPtr;
47 
48  class AsioAcceptor
49  {
50  public:
51  virtual ~AsioAcceptor()
52  {}
53  };
54 
55  typedef boost::scoped_ptr<AsioAcceptor> AsioAcceptorPtr;
56 
57  class RCF_EXPORT AsioServerTransport :
58  public ServerTransport,
59  public ServerTransportEx,
60  public I_Service
61  {
62  private:
63 
64  // Needs to call open().
65  friend class TcpTransportFactory;
66  friend class HttpTransportFactory;
67  friend class HttpsTransportFactory;
68 
69  friend class Win32NamedPipeNetworkSession;
70 
71  typedef boost::weak_ptr<I_Session> SessionWeakPtr;
72 
73  AsioNetworkSessionPtr createNetworkSession();
74 
75  protected:
76 
77  // I_ServerTransportEx implementation
78  ClientTransportAutoPtr
79  createClientTransport(
80  const Endpoint &endpoint);
81 
82  SessionPtr createServerSession(
83  ClientTransportAutoPtr & clientTransportAutoPtr,
84  StubEntryPtr stubEntryPtr,
85  bool keepClientConnection);
86 
87  ClientTransportAutoPtr
88  createClientTransport(
89  SessionPtr sessionPtr);
90 
91  private:
92 
93  // I_Service implementation
94  void open();
95  void close();
96  void stop();
97 
98  void onServiceAdded( RcfServer & server);
99  void onServiceRemoved( RcfServer & server);
100 
101  protected:
102 
103  void onServerStart( RcfServer & server);
104  void onServerStop( RcfServer & server);
105  void setServer( RcfServer & server);
106 
107  void startAccepting();
108 
109  private:
110 
111  void startAcceptingThread(Exception & eRet);
112 
113  public:
114 
115  RcfServer & getServer();
116  RcfServer & getSessionManager();
117 
118  private:
119 
120  void registerSession(AsioNetworkSessionWeakPtr session);
121  void unregisterSession(AsioNetworkSessionWeakPtr session);
122  void cancelOutstandingIo();
123 
124  friend class AsioNetworkSession;
125  friend class FilterAdapter;
126  friend class ServerTcpFrame;
127  friend class ServerHttpFrame;
128 
129  protected:
130 
131  AsioServerTransport();
132  ~AsioServerTransport();
133 
134  AsioIoService * mpIoService;
135  AsioAcceptorPtr mAcceptorPtr;
136 
137  WireProtocol mWireProtocol;
138 
139  private:
140 
141  volatile bool mStopFlag;
142  RcfServer * mpServer;
143 
144  private:
145 
146  virtual AsioNetworkSessionPtr implCreateNetworkSession() = 0;
147  virtual void implOpen() = 0;
148 
149  virtual ClientTransportAutoPtr implCreateClientTransport(
150  const Endpoint &endpoint) = 0;
151 
152  public:
153 
154  AsioAcceptor & getAcceptor();
155 
156  AsioIoService & getIoService();
157  };
158 
159  class ReadHandler
160  {
161  public:
162  ReadHandler(AsioNetworkSessionPtr networkSessionPtr);
163  void operator()(AsioErrorCode err, std::size_t bytes);
164  void * allocate(std::size_t size);
165  AsioNetworkSessionPtr mNetworkSessionPtr;
166  };
167 
168  class WriteHandler
169  {
170  public:
171  WriteHandler(AsioNetworkSessionPtr networkSessionPtr);
172  void operator()(AsioErrorCode err, std::size_t bytes);
173  void * allocate(std::size_t size);
174  AsioNetworkSessionPtr mNetworkSessionPtr;
175  };
176 
177  void * asio_handler_allocate(std::size_t size, ReadHandler * pHandler);
178  void asio_handler_deallocate(void * pointer, std::size_t size, ReadHandler * pHandler);
179  void * asio_handler_allocate(std::size_t size, WriteHandler * pHandler);
180  void asio_handler_deallocate(void * pointer, std::size_t size, WriteHandler * pHandler);
181 
182  class RCF_EXPORT AsioNetworkSession :
183  public NetworkSession,
184  boost::noncopyable
185  {
186  public:
187 
188  friend class ReadHandler;
189  friend class WriteHandler;
190  friend class ServerTcpFrame;
191  friend class ServerHttpFrame;
192 
193 
194  typedef boost::weak_ptr<AsioNetworkSession> AsioNetworkSessionWeakPtr;
195  typedef boost::shared_ptr<AsioNetworkSession> AsioNetworkSessionPtr;
196 
197  AsioNetworkSession(
198  AsioServerTransport &transport,
199  AsioIoService & ioService);
200 
201  virtual ~AsioNetworkSession();
202 
203  AsioNetworkSessionPtr sharedFromThis();
204 
205  void close();
206 
207  AsioErrorCode getLastError();
208 
209  void setCloseAfterWrite();
210 
211  protected:
212  AsioIoService & mIoService;
213 
214  std::vector<char> mReadHandlerBuffer;
215  std::vector<char> mWriteHandlerBuffer;
216 
217  AsioErrorCode mLastError;
218 
219  private:
220 
221  // read()/write() are used to connect with the filter sequence.
222  void read(
223  const ByteBuffer &byteBuffer,
224  std::size_t bytesRequested);
225 
226  void write(
227  const std::vector<ByteBuffer> &byteBuffers);
228 
229  public:
230 
231  void setTransportFilters(
232  const std::vector<FilterPtr> &filters);
233 
234  void getTransportFilters(
235  std::vector<FilterPtr> &filters);
236 
237  void setWireFilters(
238  const std::vector<FilterPtr> &filters);
239 
240  void getWireFilters(
241  std::vector<FilterPtr> &filters);
242 
243  AsioServerTransport & getAsioServerTransport();
244 
245  private:
246 
247  void beginAccept();
248  void beginRead();
249  void beginWrite();
250 
251  void onAcceptCompleted(const AsioErrorCode & error);
252 
253  void onNetworkReadCompleted(
254  AsioErrorCode error,
255  size_t bytesTransferred);
256 
257  void onNetworkWriteCompleted(
258  AsioErrorCode error,
259  size_t bytesTransferred);
260 
261  friend class HttpSessionFilter;
262  void onAppReadWriteCompleted(
263  size_t bytesTransferred);
264 
265  void sendServerError(int error);
266 
267  void doCustomFraming(size_t bytesTransferred);
268  void doRegularFraming(size_t bytesTransferred);
269 
270  // TODO: too many friends
271  friend class AsioServerTransport;
272  friend class TcpNetworkSession;
273  friend class UnixLocalNetworkSession;
274  friend class Win32NamedPipeNetworkSession;
275  friend class FilterAdapter;
276 
277  enum State
278  {
279  Ready,
280  Accepting,
281  ReadingData,
282  ReadingDataCount,
283  WritingData
284  };
285 
286  State mState;
287  bool mIssueZeroByteRead;
288  std::size_t mReadBufferRemaining;
289  std::size_t mWriteBufferRemaining;
290 
291  std::vector<FilterPtr> mTransportFilters;
292 
293  friend class HttpServerTransport;
294  friend class PublishingService;
295  std::vector<FilterPtr> mWireFilters;
296 
297  AsioServerTransport & mTransport;
298 
299  std::vector<ByteBuffer> mWriteByteBuffers;
300  std::vector<ByteBuffer> mSlicedWriteByteBuffers;
301 
302  ReallocBufferPtr mAppReadBufferPtr;
303  ByteBuffer mAppReadByteBuffer;
304 
305  ReallocBufferPtr mNetworkReadBufferPtr;
306  ByteBuffer mNetworkReadByteBuffer;
307 
308  // So we can connect our read()/write() functions to the filter sequence.
309  FilterPtr mFilterAdapterPtr;
310 
311  bool mCloseAfterWrite;
312 
313  AsioNetworkSessionWeakPtr mWeakThisPtr;
314 
315  AsioBuffers mBufs;
316 
317  boost::shared_ptr<Mutex> mSocketOpsMutexPtr;
318 
319  // I_NetworkSession
320 
321  private:
322 
323  void postRead();
324  ByteBuffer getReadByteBuffer();
325  void postWrite(std::vector<ByteBuffer> &byteBuffers);
326  void postClose();
327  ServerTransport & getServerTransport();
328  const RemoteAddress & getRemoteAddress();
329  bool isConnected();
330 
331  private:
332 
333  virtual const RemoteAddress & implGetRemoteAddress() = 0;
334  virtual void implRead(char * buffer, std::size_t bufferLen) = 0;
335  virtual void implWrite(const std::vector<ByteBuffer> & buffers) = 0;
336  virtual void implAccept() = 0;
337  virtual bool implOnAccept() = 0;
338  virtual bool implIsConnected() = 0;
339  virtual void implClose() = 0;
340  virtual void implCloseAfterWrite() {}
341  virtual void implTransferNativeFrom(ClientTransport & clientTransport) = 0;
342  virtual ClientTransportAutoPtr implCreateClientTransport() = 0;
343  };
344 
345 } // namespace RCF
346 
347 
348 #endif // ! INCLUDE_RCF_ASIOSERVERTRANSPORT_HPP