HttpBroker クラスは、mpchat_server で HttpMessageHandler を利用している部分である。 定義は次のようになっている:
class HttpBroker: public nine::HttpMessageHandler
{
public:
HttpBroker();
virtual ~HttpBroker();
bool initialize(ChatService*, const char* path);
virtual bool handleMessage(nine::Message* pMsg);
private:
void responseLog(int sid, int from);
ChatService *m_pService;
};
HttpBroker は HttpMessageHandler であり、HttpHandler である。 HttpHandler は、HttpServer の authorizeHttp() 関数の戻り値としてフレームワークに渡すことで利用されるようになる。
bool Server::initialize(const ServerConfig* pCfg)
{
...
if (! m_httpBroker.initialize(&m_service, "/http")) {
return false;
}
m_httpServer.setHandler("/http", &m_httpBroker);
m_httpServer は PathHttpServer である。
上の初期化コードにより、HttpBroker は "/http" というリクエストパスに対応するよう設定される。
bool HttpBroker::initialize(ChatService* pService, const char* path)
{
{
nine::HttpMessageHandlerConfig cfg;
cfg.nSessions = 10;
cfg.sessionCookie = "sid";
cfg.sessionCookiePath = path;
cfg.jsonp = "jsonp";
cfg.enableQueryStringMarshal = true;
cfg.enablePostMarshal = true;
typedef nine::HttpMessageHandler super;
if (! super::initialize(&cfg)) { return false; }
}
m_pService = pService;
return true;
}
responseLog() は private 関数であり、他の関数から呼び出される。 処理内容は、ChatService からログを取得し、LogNotify メッセージに入れて post することである。
post() は HTTP 要求処理中にしか使えない。サンプルでは、responseLog() は handleMessage() から呼ばれるだけになっているので問題はない。
void HttpBroker::responseLog(int sid, int from)
{
LogNotify msg;
m_pService->get(from, &msg);
if (! this->post(sid, &msg)) {
printf("post failed in HttpMessageBroker::responseLog");
}
}
HTTP の制約により、post() は要求の処理中にしか行えない。 このため、responseLog() は受信ハンドラの中から呼ばれるようになっている。
handleMessage() は、要求に含まれていたメッセージを処理するハンドラである。 HttpMessageHandler においては、HTTP応答を返す前に呼びだされるので、post() や flow() を使うことができる。
int sid = pMsg->getCommunicatorId();
uint16_t msgid = pMsg->getMessageId();
if (msgid == ChatRequest::_MESSAGE_ID) {
...
} else if (msgid == LogRequest::_MESSAGE_ID) {
...
}
ChatRequest は、クライアントが新規発言をした際に送られるメッセージである。 ChatRequest は同時に発言ログの要求も行う。
if (msgid == ChatRequest::_MESSAGE_ID) {
ChatRequest* p = static_cast< ChatRequest* >(pMsg);
m_pService->add(p->get_chat());
responseLog(sid, p->get_from());
return true;
LogRequest は、発言ログを要求するメッセージである。
} else if (msgid == LogRequest::_MESSAGE_ID) {
LogRequest* p = static_cast< LogRequest* >(pMsg);
responseLog(sid, p->get_from());
return true;