Exemples C++ -- MessageHandler

Les fragments ci-dessous font partie du composant ASRI. Ils sont extraits de asri/IEventHandler.h, asri/MessageHandler.h.

Ils utilisent les concepts et outils :

  • référence constante
  • méthode virtuelle pure
  • namespace
  • Interface : classe abstraite ne comportant que des méthodes virtuelles pures
  • std::auto_ptr<T> : pointeur permettant de libérer automatiquement une ressource

La documentation est extraite des sources par Doxygen, qui repère les commentaires //!, //@


La classe IEventHandler est une Interface,

namespace asri {
    //------------------------------------------------
  //! Interface of all Event Handlers.
  //! @nosubgrouping
    class IEventHandler
    {
  friend class Reactor ;
  public:
    //! Stop and Unregister the Handler.
    //! can be called by anybody : another Thread, the Reactor, another Handler
    //!     the current Handler himself
    virtual void unregister() = 0 ;
    //! Return Logger reference.
    virtual Logger& getLogger() const = 0 ;
    //! Set the current Logger of the Handler.
    virtual void setLogger(std::string const& loggerName)  = 0 ;
  protected:
    //! @name Specific Handler Interface.
    //! Will be called by the Reactor.
    //@{
    //! Create a Win32 Event and pass it's Handle  to _handleHolder.
    virtual void startW32Event() = 0 ;
    //! Handle the Win32 Event and Reset it if it is a manual-reset Event.
    virtual void handleW32Event() = 0 ;
    //! Stop the Win32 Event and release it
    virtual void stopW32Event() = 0 ;
    //@}
    //! @name Reactor pattern internal interface.
    //@{
    //! Return Win32 synchronizable Event Handle.
    virtual Handle getHandle() const = 0 ;
    //! The Reactor will stop when all registered Handlers are stoppable.
    virtual bool isStoppable() const = 0 ;
    //! Set the cross-link to the Reactor.
    virtual void setReactor(IReactor* reactor) = 0 ;
    //@}
    } ;

    //------------------------------------------------
} // namespace asri

La classe SocketManager dérivée de EventHandler se charge de gérer la ressource socket Win32:

namespace asri {
  class TcpSocket ;
  class TcpAddrInfo ;
  class Packeteer ;
  //! Manage a TCP socket.
  class ASRI_API SocketManager : public EventHandler
  {
  public:
    enum State
        {   StClosed        = 0,  //!< SOCKET does not exist
          // All Handlers
          StOpened, StConnected, StClosing,
          //! listening, Acceptor specific
            StListening,
          //! resolving HostName, Connector specific
            StResolvingHost,
          //! requesting a connection, Connector specific
          StConnecting,
        };
    SocketManager(std::string const& loggerName) ;
    //! Return enum that says what the socket is doing.
    State getState() const { return _state ; }
    //! TCP address information of socket.
    TcpAddrInfo const& adrInfo() const ;
  protected:
    //! Stop the Win32 event notifications, Close the socket.
    virtual void stopW32Event() ;
    //! Memorize what the socket is doing.
    void setState(State newState) ;
    std::auto_ptr<TcpSocket>    _tcpSock ;
    std::auto_ptr<TcpAddrInfo>  _tcpai ;
    State _state ;
  } ;

La classe MessageHandler dérivée de SocketManager va notamment :

  • déclarer et définir la méthode send permettant d'émettre des messages
  • déclarer les méthodes virtuelles pures que les classes dérivées devront implémenter.
  //! Manage a TCP Message stream connection.
  //!
  //! Common base of Server and Client message handlers
  class ASRI_API MessageHandler : public SocketManager
  {
  public:
    MessageHandler(std::string const& loggerName) ;
    //! event CallBack, called when a message has been received.
    virtual void onReceive(Message const& msg) = 0 ;
    //! event CallBack, called when connection has been closed by the peer, or the Network.
    virtual void onPeerClose() = 0 ;
    //! Return true if messages can be sent and received.
    bool isConnected() const { return (_state == StConnected) ; }
    //! Send message.
    void send(Message const& msg) ;
    //! Make a message and send it.
    void send(int id, std::string const& data) { send(Message(id,data)) ; }
    //! Close the connection.
    void closeConnection() ;
  protected:
    virtual void handleW32Event() ;
    virtual void handleWsaNotification(long netEventSingleMsk, int wsaErr) ;
    void handleWSAReadNotification() ;
  private:
    //! Formatter that will encode/decode the packets.
    std::auto_ptr<Packeteer>  _packeteer ;
  } ;

} // namespace asri