REC RPC library
rec_rpc_Server.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2011, REC Robotics Equipment Corporation GmbH, Planegg, Germany
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7 
8 - Redistributions of source code must retain the above copyright notice,
9  this list of conditions and the following disclaimer.
10 - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 - Neither the name of the REC Robotics Equipment Corporation GmbH nor the names of
14  its contributors may be used to endorse or promote products derived from this software
15  without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
18 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26 
27 #ifndef _REC_RPC_SERVER_H_
28 #define _REC_RPC_SERVER_H_
29 
30 #include "rec/rpc/defines.h"
31 #include "rec/rpc/rec_rpc_common.h"
33 
34 namespace rec
35 {
36  namespace rpc
37  {
39  namespace server
40  {
41  class Server;
42  }
53  {
55  virtual serialization::SerializablePtr createParam() const = 0;
56 
58  virtual serialization::SerializablePtr createResult() const = 0;
59 
67  virtual void invoke( const serialization::Serializable& param, serialization::Serializable& result, const rec::rpc::ClientInfo& client ) const = 0;
68  };
69 
78  {
88  virtual void invoke( const QUrl& url, const QString& host, QByteArray& resultPage, QString& contentType, const rec::rpc::ClientInfo& client ) = 0;
89  };
90 
99  {
107  virtual void invoke( const QByteArray& request, QByteArray& response, const rec::rpc::ClientInfo& client ) = 0;
108  };
109 
111  typedef QSharedPointer< RPCFunctionBase > RPCFunctionBasePtr;
112  typedef QSharedPointer< HTTPGetHandlerBase > HTTPGetHandlerBasePtr;
113  typedef QSharedPointer< CustomRequestHandlerBase > CustomRequestHandlerBasePtr;
114 
115  namespace detail
116  {
117  template< typename Parent_t, typename Param_t, typename Result_t >
118  struct RPCFunction : public rec::rpc::RPCFunctionBase
119  {
120  typedef void( Parent_t::*Invoke_f )( const Param_t&, Result_t&, const rec::rpc::ClientInfo& );
121 
122  RPCFunction( Parent_t* parent, Invoke_f function ) : _parent( parent ), _function( function ) { }
123  serialization::SerializablePtr createParam() const { return createSerializable< Param_t >(); }
124  serialization::SerializablePtr createResult() const { return createSerializable< Result_t >(); }
125 
126  void invoke( const serialization::Serializable& param, serialization::Serializable& result, const rec::rpc::ClientInfo& client ) const
127  {
128  if ( typeid( param ) != typeid( Param_t ) || typeid( result ) != typeid( Result_t ) )
130  ( _parent->*_function )( static_cast< const Param_t& >( param ), static_cast< Result_t& >( result ), client );
131  }
132 
133  Parent_t* _parent;
134  Invoke_f _function;
135  };
136 
137  template< typename Parent_t >
138  struct HTTPGetHandler : public rec::rpc::HTTPGetHandlerBase
139  {
140  typedef void( Parent_t::*Invoke_f )( const QUrl&, const QString&, QByteArray&, QString&, const rec::rpc::ClientInfo& );
141 
142  HTTPGetHandler( Parent_t* parent, Invoke_f function ) : _parent( parent ), _function( function ) { }
143 
144  void invoke( const QUrl& url, const QString& host, QByteArray& resultPage, QString& contentType, const rec::rpc::ClientInfo& client )
145  {
146  ( _parent->*_function )( url, host, resultPage, contentType, client );
147  }
148 
149  Parent_t* _parent;
150  Invoke_f _function;
151  };
152 
153  template< typename Parent_t >
154  struct CustomRequestHandler : public rec::rpc::CustomRequestHandlerBase
155  {
156  typedef void( Parent_t::*Invoke_f )( const QByteArray&, QByteArray& response, const rec::rpc::ClientInfo& );
157 
158  CustomRequestHandler( Parent_t* parent, Invoke_f function ) : _parent( parent ), _function( function ) { }
159 
160  void invoke( const QByteArray& request, QByteArray& response, const rec::rpc::ClientInfo& client )
161  {
162  ( _parent->*_function )( request, response, client );
163  }
164 
165  Parent_t* _parent;
166  Invoke_f _function;
167  };
168  }
176  class REC_RPC_EXPORT Server : public QObject
177  {
178  Q_OBJECT
179  public:
181  static const int DefaultClientMsgWaitTime = 5000;
182 
184  static const int DefaultHttpKeepAliveTimeout = 20;
185 
187  static const int DefaultHttpKeepAliveMaxRequests = 10;
188 
190  static const int DefaultCustomTimeout = 2;
191 
196 
202  Server( QObject* parent = 0 );
203 
205  virtual ~Server();
206 
211  bool isMultiThreadedSerializationEnabled() const;
212 
217  int port() const;
218 
223  bool isLocalIPCEnabled() const;
224 
229  int clientMsgWaitTime() const;
230 
235  int httpKeepAliveTimeout() const;
236 
241  int httpKeepAliveMaxRequests() const;
242 
247  int customTimeout() const;
248 
253  bool isListening() const;
254 
261  unsigned short serverPort() const;
262 
272  QString greeting() const;
273 
278  int numClientsConnected() const;
279 
280  public Q_SLOTS:
290  bool listen( bool blocking = false );
291 
300  void close( bool blocking = false );
301 
307  void exit();
308 
312  void disconnectAllClients();
313 
317  void disconnectClient( const QHostAddress& peerAddress, quint16 peerPort );
318 
324  void setMultiThreadedSerializationEnabled( bool enabled );
325 
331  void setPort( int port = rec::rpc::defaultPort );
332 
338  void setLocalIPCEnabled( bool enabled );
339 
345  void setClientMsgWaitTime( int clientMsgWaitTime = DefaultClientMsgWaitTime );
346 
352  void setHttpKeepAliveTimeout( int httpKeepAliveTimeout = DefaultHttpKeepAliveTimeout );
353 
359  void setHttpKeepAliveMaxRequests( int httpKeepAliveMaxRequests = DefaultHttpKeepAliveMaxRequests );
360 
366  void setCustomTimeout( int customTimeout = DefaultCustomTimeout );
367 
377  void setGreeting( const QString& greeting );
378 
379  Q_SIGNALS:
383  void listening();
384 
388  void closed();
389 
393  void finished();
394 
401  void serverError( QAbstractSocket::SocketError error, const QString& errorString );
402 
409  void clientError( QAbstractSocket::SocketError error, const QString& errorString );
410 
416  void clientConnected( const rec::rpc::ClientInfo& info );
417 
423  void clientDisconnected( const rec::rpc::ClientInfo& info );
424 
431  void registeredTopicListener( const QString& name, const rec::rpc::ClientInfo& info );
432 
439  void unregisteredTopicListener( const QString& name, const rec::rpc::ClientInfo& info );
440 
446  void numClientsConnectedChanged( int num );
447 
454  void log( const QString& message, int level = 1 );
455 
456  protected:
470  void registerFunction( const QString& name, RPCFunctionBasePtr function );
471 
482  void unregisterFunction( const QString& name );
483 
493  bool isFunctionRegistered( const QString& name ) const;
494 
508  void registerTopicListener( const QString& name, TopicListenerBasePtr listener );
509 
520  void unregisterTopicListener( const QString& name );
521 
531  bool isTopicListenerRegistered( const QString& name ) const;
532 
549  void addTopic( const QString& name, int sharedMemorySize = 0, bool serverOnly = false );
550 
567  void addEnqueuedTopic( const QString& name, bool serverOnly = false );
568 
569 
586  void addPermanentTopic( const QString& name, int sharedMemorySize = 0, bool serverOnly = false );
587 
588  void beginAddTopicGroup();
589  void endAddTopicGroup();
590 
604  void publishTopic( const QString& name, serialization::SerializablePtrConst data );
605 
616  void registerHttpGetHandler( HTTPGetHandlerBasePtr handler = HTTPGetHandlerBasePtr() );
617 
628  void registerCustomRequestHandler( CustomRequestHandlerBasePtr handler = CustomRequestHandlerBasePtr() );
629 
630  private:
631  server::Server* _server;
632  };
633  }
634 }
635 
644 #define DECLARE_FUNCTION( FUNCTIONNAME ) \
645  private: \
646  rec::rpc::RPCFunctionBasePtr create##FUNCTIONNAME##Wrapper(); \
647  void FUNCTIONNAME( const FUNCTIONNAME##Param& param, FUNCTIONNAME##Result& result, const rec::rpc::ClientInfo& client );
648 
660 #define BEGIN_FUNCTION_DEFINITION( CLASSNAME, FUNCTIONNAME ) \
661  rec::rpc::RPCFunctionBasePtr CLASSNAME::create##FUNCTIONNAME##Wrapper() \
662  { \
663  return rec::rpc::RPCFunctionBasePtr( new rec::rpc::detail::RPCFunction< CLASSNAME, FUNCTIONNAME##Param, FUNCTIONNAME##Result >( this, &CLASSNAME::FUNCTIONNAME ) ); \
664  } \
665  void CLASSNAME::FUNCTIONNAME( const FUNCTIONNAME##Param& param, FUNCTIONNAME##Result& result, const rec::rpc::ClientInfo& client ) \
666  {
667 
671 #define END_FUNCTION_DEFINITION }
672 
685 #define REGISTER_FUNCTION( FUNCTIONNAME ) registerFunction( #FUNCTIONNAME, create##FUNCTIONNAME##Wrapper() );
686 
696 #define UNREGISTER_FUNCTION( FUNCTIONNAME ) unregisterFunction( #FUNCTIONNAME );
697 
705 #define IS_FUNCTION_REGISTERED( FUNCTIONNAME ) isFunctionRegistered( #FUNCTIONNAME );
706 
719 #define ADD_TOPIC( TOPICNAME, SHAREDMEMSIZE ) addTopic( #TOPICNAME, SHAREDMEMSIZE );
720 
721 #define ADD_ENQUEUEDTOPIC( TOPICNAME ) addEnqueuedTopic( #TOPICNAME );
722 
735 #define ADD_SERVERONLY_TOPIC( TOPICNAME, SHAREDMEMSIZE ) addTopic( #TOPICNAME, SHAREDMEMSIZE, true );
736 
749 #define ADD_PERMANENT_TOPIC( TOPICNAME, SHAREDMEMSIZE ) addPermanentTopic( #TOPICNAME, SHAREDMEMSIZE );
750 
763 #define ADD_PERMANENT_SERVERONLY_TOPIC( TOPICNAME, SHAREDMEMSIZE ) addPermanentTopic( #TOPICNAME, SHAREDMEMSIZE, true );
764 
773 #define DECLARE_HTTP_GET_HANDLER( HANDLERNAME ) \
774  private: \
775  rec::rpc::HTTPGetHandlerBasePtr create##HANDLERNAME##HttpGetHandler(); \
776  void HANDLERNAME( const QUrl& url, const QString& host, QByteArray& resultPage, QString& contentType, const rec::rpc::ClientInfo& client );
777 
791 #define BEGIN_HTTP_GET_HANDLER_DEFINITION( CLASSNAME, HANDLERNAME ) \
792  rec::rpc::HTTPGetHandlerBasePtr CLASSNAME::create##HANDLERNAME##HttpGetHandler() \
793  { \
794  return rec::rpc::HTTPGetHandlerBasePtr( new rec::rpc::detail::HTTPGetHandler< CLASSNAME >( this, &CLASSNAME::HANDLERNAME ) ); \
795  } \
796  void CLASSNAME::HANDLERNAME( const QUrl& url, const QString& host, QByteArray& resultPage, QString& contentType, const rec::rpc::ClientInfo& client ) \
797  {
798 
802 #define END_HTTP_GET_HANDLER_DEFINITION }
803 
814 #define REGISTER_HTTP_GET_HANDLER( HANDLERNAME ) registerHttpGetHandler( create##HANDLERNAME##HttpGetHandler() );
815 
823 #define REMOVE_HTTP_GET_HANDLER registerHttpGetHandler( rec::rpc::HTTPGetHandlerBasePtr() );
824 
833 #define DECLARE_CUSTOM_REQUEST_HANDLER( HANDLERNAME ) \
834  private: \
835  rec::rpc::CustomRequestHandlerBasePtr create##HANDLERNAME##CustomRequestHandler(); \
836  void HANDLERNAME( const QByteArray& request, QByteArray& response, const rec::rpc::ClientInfo& client );
837 
848 #define BEGIN_CUSTOM_REQUEST_HANDLER_DEFINITION( CLASSNAME, HANDLERNAME ) \
849  rec::rpc::CustomRequestHandlerBasePtr CLASSNAME::create##HANDLERNAME##CustomRequestHandler() \
850  { \
851  return rec::rpc::CustomRequestHandlerBasePtr( new rec::rpc::detail::CustomRequestHandler< CLASSNAME >( this, &CLASSNAME::HANDLERNAME ) ); \
852  } \
853  void CLASSNAME::HANDLERNAME( const QByteArray& request, QByteArray& response, const rec::rpc::ClientInfo& client ) \
854  {
855 
859 #define END_CUSTOM_REQUEST_HANDLER_DEFINITION }
860 
871 #define REGISTER_CUSTOM_REQUEST_HANDLER( HANDLERNAME ) registerCustomRequestHandler( create##HANDLERNAME##CustomRequestHandler() );
872 
880 #define REMOVE_CUSTOM_REQUEST_HANDLER registerCustomRequestHandler( rec::rpc::CustomRequestHandlerBasePtr() );
881 
882 #endif //_REC_RPC_RPC_SERVER_H_
RPC client info.
Exception class.
const int defaultPort
The TCP port which will be used by default if no other one is specified.
RPC server base class.
RPC function wrapper interface.
static int sendFailSocketTimeout
Close socket if sending fails for sendFailSocketTimeout() milli seconds.
#define REC_RPC_EXPORT
Definition: defines.h:49
Custom request handler interface.
HTTP GET handler interface.