hello, everyone i am trying to write a simple comet server with evhttp.
the attached is my code currently compiled and runnable. but when i visit ip:8811/streaming, and close the browser, the server side connection callback doesn't invoked. where in this file it's named HTTPServer::onClose. can any one tell me how to get the callback when the browser closed? thanks.
#include <event.h> #include <evhttp.h> #include <unistd.h> #include <iostream> #include <cassert> #include <map> #define MAX 10000 using namespace std; extern "C" { class Push { }; class HTTPServer { private: struct event_base *base; struct evhttp *httpd; struct evhttp_bound_socket *handle; map<string, evhttp_request *> requests; string address; int port; int token; public: HTTPServer(string address = "0.0.0.0", int port = 80) { base = event_base_new(); assert(base); httpd = evhttp_new(base); assert(httpd); this->address = address; this->port = port; int code = evhttp_bind_socket(httpd, address.c_str(), port); cout << endl << code << endl; this->initCb(); token = 10000; } virtual void initHeader(struct evhttp_request *req) { evhttp_add_header(req->output_headers, "Server", "Comet Server"); evhttp_add_header(req->output_headers, "Cache-Control", "no-cache"); evhttp_add_header(req->output_headers, "Content-Type", "text/plain"); } virtual void initCb() { evhttp_set_cb(httpd, "/streaming", HTTPServer::onStreaming, (void *)this); evhttp_set_cb(httpd, "/register", HTTPServer::onRegister, (void *)this); evhttp_set_cb(httpd, "/notify", HTTPServer::onNotify, (void *)this); } int getToken(); int sendMessage(struct evhttp_request *req, string message, bool chunked = false); static void onCommon(struct evhttp_request *req, void *arg); static void onStreaming(struct evhttp_request *req, void *arg); static void onRegister(struct evhttp_request *req, void *arg); static void onNotify(struct evhttp_request *req, void *arg); static void onClose(struct evhttp_connection *con, void *arg); void run() { cout << "Inside Run" << endl; event_base_dispatch(base); } ~HTTPServer() { evhttp_free(httpd); } }; int HTTPServer::getToken() { return token++; } int HTTPServer::sendMessage(struct evhttp_request *req, string message, bool chunked) { struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "%s", message.c_str()); if (!chunked) { evhttp_send_reply(req, HTTP_OK, "OK", buf); } else { evhttp_send_reply_chunk(req, buf); } } void HTTPServer::onClose(struct evhttp_connection *con, void *arg) { cout << " connection closed " << endl; } void HTTPServer::onRegister(struct evhttp_request *req, void *arg) { HTTPServer *server = (HTTPServer *) arg; int key = server->getToken(); cout << key << endl; struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "%d", key); evhttp_send_reply(req, HTTP_OK, "OK", buf); } void HTTPServer::onNotify(struct evhttp_request *req, void *arg) { } void HTTPServer::onStreaming(struct evhttp_request *req, void *arg) { HTTPServer *server = (HTTPServer *)arg; cout << "Inside onComet" << endl; const char * uri = evhttp_request_uri(req); cout << uri << endl; cout << req->kind <<endl; server->initHeader(req); evhttp_send_reply_start(req, HTTP_OK, "OK"); evhttp_connection_set_closecb(req->evcon, HTTPServer::onClose, NULL); //evhttp_send_reply(req, HTTP_OK, "OK"); //evhttp_send_reply_chunk(req, buf); cout << "Inside onComet end" << endl; string a = "hello world from streaming"; server->sendMessage(req, a, true); } void HTTPServer::onCommon(struct evhttp_request *req, void *arg) { cout << "Inside onCommon" << endl; struct evbuffer *buf; buf = evbuffer_new(); cout << req->kind <<endl; if (buf == NULL) { cerr << "1, failed to create response buffer" << endl; cout << "1, failed to create response buffer" << endl; } evbuffer_add_printf(buf, "{\"now\":%d}", (int)time(NULL)); evhttp_send_reply(req, HTTP_OK, "OK", buf); cout << "Inside onCommon end" << endl; } } int main() { HTTPServer *server = new HTTPServer("0.0.0.0", 8811); server->run(); }