CometMessageHandler は、Cometサーバーで nineメッセージ通信を行うためのフレームワーククラスである。
class CometMessageHandler: public HttpHandler
{
public:
bool initialize(const CometMessageHandlerConfig* 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 と同様の関数が提供されている。CometMessageHandler は HttpHandler を継承している。利用するには、HttpHandler と同様に HttpServer の authorizeHttp() 関数の戻り値で渡せばよい。
HttpHandler は、onHttpRequest() などの生の HTTP を扱うためのハンドラ関数を実装する必要があった。HttpMessageHandler ではこれらのハンドラ関数の実装をしているので、アプリケーション側でさらにオーバーライドする必要はない。
CometMessageHandler では、アップロード用とダウンロード用の二本の HTTPセッションを用いる。 二本のセッションをまとめて、一つの仮想的な接続として振る舞う。
クライアントは HttpMessageHandler に対すると同様に HTTP セッションを指定する。 ダウンロード用の接続は常時張っておき、アップロード用接続は送信するメッセージがある時に張る。
Comet 接続のタイムアウトは、ダウンロード用接続のタイムアウトを用いる。
HTTPリクエストパスが "/u" で終わる場合はアップロード用のチャネル、"/d" で終わる場合はダウンロード用チャネルとみなす。
どちらの接続でも、同一のセッションIDを用いる。
CometMessageHandler は initialzie 関数を実装している。オブジェクトの生成後にこの関数を呼んで、適切に設定を行う必要がある。
struct CometMessageHandlerConfig
{
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 へのメッセージ直列化を処理する
項目は HttpMessageHandlerConfig と同じである。HttpMessageHandler と同様に、CometMessageHandler では定期的に turn() を呼ぶ必要がある。
turn() では、セッションの時間切れ判定を行うほか、キューイングされたメッセージの送信も行う。
さらに、何らかのメッセージが送信されていた場合、ダウンロードポートを閉じる処理も行う。
セッションの新規確立時には onSessionOpen() が、セッションの終了 OnSessionClose() が呼ばれる。
セッションはタイムアウトで切断されるが、明示的に閉じたい場合には closeLater() を呼ぶ。
handleMessage() で受け取ったメッセージオブジェクトの Message::getCommunicatorId() を呼び出して得られる値は、コミュニケータIDではなくセッションIDになっている。
CometMessageHandler では、ダウンロード接続はすぐには切断しない。 具体的には、onHttpRequest() 関数で endResponse() を呼ばない。
切断は、post() または flow() によりメッセージを送信した後の turn() で行われる。
次のダウンロード接続が来るまでの間は、ダウンロード接続は存在しない。 この時に post() を行うと失敗となる。
CometMessageHandler では、アップロード接続はメッセージを受け取るだけである。
受け取ったメッセージは handleMessage() 関数に渡される。
HTTP応答で送るメッセージは無いのだが、HttpMessageHandler の流儀に従って JSON 配列を含める。 もちろん配列は空である。 もし HTTP要求に JSONP が指定されていた場合は、JSONP 形式で返す。