HTTPメッセージハンドラ

HttpMessageHandler

HttpMessageHandler は、HTTP サーバー上で nineメッセージ通信を行うためのフレームワーククラスである。

HttpMessageHandler の使い方は、TCPメッセージサーバーに準拠しているが、HTTP上でメッセージングを実現するためにいくつかの制約を設けている:
  • cookie または querystring にセッションIDを含めることで、HTTPセッションを導入している。
  • 一つの HTTP リクエストに、一つだけのメッセージを含めることができる。
  • リクエストメッセージは、querystring または HTTP POST の本文に JSON 直列化したものを記述する。
  • HTTP 応答は一つ以上のメッセージを含めることができる。
  • HTTP応答のメッセージは応答の本文に記述する。メッセージは JSON 配列に直列化する。
  • HTTP要求を処理している時だけ、post() でのメッセージ送信を行うことができる。
  • セッションが維持されている間はいつでも queue() で送信メッセージをキューイングすることができる。
  • flow() を呼んだ時の HTTP応答で、キューイングされたメッセージを送信する。

HttpMessageHandler の定義

HttpMessageHandler 定義から、一般的に使う部分を抜き出すと次のようになっている:
class HttpMessageHandler: public HttpHandler
{
   public:
      bool initialize(const HttpMessageHandlerConfig* pCfg);

      virtual void turn(); //!< HTTPセッションの時間切れ判定を行う

      virtual bool handleMessage(Message* pMsg);
      bool post(int sid, const Message*, const SendContext* = NULL);
      bool queue(int sid, Message*, const SendContext* = NULL);
      bool flow(int sid);

      void closeLater(int sid);
      virtual void onSessionOpen(int sid);
      virtual void onSessionClose(int sid);
};

HttpMessageHandler は HttpHandler を継承している。利用するには、HttpHandler と同様に HttpServer の authorizeHttp() 関数の戻り値で渡せばよい。

HttpHandler は、onHttpRequest() などの生の HTTP を扱うためのハンドラ関数を実装する必要があった。HttpMessageHandler ではこれらのハンドラ関数の実装をしているので、アプリケーション側でさらにオーバーライドする必要はない。

サーバーの振る舞い

HttpMessageHandler の動作は、HTTP 接続にセッションを持たせただけである。 このセッションは、仮想的な接続として振る舞う。

クライアントは HTTP リクエストの QueryString または Cookie にセッションIDを持たせる。 サーバー側はリクエストハンドラの中で既存のセッションと対応付ける。

セッションにはタイムアウトを設ける。セッションに所属する HTTPリクエストが一定時間来なかったら、セッションは切断されたものとみなす。

セッションID

HttpMessageHandler は、仮想的な接続である HTTP セッションを導入している。HttpMessageHandler で、通信路を指定する場合は、ユニークなセッションIDを使う。

このセッションID は、実接続のコミュニケータID とは独立した識別子である。 異なる communicatorId が同一のセッションIDを示す場合もあるし、その逆もありうる。

初期化

HttpMessageHandler は initialzie 関数を実装している。オブジェクトの生成後にこの関数を呼んで、適切に設定を行う必要がある。

パラメータに与える HttpMessageHandlerConfig 構造体は次のように定義されている:
struct HttpMessageHandlerConfig
{
      int nSessions; //!< セッションの数
      int sessionTimeoutSec; //!< 次のHTTPリクエストが来るまでセッションを維持する時間[秒]

      // sessionCookie か sessionQueryString のどちらかの指定は必須
      std::string sessionCookie; //!< セッション情報を保持する cookie 名を指定。
      std::string sessionCookiePath; //!< セッション用 cookie のパス
      std::string sessionCookieDomain; //!< セッション用 cookie のドメイン
      std::string sessionQueryString; //!< セッション情報を保持する querystring の key を指定。

      std::string jsonp; //!< 応答を JSONP 形式で行う。JSONP関数名を保持する key を指定。

      // enableQueryStringMarshal か enablePostMarshal のどちらかの指定は必須
      bool enableQueryStringMarshal; //!< QueryString へのメッセージ直列化を処理する
      bool enablePostMarshal; //!< POST Body へのメッセージ直列化を処理する
nSessions
HTTPセッションの最大数を指定する。
HTTPセッションは、HTTP接続が切れていてもタイムアウトまでは存続することを考慮して、適切な値を指定する。
sessionTimeoutSec
HTTP セッションのタイムアウト時間。
タイムアウトは、HTTP応答を返してから、次の HTTP 要求が来るまでの間で計測される。
sessionCookie
HTTPセッションの識別子を cookie に載せることとし、その cookie の名前を指定する。
sessionCookie か sessionQueryString のどちらかの指定は必須である。
sessionCookiePath, sessionCookieDomain
HTTPセッション用 cookie のパスとドメインを指定する。
sessionQueryString
HTTPセッションの識別子を QueryString に載せることとし、その key の名前を指定する。
sessionCookie か sessionQueryString のどちらかの指定は必須である。
jsonp
メッセージの応答を JSONP 形式にする。その JSONP の関数名を指定する。
enableQueryStringMarshal
リクエストメッセージの直列化を QueryString で行う。
enableQueryStringMarshal か enablePostMarshal のどちらかの指定は必須である。
enablePostMarshal
リクエストメッセージの直列化を HTTP POST の本文で行う。
enableQueryStringMarshal か enablePostMarshal のどちらかの指定は必須である。

turn

HttpHandler と違い、HttpMessageHandler では定期的に turn() を呼ぶ必要がある。

turn() では、HTTPセッションの時間切れ判定を行っている。

セッション接続関数

セッションの新規確立時には onSessionOpen() が、セッションの終了 OnSessionClose() が呼ばれる。

セッションはタイムアウトで切断されるが、明示的に閉じたい場合には closeLater() を呼ぶ。

メッセージ関数

handleMessage(), post(), queue(), flow() といった一連のメッセージ関数を定義している。

これらの使い方は基本的に MessageServer と同じであるが、前に述べたように HTTP の性質に起因する制約がある。

handleMessage() で受け取ったメッセージオブジェクトの Message::getCommunicatorId() を呼び出して得られる値は、コミュニケータIDではなくセッションIDになっている。