libevent的http服务与libjson结合
2016-01-07 09:45
786 查看
libevent的http服务与libjson结合
最近接收了一项任务,计划在linux下的app应用程序(c++)里面添加http服务支持,因为这个app应用程序,是用libevent写的,在看到libevent有自带的http服务模块后,打算直接就拿来使用了,基本技术特点如下:libevent+http
json支持
闲话少说,贴出代码先
1,main.cpp,仅贴出部分代码
if (FAILED == CHttpMgr::CreateHttpServerThread()) { LOG_ERROR("Create Http Server Thread Failed!"); return FAILED; }
2,HttpMgr.h
// #ifndef _HTTPMGR_HH_ #define _HTTPMGR_HH_ #include "common.h" #include <event2/event.h> #include <event2/http.h> #include <event2/buffer.h> #include <event2/util.h> #include <event2/keyvalq_struct.h> #define GET_TARG_POSITION "/Target/GetPosition" // #define GET_TARG_POSITION_SIZE 19 #define GET_TARG_BASICINFO "/Target/GetInfo" // #define GET_TARG_BASICINFO_SIZE 15 class CHttpMgr { public: //创建http服务器线程 static int CreateHttpServerThread(); //libevent循环 static void* HttpServerWorkerLibevent(void* arg); //接收http请求 static void dump_request_cb(struct evhttp_request *req, void *arg); //处理http GET 请求 static void handle_request_get(struct evhttp_request *req, void *arg); //处理http POST 请求 static void handle_request_post(struct evhttp_request *req, void *arg); //业务解码 static int decode_get_targ_position(struct evkeyvalq *params, string &str); };
3,HttpMgr.cpp
#include "HttpMgr.h" #include "Util.h" #include <json/json.h> /***************************************************************************** 函数名称 : CreateHttpServerThread 函数描述 : 创建http服务器线程 输出参数 : N/A 返回值 : int 备注 : N/A *****************************************************************************/ int CHttpMgr::CreateHttpServerThread() { LOG_FUN; struct event_base *base; struct evhttp *http; struct evhttp_bound_socket *handle; unsigned short port = 8000; base = event_base_new(); if (!base) { LOG_ERROR("event_base_new FAILED!"); return FAILED; } /* Create a new evhttp object to handle requests. */ http = evhttp_new(base); if (!http) { LOG_ERROR("evhttp_new FAILED!"); return FAILED; } //仅接收"/Target"下的http请求 //evhttp_set_cb(http, "/Target", CHttpMgr::dump_request_cb, NULL); //接收http任意请求 evhttp_set_gencb(http, CHttpMgr::dump_request_cb, NULL); handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port); if (!handle) { LOG_ERROR("evhttp_bind_socket_with_handle FAILED!"); return FAILED; } //准备结束,启动循环线程 int iRet = 0; pthread_t tidHttpServer; if ((iRet = pthread_create(&tidHttpServer, NULL, CHttpMgr::HttpServerWorkerLibevent, base))) { LOG_ERROR("Create Http Server Thread Failed! -- %d", iRet); return FAILED; } return SUCCESS; } /***************************************************************************** 函数名称 : HttpServerWorkerLibevent 函数描述 : libevent循环 输出参数 : N/A 返回值 : void* 备注 : N/A *****************************************************************************/ void* CHttpMgr::HttpServerWorkerLibevent(void* arg) { LOG_FUN; struct event_base* pBase = static_cast<struct event_base*>(arg); if (!pBase) { LOG_ERROR("Http Server thread arg FAILED!"); return NULL; } (void)event_base_loop(pBase, 0); return NULL; } /***************************************************************************** 函数名称 : dump_request_cb 函数描述 : http请求处理函数 输出参数 : N/A 返回值 : void 备注 : N/A *****************************************************************************/ void CHttpMgr::dump_request_cb(struct evhttp_request *req, void *arg) { LOG_FUN; const char *cmdtype; switch (evhttp_request_get_command(req)) { case EVHTTP_REQ_GET: { cmdtype = "GET"; LOG_DEBUG("CMD Type GET "); handle_request_get(req, arg); break; } case EVHTTP_REQ_POST: { cmdtype = "POST"; LOG_DEBUG("CMD Type POST "); handle_request_post(req, arg); break; } case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; LOG_DEBUG("CMD Type HEAD ");break; case EVHTTP_REQ_PUT: cmdtype = "PUT"; LOG_DEBUG("CMD Type PUT ");break; case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; LOG_DEBUG("CMD Type DELETE ");break; case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; LOG_DEBUG("CMD Type OPTIONS "); break; case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; LOG_DEBUG("CMD Type TRACE ");break; case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; LOG_DEBUG("CMD Type CONNECT ");break; case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; LOG_DEBUG("CMD Type PATCH ");break; default: cmdtype = "unknown"; LOG_DEBUG("CMD Type unknown ");break; } } /***************************************************************************** 函数名称 : handle_request_get 函数描述 : Http Get请求处理函数 输出参数 : N/A 返回值 : void 备注 : N/A *****************************************************************************/ void CHttpMgr::handle_request_get(struct evhttp_request *req, void *arg) { LOG_FUN; struct evkeyvalq *headers; struct evkeyvalq params; struct evkeyval *header; struct evbuffer *buf; const char *uri; string strOut="";//http 输出的码流 int CODE = HTTP_OK; //获取请求的URI uri = evhttp_request_get_uri(req); LOG_DEBUG("Received a GET request for %s headers:", uri); //debug 信息输出{ headers = evhttp_request_get_input_headers(req); for (header = headers->tqh_first; header; header = header->next.tqe_next) { LOG_DEBUG("%s : %s", header->key, header->value); } //debug } //参数查询 evhttp_parse_query(uri, ¶ms); // if (0 == strncmp(uri, GET_TARG_POSITION, GET_TARG_POSITION_SIZE)) { CODE = decode_get_targ_position(¶ms, strOut); } else if (0 == strncmp(uri, GET_TARG_BASICINFO, GET_TARG_BASICINFO_SIZE)) { LOG_ERROR("Expand Get Target Info Interface, havn't implemented!"); CODE = HTTP_NOTIMPLEMENTED; strOut.append("Get Target Info not implemented"); } else { LOG_ERROR("Reserved!"); CODE = HTTP_NOTIMPLEMENTED; strOut.append("not implemented"); } buf = evbuffer_new(); evbuffer_add_printf(buf, "%s",strOut.c_str()); //http 应答 evhttp_send_reply(req, CODE, "OK", buf); //释放资源 evhttp_clear_headers(¶ms); evhttp_clear_headers(headers); evbuffer_free(buf); } /***************************************************************************** 函数名称 : handle_request_post 函数描述 : Http POST请求处理函数 输出参数 : N/A 返回值 : void 备注 : N/A *****************************************************************************/ void CHttpMgr::handle_request_post(struct evhttp_request *req, void *arg) { LOG_FUN; LOG_ERROR("handle_request_post Reserved!"); } int CHttpMgr::decode_get_targ_position(struct evkeyvalq *params, string &str) { LOG_FUN; //JSON格式编码 Json::Value root; Json::Value arrayObj; root["resultCode"] = "0"; root["TargName"] = "Test"; root["Latitude"] = "30.12345"; root["Longitude"] = "102.1323"; root["dateTime"] = 1452052317; str = root.toStyledString(); return HTTP_OK; }
相关文章推荐
- Http 协议
- Android:3G网络是否可用
- 2016【太原网络营销师】郭文军教你如何学网络营销
- 消除SDK更新时的“https://dl-ssl.google.com refused”异常
- Mac用CornerStone配置SVN,HTTP及svn简单使用说明
- asp.net中http提交数据所遇到的那些坑
- [原]unity3d之http多线程异步资源下载
- SDH,OTN,IP,MPLS,ATM网络介绍
- Android之使用Http协议实现文件上传示例(上传MP3文件)
- 关于广域网环境TCP是否适用的问题
- 关于Java去连接HTTP地址的操作
- HTTP状态码
- Tomcat 输入http://localhost:8080网页打不开(估计是端口号被占用)
- 关于Spring4.0 MappingJackson2HttpMessageConverter
- http(16):如何使用HttpClient库用代码访问服务器
- Redirect HTTP to HTTPS on Tomcat
- CentOS5.8 HA集群之基于crm配置 heartbeat + nfs + httpd
- 网络基础知识-4
- linux下TCP/IP实现简单聊天程序
- 第四十一天-http与www服务进阶概念详解