├── README.md ├── example_http ├── Makefile ├── business │ ├── businesshandle.cc │ └── businesshandle.h ├── coh │ ├── cohthread.cc │ └── cohthread.h ├── conf │ ├── config.xml │ └── log.properties ├── main │ └── main.cc ├── student_gen_cpp │ ├── Serv.cpp │ ├── Serv.h │ ├── student_constants.cpp │ ├── student_constants.h │ ├── student_types.cpp │ └── student_types.h └── valgrind.sh ├── example_thrift ├── Makefile ├── business │ ├── businesshandle.cc │ └── businesshandle.h ├── conf │ ├── config.xml │ └── log.properties ├── main │ └── main.cc ├── student.thrift └── student_gen_cpp │ ├── Serv.cpp │ ├── Serv.h │ ├── student_constants.cpp │ ├── student_constants.h │ ├── student_types.cpp │ └── student_types.h └── frame ├── Makefile ├── common ├── dirreader.cc ├── dirreader.h ├── msgqueueprio.cc ├── msgqueueprio.h ├── msgtimerthread.cc ├── msgtimerthread.h ├── soloader.cc ├── soloader.h ├── threadtimer.cc ├── threadtimer.h ├── timermanager.cc ├── timermanager.h ├── xmlconfigparser.cc └── xmlconfigparser.h ├── event ├── events.h ├── httpmessage.cc ├── httpmessage.h ├── thriftmessage.cc └── thriftmessage.h ├── interface ├── buffer.h ├── errorcode.h ├── handleralloc.h ├── loghelper.h └── urlcode.h ├── net ├── connection.cc ├── connection.h ├── ioservicethread.cc ├── ioservicethread.h ├── netservice.h ├── netthreadholder.cc ├── netthreadholder.h ├── sessioncallback.h ├── sessionmanager.cc ├── sessionmanager.h ├── socsessionmanager.cc ├── socsessionmanager.h ├── sossessionmanager.cc ├── sossessionmanager.h ├── tcpsocketserver.cc └── tcpsocketserver.h ├── protocol ├── baseparser.cc ├── baseparser.h ├── httpparser.cc ├── httpparser.h ├── protocol.h ├── protocolhelper.cc ├── protocolhelper.h ├── thriftparser.cc └── thriftparser.h ├── session ├── httpsession.cc ├── httpsession.h ├── session.cc ├── session.h └── sessionfactory.cc ├── tinyxml2 ├── tinyxml2.cpp └── tinyxml2.h └── unit_test ├── Makefile ├── helper ├── buffer.h ├── compresscoder.cc ├── compresscoder.h ├── fieldbuffer.cc ├── fieldbuffer.h ├── ftdcoder.cc ├── ftdcoder.h ├── ftdfunc.h ├── xmpcoder.cc └── xmpcoder.h ├── log.properties ├── src ├── controller.h ├── func.h ├── main.cc ├── t_httprequestdecoder.cc ├── t_httprequestencoder.cc ├── t_httpresponsedecoder.cc ├── t_httpresponseencoder.cc ├── t_parser_factory.cc ├── t_queue.cc ├── t_timer.cc ├── t_timerthread.cc ├── t_xmlconfigparser.cc ├── testthread.cc └── testthread.h └── testfile ├── badconfig.xml └── config.xml /README.md: -------------------------------------------------------------------------------- 1 | ape 2 | === 3 | 4 | 基于boost的高性能服务框架 5 | 6 | 依赖: 7 | xlog <== log4cpp 8 | boost 1.55.0 9 | -------------------------------------------------------------------------------- /example_http/Makefile: -------------------------------------------------------------------------------- 1 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 2 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 3 | VER_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo 'X86-64'; else echo 'X86'; fi;)LIB_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo '_X86-64'; else echo ''; fi;) 4 | 5 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 6 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 7 | CC=g++ 8 | VER=1.0.0 9 | XLOG=$(HOME)/local/xlog 10 | THRIFT = $(HOME)/local/thrift 11 | APE=$(HOME)/local/ape 12 | 13 | DIR_LIST=./business ./student_gen_cpp ./coh ./main 14 | OutPut=build/ 15 | NEW_CODE_PATH=./ 16 | #SOURCE CODE 17 | CC_SRC=$(shell find $(DIR_LIST) -name "*.cc" ) 18 | CC_SRC2=$(shell find $(DIR_LIST) -name "*.c" ) 19 | CC_SRC3=$(shell find $(DIR_LIST) -name "*.cpp" ) 20 | 21 | #OBJECTS 22 | CC_OBJS=$(patsubst %.cc,./$(OutPut)/%.o,$(CC_SRC)) 23 | CC_OBJS2=$(patsubst %.c,./$(OutPut)/%.o,$(CC_SRC2)) 24 | CC_OBJS3=$(patsubst %.cpp,./$(OutPut)/%.o,$(CC_SRC3)) 25 | OBJS=$(CC_OBJS) 26 | OBJS2=$(CC_OBJS2) 27 | OBJS3=$(CC_OBJS3) 28 | #DEPS 29 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 30 | 31 | define OBJ_MKDIR 32 | OBJ_DIRS+=./$(OutPut)/$(1) 33 | endef 34 | CC_DIRS=$(shell find $(DIR_LIST) -type d|sed -e '/.svn/d') 35 | #@echo $(CC_DIRS) 36 | $(foreach dir,$(CC_DIRS),$(eval $(call OBJ_MKDIR,$(dir)))) 37 | 38 | #DEPS 39 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 40 | INC_DIR= 41 | #INCLUDE DIR 42 | define SAFE_MKDIR 43 | INC_DIR+=-I $(1) 44 | endef 45 | $(foreach dir,$(CC_DIRS),$(eval $(call SAFE_MKDIR,$(dir)))) 46 | 47 | 48 | INC_DIR+=-I/usr/include -I$(XLOG)/include -I$(THRIFT)/include -I$(APE)/include 49 | 50 | #LIB_DIR 51 | 52 | LIB_DIR=-L/usr/local/lib $(XLOG)/lib/libxlog.a $(THRIFT)/lib/libthrift.a $(APE)/lib/libape.a 53 | #-ltcmalloc 54 | LIBS=-lz -lrt -lboost_thread -lboost_system -lpthread -Wall -ldl -Wl,--export-dynamic --whole-archive 55 | 56 | LDFLAGS=$(LIB_DIR) $(LIBS) 57 | CPPFLAGS=$(INC_DIR) $(DFLAGS) -DTIXML_USE_STL 58 | 59 | EXE1=./test_ape_http 60 | 61 | all:$(EXE1) 62 | $(shell mkdir -p $(sort $(OBJ_DIRS))) 63 | include $(DEPS) 64 | 65 | $(EXE1):$(OBJS) $(OBJS2) $(OBJS3) 66 | $(CC) -g -O2 -o $@ $^ $(LDFLAGS) 67 | 68 | 69 | ./$(OutPut)/%.o:%.cc 70 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 71 | ./$(OutPut)/%.d:%.cc 72 | @set -e; rm -f $@; \ 73 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 74 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 75 | rm -f $@.$$$$ 76 | 77 | ./$(OutPut)/%.o:%.cpp 78 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 79 | ./$(OutPut)/%.d:%.cpp 80 | @set -e; rm -f $@; \ 81 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 82 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 83 | rm -f $@.$$$$ 84 | 85 | ./$(OutPut)/%.o:%.c 86 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 87 | ./$(OutPut)/%.d:%.c 88 | @set -e; rm -f $@; \ 89 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 90 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 91 | rm -f $@.$$$$ 92 | 93 | clean: 94 | rm -Rf $(OutPut) 95 | rm -rf $(EXE1) 96 | codelen: 97 | find $(NEW_CODE_PATH) \( -name "*.cc" -name "*.cpp" -o -name "*.h" -o -name "*.c" \) -exec cat {} \;|sed -e 's/\"/\n\"\n/g;s/\([^\/]\)\(\/\*\)/\1\n\2\n/g;'|sed -e '/^\"/{:a;N;/\".*\"/!ba;s/\".*\".*//;N;/\"/!d;b}' -e '/^\/\*/{s/\/\*.*\*\///;/\/\*/{:b;N;/\/\*.*\*\//!bb;s/\/\*.*\*\///}}' -e 's/\/\/.*//g' |sed -e '/^[[:space:]]*$$/d'|wc -l 98 | srczip: 99 | zip -r ./$(EXE1)_src_$(VER).zip * -x *.o *.d *.svn *.zip *.a *.so $(EXE1) *.svn-work *.svn-base *.so.* *.d.* *.svn/* 100 | binzip: 101 | if [ ! -d "release" ]; then mkdir release; fi; 102 | cd release;if [ ! -d "lib" ]; then mkdir lib; fi; 103 | cd release;if [ ! -d "plugin/httptransfer" ]; then mkdir -p plugin/httptransfer; fi; 104 | cd release;if [ ! -d "plugin/rapidtransfer" ]; then mkdir -p plugin/rapidtransfer; fi; 105 | cd release;if [ ! -d "plugin/weaktransfer" ]; then mkdir -p plugin/weaktransfer; fi; 106 | cp ./beacon ./release/ 107 | cp -r ./conf ./release/conf 108 | cp ./run.sh ./release/run.sh 109 | cp $(HOME)/local/json/lib/libjson.so.0.1.0 ./release/lib/libjson.so.0 110 | 111 | ldd ./beacon>sys_so_111_232_876_23;cp `awk '{if(substr($$3,1,4)!="/lib"&&substr($$3,1,8)!="/usr/lib")print $$3}' sys_so_111_232_876_23` ./release/lib/;rm -rf sys_so_111_232_876_23 112 | cd release; zip -r ../Beacon$(VER)_$(OS)_Gcc$(GCC)_X86.zip * 113 | rm -rf release 114 | 115 | EXEDIR=apelus-beacon-server 116 | packet: 117 | if [ ! -d "release/usr/local/$(EXEDIR)" ]; then mkdir -p release/usr/local/$(EXEDIR); fi; 118 | if [ ! -d "release/usr/local/$(EXEDIR)/lib" ]; then mkdir -p release/usr/local/$(EXEDIR)/lib; fi; 119 | if [ ! -d "release/usr/local/$(EXEDIR)/conf" ]; then mkdir -p release/usr/local/$(EXEDIR)/conf; fi; 120 | if [ ! -d "release/usr/local/$(EXEDIR)/plugin" ]; then mkdir -p release/usr/local/$(EXEDIR)/plugin; fi; 121 | 122 | cp $(EXE1) ./release/usr/local/$(EXEDIR)/ 123 | cp ./conf/* ./release/usr/local/$(EXEDIR)/conf/ 124 | cp ./run.sh ./release/usr/local/$(EXEDIR)/ 125 | cp $(HOME)/local/json/lib/libjson.so.0.1.0 ./release/usr/local/$(EXEDIR)/lib/libjson.so.0 126 | cp -r ./plugin/* ./release/usr/local/$(EXEDIR)/plugin/ 127 | cp -r ./dist/DEBIAN ./release/ 128 | cp -r ./dist/etc ./release/ 129 | 130 | chmod -R +x ./release/* 131 | chmod +x ./release/usr/local/$(EXEDIR)/* 132 | chmod 755 ./release/DEBIAN/* 133 | ldd ./$(EXE1)>sys_so_111_232_876_23;cp `awk '{if(substr($$3,1,4)!="/lib"&&substr($$3,1,8)!="/usr/lib")print $$3}' sys_so_111_232_876_23` ./release/usr/local/$(EXEDIR)/lib/;rm -rf sys_so_111_232_876_23 134 | # cd release;tar -czhf ../$(EXE1)_$(VER)_$(OS)_Gcc$(GCC).tar.gz * --exclude=".svn" --exclude=".git" --exclude="*.pyc" --exclude="*.log" 135 | mv release $(EXEDIR)_$(VER)_amd64;tar -czhf ./$(EXEDIR)_$(VER)_amd64.tar.gz $(EXEDIR)_$(VER)_amd64 --exclude=".svn" --exclude=".git" --exclude="*.pyc" --exclude="*.log" 136 | #dpkg --build release/ $(EXE1)-1.0.0_i386.deb 137 | rm -rf $(EXEDIR)_$(VER)_amd64 138 | -------------------------------------------------------------------------------- /example_http/business/businesshandle.cc: -------------------------------------------------------------------------------- 1 | #include "businesshandle.h" 2 | #include "Serv.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace ape { 10 | namespace testhttp { 11 | 12 | typedef struct stThriftContext : public ape::message::SContext { 13 | ape::message::SHttpMessage *httpmsg; 14 | stThriftContext(ape::message::SHttpMessage *msg) : httpmsg(msg) {} 15 | virtual ~stThriftContext() {} 16 | }SThriftContext; 17 | 18 | CBusinessHandle::CBusinessHandle() : smseqid_(0) { 19 | } 20 | void CBusinessHandle::StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner) { 21 | threadid_ = threadid; 22 | service_ = service; 23 | timerowner_ = owner; 24 | } 25 | void CBusinessHandle::OnEvent(int threadid, void *event) { 26 | ape::message::SEvent *e = (ape::message::SEvent *)event; 27 | BS_XLOG(XLOG_TRACE,"CBusinessHandle::%s, event_id[%d], threadid[%d]\n", __FUNCTION__, e->id, threadid); 28 | switch (e->id) { 29 | case ape::message::SHttpMessage::ID: { 30 | ape::message::SHttpMessage * msg = (ape::message::SHttpMessage *)e; 31 | if (!msg->IsReply()) { 32 | DealHttpRequest(msg); 33 | } 34 | break; 35 | } 36 | case ape::message::SThriftMessage::ID: { 37 | ape::message::SThriftMessage * msg = (ape::message::SThriftMessage *)e; 38 | if (msg->IsReply()) { 39 | DealThriftResponse(msg); 40 | } 41 | delete e; 42 | break; 43 | } 44 | default: { 45 | delete e; 46 | break; 47 | } 48 | } 49 | } 50 | void CBusinessHandle::DealThriftResponse(ape::message::SThriftMessage *message) { 51 | BS_XLOG(XLOG_TRACE,"CBusinessHandle::%s, \n%s\n", __FUNCTION__, message->NoticeInfo().c_str()); 52 | 53 | boost::shared_ptr buf( 54 | new apache::thrift::transport::TMemoryBuffer((uint8_t*)(message->body.c_str()), message->body.length())); 55 | boost::shared_ptr pro(new apache::thrift::protocol::TBinaryProtocol(buf)); 56 | teststudent::Serv_QueryByNo_result result; 57 | result.read(pro.get()); 58 | 59 | teststudent::Student &stu = result.success; 60 | BS_XLOG(XLOG_DEBUG,"BusinessThread::%s, result.__isset.success[%d], no[%s], name[%s], age[%d]\n", __FUNCTION__, 61 | result.__isset.success, stu.no.c_str(), stu.name.c_str(), stu.age); 62 | 63 | SThriftContext *ctx = (SThriftContext *)(message->ctx); 64 | char szstu[1024] = {0}; 65 | snprintf(szstu, 1023, "{\"return_code\":0, \"return_message\":\"success\",\"data\":{\"no\":\"%s\",\"name\":\"%s\",\"age\":\"%d\"}}", 66 | stu.no.c_str(), stu.name.c_str(), stu.age); 67 | DoSendHttpResponse(ctx->httpmsg, 200, szstu); 68 | delete ctx; 69 | } 70 | void CBusinessHandle::DealHttpRequest(ape::message::SHttpMessage *message) { 71 | message->Dump(); 72 | if (0 == message->url.compare("/testthrift")) { 73 | DoTestThriftRequest(message); 74 | return; 75 | } 76 | DoSendHttpResponse(message, 200, "{\"return_code\":0, \"return_message\":\"success\"}"); 77 | } 78 | void CBusinessHandle::DoSendHttpResponse(ape::message::SHttpMessage *request, int code, const std::string &body) { 79 | ape::message::SHttpMessage *response = new ape::message::SHttpMessage; 80 | response->SetReply(code); 81 | response->requestno = request->requestno; 82 | response->keepalive = request->keepalive; 83 | response->httpversion = request->httpversion; 84 | response->body = body; 85 | service_->DoSendBack(request->connid, response); 86 | delete request; 87 | } 88 | void CBusinessHandle::DoTestThriftRequest(ape::message::SHttpMessage *message) { 89 | teststudent::Serv_QueryByNo_args args; 90 | args.no = "0743111245"; 91 | 92 | boost::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer(1024)); 93 | boost::shared_ptr pro(new apache::thrift::protocol::TBinaryProtocol(buf)); 94 | buf->open(); 95 | args.write(pro.get()); 96 | 97 | ape::message::SThriftMessage *msg = new ape::message::SThriftMessage; 98 | msg->method = "QueryByNo"; 99 | msg->seqid = smseqid_++; 100 | msg->body = buf->getBufferAsString(); 101 | msg->ctx = new SThriftContext(message); 102 | 103 | std::string addr = "thrift://127.0.0.1:10012"; 104 | service_->DoConnect(addr, addr, true, 5000); 105 | service_->DoSendTo(addr, msg); 106 | } 107 | void CBusinessHandle::Dump() { 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /example_http/business/businesshandle.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_TEST_BUSINESS_HANDLE_H_ 2 | #define _APE_TEST_BUSINESS_HANDLE_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace ape { 11 | namespace testhttp { 12 | 13 | class CBusinessHandle : public ape::net::CHandle { 14 | public: 15 | typedef void (CBusinessHandle::*DealUrlFunc)(ape::message::SHttpMessage *, const std::string &); 16 | CBusinessHandle(); 17 | virtual ~CBusinessHandle() {} 18 | virtual void StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner); 19 | virtual void StopInThread(int threadid) {} 20 | virtual void OnEvent(int threadid, void *event); 21 | void Dump(); 22 | 23 | private: 24 | void DealThriftResponse(ape::message::SThriftMessage *message); 25 | void DealHttpRequest(ape::message::SHttpMessage *message); 26 | void DoSendHttpResponse(ape::message::SHttpMessage *request, int code, const std::string &body); 27 | void DoTestThriftRequest(ape::message::SHttpMessage *message); 28 | private: 29 | int threadid_; 30 | ape::net::CNetService *service_; 31 | ape::common::CTimerManager *timerowner_; 32 | 33 | uint32_t smseqid_; 34 | }; 35 | } 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /example_http/coh/cohthread.cc: -------------------------------------------------------------------------------- 1 | #include "cohthread.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ape { 9 | namespace testhttp { 10 | static void ParseUrl(const std::string &url, CohThread::SUrlInfo *info) { 11 | char szhost[128]={0}; 12 | char szpath[256]={0}; 13 | 14 | sscanf(url.c_str(), "%*[HTTPhttp]://%[^/]%256s", szhost, szpath); 15 | info->addr = std::string("http://") + szhost; 16 | info->name = std::string("monitor_") + szhost; 17 | info->path = szpath; 18 | } 19 | 20 | CohThread * CohThread::sm_instance_ = NULL; 21 | CohThread * CohThread::GetInstance() { 22 | if(sm_instance_ == NULL) 23 | sm_instance_ = new CohThread; 24 | return sm_instance_; 25 | } 26 | CohThread::CohThread() :service_(NULL) { 27 | mapcmd_["/help"] = SFuncInfo(FUNC_HELP, "Get Cmd List"); 28 | funcmapping_[FUNC_HELP] = &CohThread::DoHelpInfo; 29 | } 30 | CohThread::~CohThread() { 31 | } 32 | int CohThread::StartServer(const std::string &addr) { 33 | CohHandleFactory factory; 34 | holder_.Start(&factory, 0); 35 | 36 | std::vector addrs; 37 | addrs.push_back(addr); 38 | return holder_.StartServer(addrs); 39 | } 40 | void CohThread::Stop() { 41 | holder_.Stop(); 42 | } 43 | void CohThread::InitUrl(const std::string &errorrurl, const std::string &actionurl) { 44 | ParseUrl(errorrurl, &error_url_); 45 | ParseUrl(actionurl, &action_url); 46 | } 47 | void CohThread::OnErrorReport(const std::string &info) { 48 | ape::message::SHttpMessage *msg = new ape::message::SHttpMessage; 49 | msg->httpversion = ape::message::SHttpMessage::HTTP_1_0; 50 | msg->method = "POST"; 51 | msg->url = error_url_.path; 52 | msg->keepalive = false; 53 | msg->body = info; 54 | if (service_) { 55 | service_->OnConnect(error_url_.name, error_url_.addr, true, 5000); 56 | service_->OnSendTo(error_url_.name, msg); 57 | } 58 | } 59 | void CohThread::OnActionReport(const std::string &info) { 60 | ape::message::SHttpMessage *msg = new ape::message::SHttpMessage; 61 | msg->httpversion = ape::message::SHttpMessage::HTTP_1_0; 62 | msg->method = "POST"; 63 | msg->url = action_url.path; 64 | msg->keepalive = false; 65 | msg->body = info; 66 | if (service_) { 67 | service_->OnConnect(action_url.name, action_url.addr); 68 | service_->OnSendTo(action_url.name, msg); 69 | } 70 | } 71 | void CohThread::StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner) { 72 | service_ = service; 73 | } 74 | void CohThread::OnEvent(int threadid, void *event) { 75 | ape::message::SEvent *e = (ape::message::SEvent *)event; 76 | BS_XLOG(XLOG_TRACE,"CohThread::%s, type[%d], threadid[%d]\n", __FUNCTION__, e->id, threadid); 77 | switch (e->id) { 78 | case ape::message::SHttpMessage::ID: { 79 | ape::message::SHttpMessage *message = (ape::message::SHttpMessage *)e; 80 | message->Dump(); 81 | if (message->type == ape::message::SNetMessage::E_Request) { 82 | DealCohCmd(message); 83 | } 84 | delete e; 85 | break; 86 | } 87 | default: { 88 | delete e; 89 | break; 90 | } 91 | } 92 | } 93 | void CohThread::DealCohCmd(ape::message::SHttpMessage *message) { 94 | ape::message::SHttpMessage *response = new ape::message::SHttpMessage; 95 | transform(message->url.begin(), message->url.end(), message->url.begin(), ::tolower); 96 | std::map::iterator itr = mapcmd_.find(message->url); 97 | if (itr != mapcmd_.end()) { 98 | response->body = (this->*(funcmapping_[itr->second.type]))(message); 99 | } else { 100 | response->body = "Bad Command; Try /Help"; 101 | } 102 | 103 | response->code = 200; 104 | response->SetReply(200); 105 | response->requestno = message->requestno; 106 | response->keepalive = message->keepalive; 107 | response->httpversion = message->httpversion; 108 | service_->DoSendBack(message->connid, response); 109 | } 110 | std::string CohThread::DoHelpInfo(ape::message::SHttpMessage *message) { 111 | std::string str = "Help"; 112 | str.append(""); 113 | std::map::iterator itr = mapcmd_.begin(); 114 | for(; itr != mapcmd_.end(); ++itr) { 115 | str.append(""); 120 | } 121 | str.append("
commanddescription
"); 116 | str.append(itr->first); 117 | str.append(""); 118 | str.append(itr->second.desc); 119 | str.append("
"); 122 | return str; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /example_http/coh/cohthread.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_COH_THREAD_ 2 | #define _APE_COMMON_COH_THREAD_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace ape { 11 | namespace testhttp { 12 | 13 | class CohThread : public ape::net::CHandle { 14 | public: 15 | typedef enum{FUNC_HELP = 0, FUNC_ALL}EFuncType; 16 | typedef std::string (CohThread::*DealCmdFunc)(ape::message::SHttpMessage *); 17 | typedef struct stFuncInfo { 18 | EFuncType type; 19 | std::string desc; 20 | stFuncInfo(){} 21 | stFuncInfo(EFuncType t, const std::string &s) : type(t), desc(s){} 22 | }SFuncInfo; 23 | public: 24 | static CohThread *GetInstance(); 25 | virtual ~CohThread(); 26 | int StartServer(const std::string &addr); 27 | void Stop(); 28 | void InitUrl(const std::string &errorrurl, const std::string &actionurl); 29 | void OnErrorReport(const std::string &info); 30 | void OnActionReport(const std::string &info); 31 | public: 32 | virtual void StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner); 33 | virtual void StopInThread(int threadid) {} 34 | virtual void OnEvent(int threadid, void *event); 35 | virtual void Release() {} 36 | public: 37 | typedef struct stUrlInfo { 38 | std::string addr; 39 | std::string name; 40 | std::string path; 41 | }SUrlInfo; 42 | private: 43 | CohThread(); 44 | void DealCohCmd(ape::message::SHttpMessage *message); 45 | std::string DoHelpInfo(ape::message::SHttpMessage *message); 46 | private: 47 | static CohThread * sm_instance_; 48 | ape::net::CNetThreadHolder holder_; 49 | ape::net::CNetService *service_; 50 | std::map mapcmd_; 51 | DealCmdFunc funcmapping_[FUNC_ALL]; 52 | 53 | SUrlInfo error_url_; 54 | SUrlInfo action_url; 55 | }; 56 | class CohHandleFactory : public ape::net::HandleFactory { 57 | public: 58 | virtual ape::net::CHandle* NewHandler() { 59 | return CohThread::GetInstance(); 60 | } 61 | virtual ~CohHandleFactory() {} 62 | }; 63 | } 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /example_http/conf/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 4 | 5 | http://0.0.0.0:10011 6 | 7 | http://0.0.0.0:20021 8 | 9 | 10 | -------------------------------------------------------------------------------- /example_http/conf/log.properties: -------------------------------------------------------------------------------- 1 | log4cplus.logger.business=ALL,BUSINESS 2 | log4cplus.additivity.business=false 3 | 4 | log4cplus.appender.STDOUT=log4cplus::ConsoleAppender 5 | log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout 6 | log4cplus.appender.STDOUT.layout.ConversionPattern=%-6p[%t][%D{%m/%d/%y %H:%M:%S %Q}]%m 7 | 8 | log4cplus.appender.BUSINESS=log4cplus::RollingFileAppender 9 | log4cplus.appender.BUSINESS.File=./log/all.log 10 | log4cplus.appender.BUSINESS.MaxFileSize=5MB 11 | log4cplus.appender.BUSINESS.MaxBackupIndex=5 12 | log4cplus.appender.BUSINESS.layout=log4cplus::PatternLayout 13 | log4cplus.appender.BUSINESS.layout.ConversionPattern=%-6p[%t] [%D{%m/%d/%y %H:%M:%S %Q}] %m 14 | 15 | -------------------------------------------------------------------------------- /example_http/main/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "businesshandle.h" 12 | #include "cohthread.h" 13 | 14 | #define __TESTAPE__VERSION__ "1.0.0" 15 | #define DEBUG 16 | 17 | void terminate(int signum) { 18 | usleep(500); 19 | _exit(0); 20 | } 21 | 22 | int run(int flag, int argc, char* argv[]) { 23 | XLOG_INIT("./conf/log.properties", true); 24 | XLOG_REGISTER(BUSINESS_MODULE, "business"); 25 | 26 | if (flag != 0) { 27 | BS_XLOG(XLOG_FATAL,"--------reboot!!!--------\n"); 28 | } 29 | const char *configfile = "./conf/config.xml"; 30 | ape::common::CXmlConfigParser parser; 31 | if (0 != parser.ParseFile(configfile)) { 32 | BS_XLOG(XLOG_FATAL,"parse config[%s] failed, error[%s]\n", configfile, parser.GetErrorMessage().c_str()); 33 | return -1; 34 | } 35 | 36 | sigset_t new_mask; 37 | sigfillset(&new_mask); 38 | sigset_t old_mask; 39 | pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); 40 | 41 | std::vector addrs = parser.GetParameters("server/addr"); 42 | ape::net::NetHandleFactory factory; 43 | ape::net::CNetThreadHolder threadholder; 44 | threadholder.Start(&factory, parser.GetParameter("netthread", 3)); 45 | if (0 != threadholder.StartServer(addrs)) { 46 | return -1; 47 | } 48 | 49 | if (0 != ape::testhttp::CohThread::GetInstance()->StartServer( 50 | parser.GetParameter("cohserver", "http://0.0.0.0:9080"))) 51 | { 52 | return -1; 53 | } 54 | ape::testhttp::CohThread::GetInstance()->InitUrl( 55 | "http://192.168.0.176:8008/errorreport.html", 56 | "http://192.168.0.176:8008/actionreport.html"); 57 | 58 | pthread_sigmask(SIG_SETMASK, &old_mask, 0); 59 | signal(SIGTERM, terminate); 60 | 61 | #if 1 62 | char c; 63 | while ( c = getchar()) { 64 | if(c=='q') { 65 | threadholder.Stop(); 66 | ape::testhttp::CohThread::GetInstance()->Stop(); 67 | delete ape::testhttp::CohThread::GetInstance(); 68 | XLOG_DESTROY(); 69 | break; 70 | } 71 | else if(c=='p'){ 72 | /** dump */ 73 | } else if(c=='t'){ 74 | ape::testhttp::CohThread::GetInstance()->OnErrorReport("error=message&ip=127.0.0.1"); 75 | } else if(c!='\n') { 76 | BS_XLOG(XLOG_WARNING,"can not regnize char [%c]\n",c); 77 | } 78 | } 79 | #else 80 | while (1){ 81 | sleep(1); 82 | } 83 | #endif 84 | } 85 | 86 | bool process_arg(int argc, char* argv[]) { 87 | char c; 88 | while((c = getopt (argc,argv,"v")) != -1 ) { 89 | switch (c) { 90 | case 'v': 91 | printf("Monitor Server version: %s\n", __TESTAPE__VERSION__); 92 | printf("Build time: %s %s\n", __TIME__, __DATE__); 93 | return false; 94 | default: 95 | return true; 96 | } 97 | } 98 | return true; 99 | } 100 | 101 | int main(int argc, char* argv[]) 102 | { 103 | if(!process_arg(argc,argv)) 104 | return 0; 105 | 106 | #ifdef DEBUG 107 | run(0, argc, argv); 108 | #else 109 | if (0 == fork()) { 110 | run(0, argc, argv); 111 | exit(0); 112 | } 113 | 114 | struct timeval begin, end, interval; 115 | gettimeofday(&begin,0); 116 | while (1) { 117 | wait(NULL); 118 | gettimeofday(&end,0); 119 | if(end.tv_sec > begin.tv_sec) { 120 | sleep(1); 121 | if (0 == fork()) { 122 | run(-1, argc, argv); 123 | exit(0); 124 | } 125 | } 126 | } 127 | #endif 128 | return 0; 129 | } 130 | 131 | -------------------------------------------------------------------------------- /example_http/student_gen_cpp/Serv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef Serv_H 8 | #define Serv_H 9 | 10 | #include 11 | #include "student_types.h" 12 | 13 | namespace teststudent { 14 | 15 | class ServIf { 16 | public: 17 | virtual ~ServIf() {} 18 | virtual void QueryByNo(Student& _return, const std::string& no) = 0; 19 | }; 20 | 21 | class ServIfFactory { 22 | public: 23 | typedef ServIf Handler; 24 | 25 | virtual ~ServIfFactory() {} 26 | 27 | virtual ServIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0; 28 | virtual void releaseHandler(ServIf* /* handler */) = 0; 29 | }; 30 | 31 | class ServIfSingletonFactory : virtual public ServIfFactory { 32 | public: 33 | ServIfSingletonFactory(const boost::shared_ptr& iface) : iface_(iface) {} 34 | virtual ~ServIfSingletonFactory() {} 35 | 36 | virtual ServIf* getHandler(const ::apache::thrift::TConnectionInfo&) { 37 | return iface_.get(); 38 | } 39 | virtual void releaseHandler(ServIf* /* handler */) {} 40 | 41 | protected: 42 | boost::shared_ptr iface_; 43 | }; 44 | 45 | class ServNull : virtual public ServIf { 46 | public: 47 | virtual ~ServNull() {} 48 | void QueryByNo(Student& /* _return */, const std::string& /* no */) { 49 | return; 50 | } 51 | }; 52 | 53 | typedef struct _Serv_QueryByNo_args__isset { 54 | _Serv_QueryByNo_args__isset() : no(false) {} 55 | bool no; 56 | } _Serv_QueryByNo_args__isset; 57 | 58 | class Serv_QueryByNo_args { 59 | public: 60 | 61 | Serv_QueryByNo_args() : no() { 62 | } 63 | 64 | virtual ~Serv_QueryByNo_args() throw() {} 65 | 66 | std::string no; 67 | 68 | _Serv_QueryByNo_args__isset __isset; 69 | 70 | void __set_no(const std::string& val) { 71 | no = val; 72 | } 73 | 74 | bool operator == (const Serv_QueryByNo_args & rhs) const 75 | { 76 | if (!(no == rhs.no)) 77 | return false; 78 | return true; 79 | } 80 | bool operator != (const Serv_QueryByNo_args &rhs) const { 81 | return !(*this == rhs); 82 | } 83 | 84 | bool operator < (const Serv_QueryByNo_args & ) const; 85 | 86 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 87 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 88 | 89 | }; 90 | 91 | 92 | class Serv_QueryByNo_pargs { 93 | public: 94 | 95 | 96 | virtual ~Serv_QueryByNo_pargs() throw() {} 97 | 98 | const std::string* no; 99 | 100 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 101 | 102 | }; 103 | 104 | typedef struct _Serv_QueryByNo_result__isset { 105 | _Serv_QueryByNo_result__isset() : success(false) {} 106 | bool success; 107 | } _Serv_QueryByNo_result__isset; 108 | 109 | class Serv_QueryByNo_result { 110 | public: 111 | 112 | Serv_QueryByNo_result() { 113 | } 114 | 115 | virtual ~Serv_QueryByNo_result() throw() {} 116 | 117 | Student success; 118 | 119 | _Serv_QueryByNo_result__isset __isset; 120 | 121 | void __set_success(const Student& val) { 122 | success = val; 123 | } 124 | 125 | bool operator == (const Serv_QueryByNo_result & rhs) const 126 | { 127 | if (!(success == rhs.success)) 128 | return false; 129 | return true; 130 | } 131 | bool operator != (const Serv_QueryByNo_result &rhs) const { 132 | return !(*this == rhs); 133 | } 134 | 135 | bool operator < (const Serv_QueryByNo_result & ) const; 136 | 137 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 138 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 139 | 140 | }; 141 | 142 | typedef struct _Serv_QueryByNo_presult__isset { 143 | _Serv_QueryByNo_presult__isset() : success(false) {} 144 | bool success; 145 | } _Serv_QueryByNo_presult__isset; 146 | 147 | class Serv_QueryByNo_presult { 148 | public: 149 | 150 | 151 | virtual ~Serv_QueryByNo_presult() throw() {} 152 | 153 | Student* success; 154 | 155 | _Serv_QueryByNo_presult__isset __isset; 156 | 157 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 158 | 159 | }; 160 | 161 | class ServClient : virtual public ServIf { 162 | public: 163 | ServClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) : 164 | piprot_(prot), 165 | poprot_(prot) { 166 | iprot_ = prot.get(); 167 | oprot_ = prot.get(); 168 | } 169 | ServClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) : 170 | piprot_(iprot), 171 | poprot_(oprot) { 172 | iprot_ = iprot.get(); 173 | oprot_ = oprot.get(); 174 | } 175 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() { 176 | return piprot_; 177 | } 178 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() { 179 | return poprot_; 180 | } 181 | void QueryByNo(Student& _return, const std::string& no); 182 | void send_QueryByNo(const std::string& no); 183 | void recv_QueryByNo(Student& _return); 184 | protected: 185 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_; 186 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_; 187 | ::apache::thrift::protocol::TProtocol* iprot_; 188 | ::apache::thrift::protocol::TProtocol* oprot_; 189 | }; 190 | 191 | class ServProcessor : public ::apache::thrift::TDispatchProcessor { 192 | protected: 193 | boost::shared_ptr iface_; 194 | virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext); 195 | private: 196 | typedef void (ServProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*); 197 | typedef std::map ProcessMap; 198 | ProcessMap processMap_; 199 | void process_QueryByNo(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); 200 | public: 201 | ServProcessor(boost::shared_ptr iface) : 202 | iface_(iface) { 203 | processMap_["QueryByNo"] = &ServProcessor::process_QueryByNo; 204 | } 205 | 206 | virtual ~ServProcessor() {} 207 | }; 208 | 209 | class ServProcessorFactory : public ::apache::thrift::TProcessorFactory { 210 | public: 211 | ServProcessorFactory(const ::boost::shared_ptr< ServIfFactory >& handlerFactory) : 212 | handlerFactory_(handlerFactory) {} 213 | 214 | ::boost::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo); 215 | 216 | protected: 217 | ::boost::shared_ptr< ServIfFactory > handlerFactory_; 218 | }; 219 | 220 | class ServMultiface : virtual public ServIf { 221 | public: 222 | ServMultiface(std::vector >& ifaces) : ifaces_(ifaces) { 223 | } 224 | virtual ~ServMultiface() {} 225 | protected: 226 | std::vector > ifaces_; 227 | ServMultiface() {} 228 | void add(boost::shared_ptr iface) { 229 | ifaces_.push_back(iface); 230 | } 231 | public: 232 | void QueryByNo(Student& _return, const std::string& no) { 233 | size_t sz = ifaces_.size(); 234 | size_t i = 0; 235 | for (; i < (sz - 1); ++i) { 236 | ifaces_[i]->QueryByNo(_return, no); 237 | } 238 | ifaces_[i]->QueryByNo(_return, no); 239 | return; 240 | } 241 | 242 | }; 243 | 244 | } // namespace 245 | 246 | #endif 247 | -------------------------------------------------------------------------------- /example_http/student_gen_cpp/student_constants.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #include "student_constants.h" 8 | 9 | namespace teststudent { 10 | 11 | const studentConstants g_student_constants; 12 | 13 | studentConstants::studentConstants() { 14 | } 15 | 16 | } // namespace 17 | 18 | -------------------------------------------------------------------------------- /example_http/student_gen_cpp/student_constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef student_CONSTANTS_H 8 | #define student_CONSTANTS_H 9 | 10 | #include "student_types.h" 11 | 12 | namespace teststudent { 13 | 14 | class studentConstants { 15 | public: 16 | studentConstants(); 17 | 18 | }; 19 | 20 | extern const studentConstants g_student_constants; 21 | 22 | } // namespace 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /example_http/student_gen_cpp/student_types.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #include "student_types.h" 8 | 9 | #include 10 | 11 | namespace teststudent { 12 | 13 | const char* Student::ascii_fingerprint = "52F7D5E8217C4B8FC14F1F30BF2EB41C"; 14 | const uint8_t Student::binary_fingerprint[16] = {0x52,0xF7,0xD5,0xE8,0x21,0x7C,0x4B,0x8F,0xC1,0x4F,0x1F,0x30,0xBF,0x2E,0xB4,0x1C}; 15 | 16 | uint32_t Student::read(::apache::thrift::protocol::TProtocol* iprot) { 17 | 18 | uint32_t xfer = 0; 19 | std::string fname; 20 | ::apache::thrift::protocol::TType ftype; 21 | int16_t fid; 22 | 23 | xfer += iprot->readStructBegin(fname); 24 | 25 | using ::apache::thrift::protocol::TProtocolException; 26 | 27 | 28 | while (true) 29 | { 30 | xfer += iprot->readFieldBegin(fname, ftype, fid); 31 | if (ftype == ::apache::thrift::protocol::T_STOP) { 32 | break; 33 | } 34 | switch (fid) 35 | { 36 | case 1: 37 | if (ftype == ::apache::thrift::protocol::T_STRING) { 38 | xfer += iprot->readString(this->no); 39 | this->__isset.no = true; 40 | } else { 41 | xfer += iprot->skip(ftype); 42 | } 43 | break; 44 | case 2: 45 | if (ftype == ::apache::thrift::protocol::T_STRING) { 46 | xfer += iprot->readString(this->name); 47 | this->__isset.name = true; 48 | } else { 49 | xfer += iprot->skip(ftype); 50 | } 51 | break; 52 | case 3: 53 | if (ftype == ::apache::thrift::protocol::T_I16) { 54 | xfer += iprot->readI16(this->age); 55 | this->__isset.age = true; 56 | } else { 57 | xfer += iprot->skip(ftype); 58 | } 59 | break; 60 | default: 61 | xfer += iprot->skip(ftype); 62 | break; 63 | } 64 | xfer += iprot->readFieldEnd(); 65 | } 66 | 67 | xfer += iprot->readStructEnd(); 68 | 69 | return xfer; 70 | } 71 | 72 | uint32_t Student::write(::apache::thrift::protocol::TProtocol* oprot) const { 73 | uint32_t xfer = 0; 74 | xfer += oprot->writeStructBegin("Student"); 75 | 76 | xfer += oprot->writeFieldBegin("no", ::apache::thrift::protocol::T_STRING, 1); 77 | xfer += oprot->writeString(this->no); 78 | xfer += oprot->writeFieldEnd(); 79 | 80 | xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 2); 81 | xfer += oprot->writeString(this->name); 82 | xfer += oprot->writeFieldEnd(); 83 | 84 | xfer += oprot->writeFieldBegin("age", ::apache::thrift::protocol::T_I16, 3); 85 | xfer += oprot->writeI16(this->age); 86 | xfer += oprot->writeFieldEnd(); 87 | 88 | xfer += oprot->writeFieldStop(); 89 | xfer += oprot->writeStructEnd(); 90 | return xfer; 91 | } 92 | 93 | void swap(Student &a, Student &b) { 94 | using ::std::swap; 95 | swap(a.no, b.no); 96 | swap(a.name, b.name); 97 | swap(a.age, b.age); 98 | swap(a.__isset, b.__isset); 99 | } 100 | 101 | } // namespace 102 | -------------------------------------------------------------------------------- /example_http/student_gen_cpp/student_types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef student_TYPES_H 8 | #define student_TYPES_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | 18 | namespace teststudent { 19 | 20 | typedef struct _Student__isset { 21 | _Student__isset() : no(false), name(false), age(false) {} 22 | bool no; 23 | bool name; 24 | bool age; 25 | } _Student__isset; 26 | 27 | class Student { 28 | public: 29 | 30 | static const char* ascii_fingerprint; // = "52F7D5E8217C4B8FC14F1F30BF2EB41C"; 31 | static const uint8_t binary_fingerprint[16]; // = {0x52,0xF7,0xD5,0xE8,0x21,0x7C,0x4B,0x8F,0xC1,0x4F,0x1F,0x30,0xBF,0x2E,0xB4,0x1C}; 32 | 33 | Student() : no(), name(), age(0) { 34 | } 35 | 36 | virtual ~Student() throw() {} 37 | 38 | std::string no; 39 | std::string name; 40 | int16_t age; 41 | 42 | _Student__isset __isset; 43 | 44 | void __set_no(const std::string& val) { 45 | no = val; 46 | } 47 | 48 | void __set_name(const std::string& val) { 49 | name = val; 50 | } 51 | 52 | void __set_age(const int16_t val) { 53 | age = val; 54 | } 55 | 56 | bool operator == (const Student & rhs) const 57 | { 58 | if (!(no == rhs.no)) 59 | return false; 60 | if (!(name == rhs.name)) 61 | return false; 62 | if (!(age == rhs.age)) 63 | return false; 64 | return true; 65 | } 66 | bool operator != (const Student &rhs) const { 67 | return !(*this == rhs); 68 | } 69 | 70 | bool operator < (const Student & ) const; 71 | 72 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 73 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 74 | 75 | }; 76 | 77 | void swap(Student &a, Student &b); 78 | 79 | } // namespace 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /example_http/valgrind.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | valgrind -v --leak-check=full ./test_ape_http 3 | -------------------------------------------------------------------------------- /example_thrift/Makefile: -------------------------------------------------------------------------------- 1 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 2 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 3 | VER_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo 'X86-64'; else echo 'X86'; fi;)LIB_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo '_X86-64'; else echo ''; fi;) 4 | 5 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 6 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 7 | CC=g++ 8 | VER=1.0.0 9 | XLOG=$(HOME)/local/xlog 10 | THRIFT=$(HOME)/local/thrift 11 | APE=$(HOME)/local/ape 12 | 13 | DIR_LIST=./business ./student_gen_cpp ./main 14 | OutPut=build/ 15 | NEW_CODE_PATH=./ 16 | #SOURCE CODE 17 | CC_SRC=$(shell find $(DIR_LIST) -name "*.cc" ) 18 | CC_SRC2=$(shell find $(DIR_LIST) -name "*.c" ) 19 | CC_SRC3=$(shell find $(DIR_LIST) -name "*.cpp" ) 20 | 21 | #OBJECTS 22 | CC_OBJS=$(patsubst %.cc,./$(OutPut)/%.o,$(CC_SRC)) 23 | CC_OBJS2=$(patsubst %.c,./$(OutPut)/%.o,$(CC_SRC2)) 24 | CC_OBJS3=$(patsubst %.cpp,./$(OutPut)/%.o,$(CC_SRC3)) 25 | OBJS=$(CC_OBJS) 26 | OBJS2=$(CC_OBJS2) 27 | OBJS3=$(CC_OBJS3) 28 | #DEPS 29 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 30 | 31 | define OBJ_MKDIR 32 | OBJ_DIRS+=./$(OutPut)/$(1) 33 | endef 34 | CC_DIRS=$(shell find $(DIR_LIST) -type d|sed -e '/.svn/d') 35 | #@echo $(CC_DIRS) 36 | $(foreach dir,$(CC_DIRS),$(eval $(call OBJ_MKDIR,$(dir)))) 37 | 38 | #DEPS 39 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 40 | INC_DIR= 41 | #INCLUDE DIR 42 | define SAFE_MKDIR 43 | INC_DIR+=-I $(1) 44 | endef 45 | $(foreach dir,$(CC_DIRS),$(eval $(call SAFE_MKDIR,$(dir)))) 46 | 47 | 48 | INC_DIR+=-I/usr/include -I$(XLOG)/include -I$(THRIFT)/include -I$(APE)/include 49 | 50 | #LIB_DIR 51 | 52 | LIB_DIR=-L/usr/local/lib $(XLOG)/lib/libxlog.a -L$(MONGOC)/lib $(THRIFT)/lib/libthrift.a $(APE)/lib/libape.a 53 | #-ltcmalloc 54 | LIBS=-lz -lrt -lboost_thread -lboost_system -lpthread -Wall -ldl -Wl,--export-dynamic 55 | 56 | LDFLAGS=$(LIB_DIR) $(LIBS) 57 | CPPFLAGS=$(INC_DIR) $(DFLAGS) -DTIXML_USE_STL 58 | 59 | EXE1=./test_ape_thrift 60 | 61 | all:$(EXE1) 62 | $(shell mkdir -p $(sort $(OBJ_DIRS))) 63 | include $(DEPS) 64 | 65 | $(EXE1):$(OBJS) $(OBJS2) $(OBJS3) 66 | $(CC) -g -O2 -o $@ $^ $(LDFLAGS) 67 | 68 | 69 | ./$(OutPut)/%.o:%.cc 70 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 71 | ./$(OutPut)/%.d:%.cc 72 | @set -e; rm -f $@; \ 73 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 74 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 75 | rm -f $@.$$$$ 76 | 77 | ./$(OutPut)/%.o:%.cpp 78 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 79 | ./$(OutPut)/%.d:%.cpp 80 | @set -e; rm -f $@; \ 81 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 82 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 83 | rm -f $@.$$$$ 84 | 85 | ./$(OutPut)/%.o:%.c 86 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 87 | ./$(OutPut)/%.d:%.c 88 | @set -e; rm -f $@; \ 89 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 90 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 91 | rm -f $@.$$$$ 92 | 93 | clean: 94 | rm -Rf $(OutPut) 95 | rm -rf $(EXE1) 96 | codelen: 97 | find $(NEW_CODE_PATH) \( -name "*.cc" -name "*.cpp" -o -name "*.h" -o -name "*.c" \) -exec cat {} \;|sed -e 's/\"/\n\"\n/g;s/\([^\/]\)\(\/\*\)/\1\n\2\n/g;'|sed -e '/^\"/{:a;N;/\".*\"/!ba;s/\".*\".*//;N;/\"/!d;b}' -e '/^\/\*/{s/\/\*.*\*\///;/\/\*/{:b;N;/\/\*.*\*\//!bb;s/\/\*.*\*\///}}' -e 's/\/\/.*//g' |sed -e '/^[[:space:]]*$$/d'|wc -l 98 | srczip: 99 | zip -r ./$(EXE1)_src_$(VER).zip * -x *.o *.d *.svn *.zip *.a *.so $(EXE1) *.svn-work *.svn-base *.so.* *.d.* *.svn/* 100 | binzip: 101 | if [ ! -d "release" ]; then mkdir release; fi; 102 | cd release;if [ ! -d "lib" ]; then mkdir lib; fi; 103 | cd release;if [ ! -d "plugin/httptransfer" ]; then mkdir -p plugin/httptransfer; fi; 104 | cd release;if [ ! -d "plugin/rapidtransfer" ]; then mkdir -p plugin/rapidtransfer; fi; 105 | cd release;if [ ! -d "plugin/weaktransfer" ]; then mkdir -p plugin/weaktransfer; fi; 106 | cp ./beacon ./release/ 107 | cp -r ./conf ./release/conf 108 | cp ./run.sh ./release/run.sh 109 | cp $(HOME)/local/json/lib/libjson.so.0.1.0 ./release/lib/libjson.so.0 110 | 111 | ldd ./beacon>sys_so_111_232_876_23;cp `awk '{if(substr($$3,1,4)!="/lib"&&substr($$3,1,8)!="/usr/lib")print $$3}' sys_so_111_232_876_23` ./release/lib/;rm -rf sys_so_111_232_876_23 112 | cd release; zip -r ../Beacon$(VER)_$(OS)_Gcc$(GCC)_X86.zip * 113 | rm -rf release 114 | 115 | EXEDIR=apelus-beacon-server 116 | packet: 117 | if [ ! -d "release/usr/local/$(EXEDIR)" ]; then mkdir -p release/usr/local/$(EXEDIR); fi; 118 | if [ ! -d "release/usr/local/$(EXEDIR)/lib" ]; then mkdir -p release/usr/local/$(EXEDIR)/lib; fi; 119 | if [ ! -d "release/usr/local/$(EXEDIR)/conf" ]; then mkdir -p release/usr/local/$(EXEDIR)/conf; fi; 120 | if [ ! -d "release/usr/local/$(EXEDIR)/plugin" ]; then mkdir -p release/usr/local/$(EXEDIR)/plugin; fi; 121 | 122 | cp $(EXE1) ./release/usr/local/$(EXEDIR)/ 123 | cp ./conf/* ./release/usr/local/$(EXEDIR)/conf/ 124 | cp ./run.sh ./release/usr/local/$(EXEDIR)/ 125 | cp $(HOME)/local/json/lib/libjson.so.0.1.0 ./release/usr/local/$(EXEDIR)/lib/libjson.so.0 126 | cp -r ./plugin/* ./release/usr/local/$(EXEDIR)/plugin/ 127 | cp -r ./dist/DEBIAN ./release/ 128 | cp -r ./dist/etc ./release/ 129 | 130 | chmod -R +x ./release/* 131 | chmod +x ./release/usr/local/$(EXEDIR)/* 132 | chmod 755 ./release/DEBIAN/* 133 | ldd ./$(EXE1)>sys_so_111_232_876_23;cp `awk '{if(substr($$3,1,4)!="/lib"&&substr($$3,1,8)!="/usr/lib")print $$3}' sys_so_111_232_876_23` ./release/usr/local/$(EXEDIR)/lib/;rm -rf sys_so_111_232_876_23 134 | # cd release;tar -czhf ../$(EXE1)_$(VER)_$(OS)_Gcc$(GCC).tar.gz * --exclude=".svn" --exclude=".git" --exclude="*.pyc" --exclude="*.log" 135 | mv release $(EXEDIR)_$(VER)_amd64;tar -czhf ./$(EXEDIR)_$(VER)_amd64.tar.gz $(EXEDIR)_$(VER)_amd64 --exclude=".svn" --exclude=".git" --exclude="*.pyc" --exclude="*.log" 136 | #dpkg --build release/ $(EXE1)-1.0.0_i386.deb 137 | rm -rf $(EXEDIR)_$(VER)_amd64 138 | -------------------------------------------------------------------------------- /example_thrift/business/businesshandle.cc: -------------------------------------------------------------------------------- 1 | #include "businesshandle.h" 2 | #include "Serv.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace ape { 10 | namespace testthrift { 11 | CBusinessHandle::CBusinessHandle() { 12 | } 13 | void CBusinessHandle::StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner) { 14 | threadid_ = threadid; 15 | service_ = service; 16 | timerowner_ = owner; 17 | } 18 | void CBusinessHandle::OnEvent(int threadid, void *event) { 19 | ape::message::SEvent *e = (ape::message::SEvent *)event; 20 | BS_XLOG(XLOG_TRACE,"CBusinessHandle::%s, type[%d], threadid[%d]\n", __FUNCTION__, e->id, threadid); 21 | switch (e->id) { 22 | case ape::message::SThriftMessage::ID: { 23 | ape::message::SThriftMessage * msg = (ape::message::SThriftMessage *)e; 24 | if (!msg->IsReply()) { 25 | DealThriftRequest(msg); 26 | } 27 | delete e; 28 | break; 29 | } 30 | default: { 31 | delete e; 32 | break; 33 | } 34 | } 35 | } 36 | void CBusinessHandle::DealThriftRequest(ape::message::SThriftMessage *message) { 37 | BS_XLOG(XLOG_TRACE,"CBusinessHandle::%s, \n%s\n", __FUNCTION__, message->NoticeInfo().c_str()); 38 | 39 | boost::shared_ptr buf(new apache::thrift::transport::TMemoryBuffer((uint8_t*)(message->body.c_str()), message->body.length())); 40 | boost::shared_ptr pro(new apache::thrift::protocol::TBinaryProtocol(buf)); 41 | teststudent::Serv_QueryByNo_args args; 42 | args.read(pro.get()); 43 | BS_XLOG(XLOG_TRACE,"CBusinessHandle::%s, no[%s]\n", __FUNCTION__, args.no.c_str()); 44 | 45 | teststudent::Serv_QueryByNo_result result; 46 | result.success.no = "0743111245"; 47 | result.success.name = "test_student_xiaozhai"; 48 | result.success.age = 24; 49 | result.__isset.success = true; 50 | 51 | buf.reset(new apache::thrift::transport::TMemoryBuffer(10240)); 52 | buf->open(); 53 | pro.reset(new apache::thrift::protocol::TBinaryProtocol(buf)); 54 | result.write(pro.get()); 55 | 56 | ape::message::SThriftMessage *resmsg = new ape::message::SThriftMessage; 57 | resmsg->method = "QueryByNo"; 58 | resmsg->seqid = message->seqid; 59 | resmsg->body = buf->getBufferAsString(); 60 | resmsg->SetReply(); 61 | service_->DoSendBack(message->connid, resmsg); 62 | } 63 | void CBusinessHandle::Dump() { 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /example_thrift/business/businesshandle.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_MONITOR_BUSINESS_HANDLE_H_ 2 | #define _APE_MONITOR_BUSINESS_HANDLE_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace ape { 10 | namespace testthrift { 11 | class CBusinessHandle : public ape::net::CHandle { 12 | public: 13 | CBusinessHandle(); 14 | virtual ~CBusinessHandle() {} 15 | virtual void StartInThread(int threadid, ape::net::CNetService *service, ape::common::CTimerManager *owner); 16 | virtual void StopInThread(int threadid) {} 17 | virtual void OnEvent(int threadid, void *event); 18 | void Dump(); 19 | private: 20 | void DealThriftRequest(ape::message::SThriftMessage *message); 21 | private: 22 | int threadid_; 23 | ape::net::CNetService *service_; 24 | ape::common::CTimerManager *timerowner_; 25 | }; 26 | } 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /example_thrift/conf/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 4 | 5 | thrift://0.0.0.0:10012 6 | 7 | 8 | -------------------------------------------------------------------------------- /example_thrift/conf/log.properties: -------------------------------------------------------------------------------- 1 | log4cplus.logger.business=WARN,BUSINESS 2 | log4cplus.additivity.business=false 3 | 4 | log4cplus.appender.STDOUT=log4cplus::ConsoleAppender 5 | log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout 6 | log4cplus.appender.STDOUT.layout.ConversionPattern=%-6p[%t][%D{%m/%d/%y %H:%M:%S %Q}]%m 7 | 8 | log4cplus.appender.BUSINESS=log4cplus::RollingFileAppender 9 | log4cplus.appender.BUSINESS.File=./log/all.log 10 | log4cplus.appender.BUSINESS.MaxFileSize=5MB 11 | log4cplus.appender.BUSINESS.MaxBackupIndex=5 12 | log4cplus.appender.BUSINESS.layout=log4cplus::PatternLayout 13 | log4cplus.appender.BUSINESS.layout.ConversionPattern=%-6p[%t] [%D{%m/%d/%y %H:%M:%S %Q}] %m 14 | 15 | -------------------------------------------------------------------------------- /example_thrift/main/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "businesshandle.h" 12 | 13 | #define __TESTAPE__VERSION__ "1.0.0" 14 | #define DEBUG 15 | 16 | void terminate(int signum) { 17 | usleep(500); 18 | _exit(0); 19 | } 20 | 21 | int run(int flag, int argc, char* argv[]) { 22 | XLOG_INIT("./conf/log.properties", true); 23 | XLOG_REGISTER(BUSINESS_MODULE, "business"); 24 | 25 | if (flag != 0) { 26 | BS_XLOG(XLOG_FATAL,"--------reboot!!!--------\n"); 27 | } 28 | const char *configfile = "./conf/config.xml"; 29 | ape::common::CXmlConfigParser parser; 30 | if (0 != parser.ParseFile(configfile)) { 31 | BS_XLOG(XLOG_FATAL,"parse config[%s] failed, error[%s]\n", configfile, parser.GetErrorMessage().c_str()); 32 | return -1; 33 | } 34 | 35 | sigset_t new_mask; 36 | sigfillset(&new_mask); 37 | sigset_t old_mask; 38 | pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); 39 | 40 | std::vector addrs = parser.GetParameters("server/addr"); 41 | ape::net::NetHandleFactory factory; 42 | ape::net::CNetThreadHolder threadholder; 43 | threadholder.Start(&factory, parser.GetParameter("netthread", 3)); 44 | if (0 != threadholder.StartServer(addrs)) { 45 | return -1; 46 | } 47 | 48 | pthread_sigmask(SIG_SETMASK, &old_mask, 0); 49 | signal(SIGTERM, terminate); 50 | 51 | #if 1 52 | char c; 53 | while ( c = getchar()) { 54 | if(c=='q') { 55 | threadholder.Stop(); 56 | XLOG_DESTROY(); 57 | break; 58 | } 59 | else if(c=='p'){ 60 | /** dump */ 61 | } else if(c!='\n') { 62 | BS_XLOG(XLOG_WARNING,"can not regnize char [%c]\n",c); 63 | } 64 | } 65 | #else 66 | while (1){ 67 | sleep(1); 68 | } 69 | #endif 70 | } 71 | 72 | bool process_arg(int argc, char* argv[]) { 73 | char c; 74 | while((c = getopt (argc,argv,"v")) != -1 ) { 75 | switch (c) { 76 | case 'v': 77 | printf("Server version: %s\n", __TESTAPE__VERSION__); 78 | printf("Build time: %s %s\n", __TIME__, __DATE__); 79 | return false; 80 | default: 81 | return true; 82 | } 83 | } 84 | return true; 85 | } 86 | 87 | int main(int argc, char* argv[]) 88 | { 89 | if(!process_arg(argc,argv)) 90 | return 0; 91 | 92 | #ifdef DEBUG 93 | run(0, argc, argv); 94 | #else 95 | if (0 == fork()) { 96 | run(0, argc, argv); 97 | exit(0); 98 | } 99 | 100 | struct timeval begin, end, interval; 101 | gettimeofday(&begin,0); 102 | while (1) { 103 | wait(NULL); 104 | gettimeofday(&end,0); 105 | if(end.tv_sec > begin.tv_sec) { 106 | sleep(1); 107 | if (0 == fork()) { 108 | run(-1, argc, argv); 109 | exit(0); 110 | } 111 | } 112 | } 113 | #endif 114 | return 0; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /example_thrift/student.thrift: -------------------------------------------------------------------------------- 1 | namespace cpp teststudent 2 | 3 | struct Student{ 4 | 1: string no, 5 | 2: string name, 6 | 3: i16 age, 7 | } 8 | service Serv{ 9 | Student QueryByNo(1: string no), 10 | } 11 | -------------------------------------------------------------------------------- /example_thrift/student_gen_cpp/Serv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef Serv_H 8 | #define Serv_H 9 | 10 | #include 11 | #include "student_types.h" 12 | 13 | namespace teststudent { 14 | 15 | class ServIf { 16 | public: 17 | virtual ~ServIf() {} 18 | virtual void QueryByNo(Student& _return, const std::string& no) = 0; 19 | }; 20 | 21 | class ServIfFactory { 22 | public: 23 | typedef ServIf Handler; 24 | 25 | virtual ~ServIfFactory() {} 26 | 27 | virtual ServIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) = 0; 28 | virtual void releaseHandler(ServIf* /* handler */) = 0; 29 | }; 30 | 31 | class ServIfSingletonFactory : virtual public ServIfFactory { 32 | public: 33 | ServIfSingletonFactory(const boost::shared_ptr& iface) : iface_(iface) {} 34 | virtual ~ServIfSingletonFactory() {} 35 | 36 | virtual ServIf* getHandler(const ::apache::thrift::TConnectionInfo&) { 37 | return iface_.get(); 38 | } 39 | virtual void releaseHandler(ServIf* /* handler */) {} 40 | 41 | protected: 42 | boost::shared_ptr iface_; 43 | }; 44 | 45 | class ServNull : virtual public ServIf { 46 | public: 47 | virtual ~ServNull() {} 48 | void QueryByNo(Student& /* _return */, const std::string& /* no */) { 49 | return; 50 | } 51 | }; 52 | 53 | typedef struct _Serv_QueryByNo_args__isset { 54 | _Serv_QueryByNo_args__isset() : no(false) {} 55 | bool no; 56 | } _Serv_QueryByNo_args__isset; 57 | 58 | class Serv_QueryByNo_args { 59 | public: 60 | 61 | Serv_QueryByNo_args() : no() { 62 | } 63 | 64 | virtual ~Serv_QueryByNo_args() throw() {} 65 | 66 | std::string no; 67 | 68 | _Serv_QueryByNo_args__isset __isset; 69 | 70 | void __set_no(const std::string& val) { 71 | no = val; 72 | } 73 | 74 | bool operator == (const Serv_QueryByNo_args & rhs) const 75 | { 76 | if (!(no == rhs.no)) 77 | return false; 78 | return true; 79 | } 80 | bool operator != (const Serv_QueryByNo_args &rhs) const { 81 | return !(*this == rhs); 82 | } 83 | 84 | bool operator < (const Serv_QueryByNo_args & ) const; 85 | 86 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 87 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 88 | 89 | }; 90 | 91 | 92 | class Serv_QueryByNo_pargs { 93 | public: 94 | 95 | 96 | virtual ~Serv_QueryByNo_pargs() throw() {} 97 | 98 | const std::string* no; 99 | 100 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 101 | 102 | }; 103 | 104 | typedef struct _Serv_QueryByNo_result__isset { 105 | _Serv_QueryByNo_result__isset() : success(false) {} 106 | bool success; 107 | } _Serv_QueryByNo_result__isset; 108 | 109 | class Serv_QueryByNo_result { 110 | public: 111 | 112 | Serv_QueryByNo_result() { 113 | } 114 | 115 | virtual ~Serv_QueryByNo_result() throw() {} 116 | 117 | Student success; 118 | 119 | _Serv_QueryByNo_result__isset __isset; 120 | 121 | void __set_success(const Student& val) { 122 | success = val; 123 | } 124 | 125 | bool operator == (const Serv_QueryByNo_result & rhs) const 126 | { 127 | if (!(success == rhs.success)) 128 | return false; 129 | return true; 130 | } 131 | bool operator != (const Serv_QueryByNo_result &rhs) const { 132 | return !(*this == rhs); 133 | } 134 | 135 | bool operator < (const Serv_QueryByNo_result & ) const; 136 | 137 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 138 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 139 | 140 | }; 141 | 142 | typedef struct _Serv_QueryByNo_presult__isset { 143 | _Serv_QueryByNo_presult__isset() : success(false) {} 144 | bool success; 145 | } _Serv_QueryByNo_presult__isset; 146 | 147 | class Serv_QueryByNo_presult { 148 | public: 149 | 150 | 151 | virtual ~Serv_QueryByNo_presult() throw() {} 152 | 153 | Student* success; 154 | 155 | _Serv_QueryByNo_presult__isset __isset; 156 | 157 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 158 | 159 | }; 160 | 161 | class ServClient : virtual public ServIf { 162 | public: 163 | ServClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) : 164 | piprot_(prot), 165 | poprot_(prot) { 166 | iprot_ = prot.get(); 167 | oprot_ = prot.get(); 168 | } 169 | ServClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) : 170 | piprot_(iprot), 171 | poprot_(oprot) { 172 | iprot_ = iprot.get(); 173 | oprot_ = oprot.get(); 174 | } 175 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() { 176 | return piprot_; 177 | } 178 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() { 179 | return poprot_; 180 | } 181 | void QueryByNo(Student& _return, const std::string& no); 182 | void send_QueryByNo(const std::string& no); 183 | void recv_QueryByNo(Student& _return); 184 | protected: 185 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot_; 186 | boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot_; 187 | ::apache::thrift::protocol::TProtocol* iprot_; 188 | ::apache::thrift::protocol::TProtocol* oprot_; 189 | }; 190 | 191 | class ServProcessor : public ::apache::thrift::TDispatchProcessor { 192 | protected: 193 | boost::shared_ptr iface_; 194 | virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext); 195 | private: 196 | typedef void (ServProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*); 197 | typedef std::map ProcessMap; 198 | ProcessMap processMap_; 199 | void process_QueryByNo(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext); 200 | public: 201 | ServProcessor(boost::shared_ptr iface) : 202 | iface_(iface) { 203 | processMap_["QueryByNo"] = &ServProcessor::process_QueryByNo; 204 | } 205 | 206 | virtual ~ServProcessor() {} 207 | }; 208 | 209 | class ServProcessorFactory : public ::apache::thrift::TProcessorFactory { 210 | public: 211 | ServProcessorFactory(const ::boost::shared_ptr< ServIfFactory >& handlerFactory) : 212 | handlerFactory_(handlerFactory) {} 213 | 214 | ::boost::shared_ptr< ::apache::thrift::TProcessor > getProcessor(const ::apache::thrift::TConnectionInfo& connInfo); 215 | 216 | protected: 217 | ::boost::shared_ptr< ServIfFactory > handlerFactory_; 218 | }; 219 | 220 | class ServMultiface : virtual public ServIf { 221 | public: 222 | ServMultiface(std::vector >& ifaces) : ifaces_(ifaces) { 223 | } 224 | virtual ~ServMultiface() {} 225 | protected: 226 | std::vector > ifaces_; 227 | ServMultiface() {} 228 | void add(boost::shared_ptr iface) { 229 | ifaces_.push_back(iface); 230 | } 231 | public: 232 | void QueryByNo(Student& _return, const std::string& no) { 233 | size_t sz = ifaces_.size(); 234 | size_t i = 0; 235 | for (; i < (sz - 1); ++i) { 236 | ifaces_[i]->QueryByNo(_return, no); 237 | } 238 | ifaces_[i]->QueryByNo(_return, no); 239 | return; 240 | } 241 | 242 | }; 243 | 244 | } // namespace 245 | 246 | #endif 247 | -------------------------------------------------------------------------------- /example_thrift/student_gen_cpp/student_constants.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #include "student_constants.h" 8 | 9 | namespace teststudent { 10 | 11 | const studentConstants g_student_constants; 12 | 13 | studentConstants::studentConstants() { 14 | } 15 | 16 | } // namespace 17 | 18 | -------------------------------------------------------------------------------- /example_thrift/student_gen_cpp/student_constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef student_CONSTANTS_H 8 | #define student_CONSTANTS_H 9 | 10 | #include "student_types.h" 11 | 12 | namespace teststudent { 13 | 14 | class studentConstants { 15 | public: 16 | studentConstants(); 17 | 18 | }; 19 | 20 | extern const studentConstants g_student_constants; 21 | 22 | } // namespace 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /example_thrift/student_gen_cpp/student_types.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #include "student_types.h" 8 | 9 | #include 10 | 11 | namespace teststudent { 12 | 13 | const char* Student::ascii_fingerprint = "52F7D5E8217C4B8FC14F1F30BF2EB41C"; 14 | const uint8_t Student::binary_fingerprint[16] = {0x52,0xF7,0xD5,0xE8,0x21,0x7C,0x4B,0x8F,0xC1,0x4F,0x1F,0x30,0xBF,0x2E,0xB4,0x1C}; 15 | 16 | uint32_t Student::read(::apache::thrift::protocol::TProtocol* iprot) { 17 | 18 | uint32_t xfer = 0; 19 | std::string fname; 20 | ::apache::thrift::protocol::TType ftype; 21 | int16_t fid; 22 | 23 | xfer += iprot->readStructBegin(fname); 24 | 25 | using ::apache::thrift::protocol::TProtocolException; 26 | 27 | 28 | while (true) 29 | { 30 | xfer += iprot->readFieldBegin(fname, ftype, fid); 31 | if (ftype == ::apache::thrift::protocol::T_STOP) { 32 | break; 33 | } 34 | switch (fid) 35 | { 36 | case 1: 37 | if (ftype == ::apache::thrift::protocol::T_STRING) { 38 | xfer += iprot->readString(this->no); 39 | this->__isset.no = true; 40 | } else { 41 | xfer += iprot->skip(ftype); 42 | } 43 | break; 44 | case 2: 45 | if (ftype == ::apache::thrift::protocol::T_STRING) { 46 | xfer += iprot->readString(this->name); 47 | this->__isset.name = true; 48 | } else { 49 | xfer += iprot->skip(ftype); 50 | } 51 | break; 52 | case 3: 53 | if (ftype == ::apache::thrift::protocol::T_I16) { 54 | xfer += iprot->readI16(this->age); 55 | this->__isset.age = true; 56 | } else { 57 | xfer += iprot->skip(ftype); 58 | } 59 | break; 60 | default: 61 | xfer += iprot->skip(ftype); 62 | break; 63 | } 64 | xfer += iprot->readFieldEnd(); 65 | } 66 | 67 | xfer += iprot->readStructEnd(); 68 | 69 | return xfer; 70 | } 71 | 72 | uint32_t Student::write(::apache::thrift::protocol::TProtocol* oprot) const { 73 | uint32_t xfer = 0; 74 | xfer += oprot->writeStructBegin("Student"); 75 | 76 | xfer += oprot->writeFieldBegin("no", ::apache::thrift::protocol::T_STRING, 1); 77 | xfer += oprot->writeString(this->no); 78 | xfer += oprot->writeFieldEnd(); 79 | 80 | xfer += oprot->writeFieldBegin("name", ::apache::thrift::protocol::T_STRING, 2); 81 | xfer += oprot->writeString(this->name); 82 | xfer += oprot->writeFieldEnd(); 83 | 84 | xfer += oprot->writeFieldBegin("age", ::apache::thrift::protocol::T_I16, 3); 85 | xfer += oprot->writeI16(this->age); 86 | xfer += oprot->writeFieldEnd(); 87 | 88 | xfer += oprot->writeFieldStop(); 89 | xfer += oprot->writeStructEnd(); 90 | return xfer; 91 | } 92 | 93 | void swap(Student &a, Student &b) { 94 | using ::std::swap; 95 | swap(a.no, b.no); 96 | swap(a.name, b.name); 97 | swap(a.age, b.age); 98 | swap(a.__isset, b.__isset); 99 | } 100 | 101 | } // namespace 102 | -------------------------------------------------------------------------------- /example_thrift/student_gen_cpp/student_types.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Autogenerated by Thrift Compiler (0.9.1) 3 | * 4 | * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 5 | * @generated 6 | */ 7 | #ifndef student_TYPES_H 8 | #define student_TYPES_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | 18 | namespace teststudent { 19 | 20 | typedef struct _Student__isset { 21 | _Student__isset() : no(false), name(false), age(false) {} 22 | bool no; 23 | bool name; 24 | bool age; 25 | } _Student__isset; 26 | 27 | class Student { 28 | public: 29 | 30 | static const char* ascii_fingerprint; // = "52F7D5E8217C4B8FC14F1F30BF2EB41C"; 31 | static const uint8_t binary_fingerprint[16]; // = {0x52,0xF7,0xD5,0xE8,0x21,0x7C,0x4B,0x8F,0xC1,0x4F,0x1F,0x30,0xBF,0x2E,0xB4,0x1C}; 32 | 33 | Student() : no(), name(), age(0) { 34 | } 35 | 36 | virtual ~Student() throw() {} 37 | 38 | std::string no; 39 | std::string name; 40 | int16_t age; 41 | 42 | _Student__isset __isset; 43 | 44 | void __set_no(const std::string& val) { 45 | no = val; 46 | } 47 | 48 | void __set_name(const std::string& val) { 49 | name = val; 50 | } 51 | 52 | void __set_age(const int16_t val) { 53 | age = val; 54 | } 55 | 56 | bool operator == (const Student & rhs) const 57 | { 58 | if (!(no == rhs.no)) 59 | return false; 60 | if (!(name == rhs.name)) 61 | return false; 62 | if (!(age == rhs.age)) 63 | return false; 64 | return true; 65 | } 66 | bool operator != (const Student &rhs) const { 67 | return !(*this == rhs); 68 | } 69 | 70 | bool operator < (const Student & ) const; 71 | 72 | uint32_t read(::apache::thrift::protocol::TProtocol* iprot); 73 | uint32_t write(::apache::thrift::protocol::TProtocol* oprot) const; 74 | 75 | }; 76 | 77 | void swap(Student &a, Student &b); 78 | 79 | } // namespace 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /frame/Makefile: -------------------------------------------------------------------------------- 1 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 2 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 3 | VER_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo 'X86-64'; else echo 'X86'; fi;)LIB_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo '_X86-64'; else echo ''; fi;) 4 | 5 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 6 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 7 | CC=g++ 8 | VER=1.0.0 9 | XLOG=$(HOME)/local/xlog 10 | BOOST=$(HOME)/local/boost 11 | 12 | INSTALLDIR=$(HOME)/local/ape 13 | 14 | DIR_LIST=./common ./interface ./net ./protocol ./session ./tinyxml2 ./event ./compressutil 15 | OutPut=build/ 16 | NEW_CODE_PATH=./ 17 | #SOURCE CODE 18 | CC_SRC=$(shell find $(DIR_LIST) -name "*.cc" ) 19 | CC_SRC2=$(shell find $(DIR_LIST) -name "*.c" ) 20 | CC_SRC3=$(shell find $(DIR_LIST) -name "*.cpp" ) 21 | 22 | #OBJECTS 23 | CC_OBJS=$(patsubst %.cc,./$(OutPut)/%.o,$(CC_SRC)) 24 | CC_OBJS2=$(patsubst %.c,./$(OutPut)/%.o,$(CC_SRC2)) 25 | CC_OBJS3=$(patsubst %.cpp,./$(OutPut)/%.o,$(CC_SRC3)) 26 | OBJS=$(CC_OBJS) 27 | OBJS2=$(CC_OBJS2) 28 | OBJS3=$(CC_OBJS3) 29 | #DEPS 30 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 31 | 32 | define OBJ_MKDIR 33 | OBJ_DIRS+=./$(OutPut)/$(1) 34 | endef 35 | CC_DIRS=$(shell find $(DIR_LIST) -type d|sed -e '/.svn/d') 36 | #@echo $(CC_DIRS) 37 | $(foreach dir,$(CC_DIRS),$(eval $(call OBJ_MKDIR,$(dir)))) 38 | 39 | #DEPS 40 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 41 | INC_DIR= 42 | #INCLUDE DIR 43 | define SAFE_MKDIR 44 | INC_DIR+=-I $(1) 45 | endef 46 | $(foreach dir,$(CC_DIRS),$(eval $(call SAFE_MKDIR,$(dir)))) 47 | 48 | 49 | INC_DIR+=-I/usr/include -I$(XLOG)/include -I$(BOOST)/include 50 | 51 | #LIB_DIR 52 | 53 | LIB_DIR=-L/usr/local/lib 54 | #-ltcmalloc 55 | LIBS=-Wall, --export-dynamic 56 | 57 | LDFLAGS=$(LIB_DIR) $(LIBS) 58 | CPPFLAGS=$(INC_DIR) $(DFLAGS) -DTIXML_USE_STL 59 | CFLAGS= -g -O0 -fPIC 60 | 61 | EXE1=$(OutPut)/libape.a 62 | 63 | all:$(EXE1) 64 | $(shell mkdir -p $(sort $(OBJ_DIRS))) 65 | include $(DEPS) 66 | 67 | $(EXE1):$(OBJS) $(OBJS2) $(OBJS3) 68 | ar -r $@ ./build/*/*.o 69 | 70 | ./$(OutPut)/%.o:%.cc 71 | $(CC) -o $@ $(CFLAGS) -c $< $(CPPFLAGS) #2> output 72 | ./$(OutPut)/%.d:%.cc 73 | @set -e; rm -f $@; \ 74 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 75 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 76 | rm -f $@.$$$$ 77 | 78 | ./$(OutPut)/%.o:%.cpp 79 | $(CC) -o $@ $(CFLAGS) -c $< $(CPPFLAGS) #2> output 80 | ./$(OutPut)/%.d:%.cpp 81 | @set -e; rm -f $@; \ 82 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 83 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 84 | rm -f $@.$$$$ 85 | 86 | ./$(OutPut)/%.o:%.c 87 | $(CC) -o $@ $(CFLAGS) -c $< $(CPPFLAGS) #2> output 88 | ./$(OutPut)/%.d:%.c 89 | @set -e; rm -f $@; \ 90 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 91 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 92 | rm -f $@.$$$$ 93 | 94 | clean: 95 | rm -Rf $(OutPut) 96 | rm -rf $(EXE1) 97 | codelen: 98 | find $(NEW_CODE_PATH) \( -name "*.cc" -name "*.cpp" -o -name "*.h" -o -name "*.c" \) -exec cat {} \;|sed -e 's/\"/\n\"\n/g;s/\([^\/]\)\(\/\*\)/\1\n\2\n/g;'|sed -e '/^\"/{:a;N;/\".*\"/!ba;s/\".*\".*//;N;/\"/!d;b}' -e '/^\/\*/{s/\/\*.*\*\///;/\/\*/{:b;N;/\/\*.*\*\//!bb;s/\/\*.*\*\///}}' -e 's/\/\/.*//g' |sed -e '/^[[:space:]]*$$/d'|wc -l 99 | srczip: 100 | zip -r ./$(EXE1)_src_$(VER).zip * -x *.o *.d *.svn *.zip *.a *.so $(EXE1) *.svn-work *.svn-base *.so.* *.d.* *.svn/* 101 | install: 102 | if [ ! -d $(INSTALLDIR)/include/ape ]; then mkdir -p $(INSTALLDIR)/include/ape; fi; 103 | if [ ! -d $(INSTALLDIR)/lib ]; then mkdir -p $(INSTALLDIR)/lib; fi; 104 | cp ./common/*.h $(INSTALLDIR)/include/ape/ 105 | cp ./interface/*.h $(INSTALLDIR)/include/ape/ 106 | cp ./tinyxml2/*.h $(INSTALLDIR)/include/ape/ 107 | cp ./net/netthreadholder.h $(INSTALLDIR)/include/ape/ 108 | cp ./net/netservice.h $(INSTALLDIR)/include/ape/ 109 | cp ./net/sessioncallback.h $(INSTALLDIR)/include/ape/ 110 | cp ./event/*.h $(INSTALLDIR)/include/ape/ 111 | cp ./protocol/*.h $(INSTALLDIR)/include/ape/ 112 | cp $(EXE1) $(INSTALLDIR)/lib 113 | -------------------------------------------------------------------------------- /frame/common/dirreader.cc: -------------------------------------------------------------------------------- 1 | #include "dirreader.h" 2 | #include 3 | #include "loghelper.h" 4 | 5 | namespace ape { 6 | namespace common { 7 | CDirReader::CDirReader(const char* filter) : currentindex_(0) { 8 | filter_ = (filter == NULL || filter[0] == 0) ? "*" : filter; 9 | } 10 | CDirReader::~CDirReader(){ } 11 | bool CDirReader::GetNextFilePath(char *filename) { 12 | if (filenames_.empty() || currentindex_ >= filenames_.size()) 13 | return false; 14 | snprintf(filename, 255, "%s", filenames_.at(currentindex_++).c_str()); 15 | return true; 16 | } 17 | bool CDirReader::GetFirstFilePath(char *filename) { 18 | if (filenames_.empty()) 19 | return false; 20 | currentindex_ = 0; 21 | snprintf(filename, 255, "%s", filenames_.at(currentindex_++).c_str()); 22 | return true; 23 | } 24 | bool CDirReader::OpenDir(const char* path) { 25 | if (access(path,0) < 0) { 26 | return false; 27 | } 28 | ReadFiles(path); 29 | return true; 30 | } 31 | void CDirReader::ReadFiles(const char *path) { 32 | struct dirent *pdirent; 33 | struct stat statbuf; 34 | DIR *dir = opendir(path); 35 | if (NULL == dir) { 36 | BS_XLOG(XLOG_WARNING,"CDirReader::%s, open dir error. path[%s]\n", __FUNCTION__, path); 37 | return; 38 | } 39 | 40 | while (NULL != (pdirent = readdir(dir))) { 41 | if ((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))) 42 | continue; 43 | 44 | std::string filepath = path; 45 | if (filepath.at(filepath.length()-1) != '/') { 46 | filepath.append("/"); 47 | } 48 | filepath.append(pdirent->d_name); 49 | if(0 > stat(filepath.c_str(), &statbuf)) { 50 | BS_XLOG(XLOG_WARNING, "CDirReader::%s. stat file error: %s\n", __FUNCTION__, filepath.c_str()); 51 | continue; 52 | } 53 | 54 | if(S_ISDIR(statbuf.st_mode)) { 55 | ReadFiles(filepath.c_str()); 56 | } else { 57 | //BS_XLOG(XLOG_TRACE,"CDirReader::%s. fileName[%s]\n",__FUNCTION__, filepath.c_str()); 58 | if (filter_.empty() || 0 == fnmatch(filter_.c_str(), pdirent->d_name, FNM_PATHNAME|FNM_PERIOD)) { 59 | //BS_XLOG(XLOG_TRACE,"CDirReader::%s. matched fileName[%s]\n",__FUNCTION__, filepath.c_str()); 60 | filenames_.push_back(filepath); 61 | } 62 | } 63 | } 64 | closedir(dir); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /frame/common/dirreader.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_DIR_READER_H 2 | #define _APE_COMMON_DIR_READER_H 3 | 4 | #include 5 | #ifndef WIN32 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #else 12 | #include 13 | #include 14 | #endif 15 | 16 | #ifndef WIN32 17 | #define MAX_PATH 256 18 | #endif 19 | 20 | #include 21 | #include 22 | namespace ape { 23 | namespace common { 24 | class CDirReader { 25 | public: 26 | CDirReader(const char* filter = NULL); 27 | virtual ~CDirReader(); 28 | public: 29 | bool OpenDir(const char* path); 30 | bool GetFirstFilePath(char *filename); 31 | bool GetNextFilePath(char *filename); 32 | private: 33 | void ReadFiles(const char*path); 34 | private: 35 | std::string path_; 36 | std::string filter_; 37 | std::vector filenames_; 38 | unsigned int currentindex_; 39 | }; 40 | } 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /frame/common/msgqueueprio.cc: -------------------------------------------------------------------------------- 1 | #include "msgqueueprio.h" 2 | #include "loghelper.h" 3 | namespace ape { 4 | namespace common { 5 | MsgQueuePrio::MsgQueuePrio(int num_highqueuesize,int num_mediumqueuesize,int num_lowqueuesize):waitinggetthreadnum_(0) { 6 | queue_ = (MsgQueue *)malloc(MSG_PRIO_MAX * sizeof(MsgQueue)); 7 | new(&queue_[MSG_HIGH]) MsgQueue(num_highqueuesize); 8 | new(&queue_[MSG_MEDIUM]) MsgQueue(num_mediumqueuesize); 9 | new(&queue_[MSG_LOW]) MsgQueue(num_lowqueuesize); 10 | } 11 | MsgQueuePrio::~MsgQueuePrio() { 12 | queue_[MSG_HIGH].~MsgQueue(); 13 | queue_[MSG_MEDIUM].~MsgQueue(); 14 | queue_[MSG_LOW].~MsgQueue(); 15 | free(queue_); 16 | } 17 | bool MsgQueuePrio::PutQ(void *pdata, int num_seconds, EMsgPriority en_prio) { 18 | MsgQueue *p_queue = &(queue_[en_prio]); 19 | boost::unique_lock lock(m_mut); 20 | while (p_queue->IsFull()) { 21 | if (num_seconds == 0) { 22 | p_queue->waitingputthreadnum++; 23 | p_queue->cond_put.wait(lock); 24 | p_queue->waitingputthreadnum--; 25 | } else { 26 | p_queue->waitingputthreadnum++; 27 | if (p_queue->cond_put.timed_wait(lock,boost::posix_time::seconds(num_seconds))==false) { 28 | p_queue->waitingputthreadnum--; 29 | return false; 30 | } 31 | p_queue->waitingputthreadnum--; 32 | } 33 | } 34 | p_queue->ppbuf[p_queue->putloc++] = pdata; 35 | ++(p_queue->datasize); 36 | if (p_queue->putloc == p_queue->capacity) { 37 | p_queue->putloc=0; 38 | } 39 | if(waitinggetthreadnum_) { 40 | cond_get_.notify_one(); 41 | } 42 | return true; 43 | } 44 | void *MsgQueuePrio::GetQ(int num_seconds) { 45 | void *pdata = NULL; 46 | MsgQueue *p_queue = NULL; 47 | boost::unique_lock lock(m_mut); 48 | while(p_queue == NULL) { 49 | if (!queue_[MSG_HIGH].IsEmpty()) { 50 | p_queue = &(queue_[MSG_HIGH]); 51 | } 52 | else if(!queue_[MSG_MEDIUM].IsEmpty()) { 53 | p_queue = &(queue_[MSG_MEDIUM]); 54 | } 55 | else if(!queue_[MSG_LOW].IsEmpty()) { 56 | p_queue = &(queue_[MSG_LOW]); 57 | } 58 | if (p_queue != NULL) { 59 | pdata = p_queue->ppbuf[p_queue->getloc++]; 60 | --(p_queue->datasize); 61 | if (p_queue->getloc == p_queue->capacity) { 62 | p_queue->getloc = 0; 63 | } 64 | if (p_queue->waitingputthreadnum) { 65 | p_queue->cond_put.notify_one(); 66 | } 67 | return pdata; 68 | } else { 69 | if (num_seconds == 0) { 70 | waitinggetthreadnum_++; 71 | cond_get_.wait(lock); 72 | waitinggetthreadnum_--; 73 | } else { 74 | waitinggetthreadnum_++; 75 | if(cond_get_.timed_wait(lock,boost::posix_time::seconds(num_seconds)) == false) { 76 | waitinggetthreadnum_--; 77 | return NULL; 78 | } 79 | waitinggetthreadnum_--; 80 | } 81 | } 82 | } 83 | return NULL; 84 | } 85 | int MsgQueuePrio::GetCapacity(EMsgPriority en_prio) { 86 | return queue_[en_prio].capacity; 87 | } 88 | int MsgQueuePrio::GetUsed(EMsgPriority en_prio) { 89 | return queue_[en_prio].datasize; 90 | } 91 | bool MsgQueuePrio::IsEmpty() { 92 | return queue_[MSG_HIGH].IsEmpty() && queue_[MSG_MEDIUM].IsEmpty() && queue_[MSG_LOW].IsEmpty(); 93 | } 94 | 95 | void MsgQueuePrio::Dump() { 96 | BS_XLOG(XLOG_DEBUG, "==========MsgQueuePrio::Dump==========\n"); 97 | boost::unique_lock lock(m_mut); 98 | BS_XLOG(XLOG_DEBUG, " high_queue: capacity[%d], datasize[%d], putloc[%d], getloc[%d]\n", 99 | queue_[MSG_HIGH].capacity, queue_[MSG_HIGH].datasize, queue_[MSG_HIGH].putloc, 100 | queue_[MSG_HIGH].getloc); 101 | BS_XLOG(XLOG_DEBUG, " middle_queue: capacity[%d], datasize[%d], putloc[%d], getloc[%d]\n", 102 | queue_[MSG_MEDIUM].capacity, queue_[MSG_MEDIUM].datasize, queue_[MSG_MEDIUM].putloc, 103 | queue_[MSG_MEDIUM].getloc); 104 | BS_XLOG(XLOG_DEBUG, " low_queue: capacity[%d], datasize[%d], putloc[%d], getloc[%d]\n", 105 | queue_[MSG_LOW].capacity, queue_[MSG_LOW].datasize, queue_[MSG_LOW].putloc, 106 | queue_[MSG_LOW].getloc); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /frame/common/msgqueueprio.h: -------------------------------------------------------------------------------- 1 | #ifndef APE_COMMON_MSG_QUEUE_PIRO_H_ 2 | #define APE_COMMON_MSG_QUEUE_PIRO_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ape { 9 | namespace common { 10 | #define DEFAULT_MEDIUMQUEUESIZE 1024*1024 11 | 12 | class MsgQueuePrio { 13 | public: 14 | typedef enum emMsgPriority { 15 | MSG_HIGH=0, 16 | MSG_MEDIUM=1, 17 | MSG_LOW=2, 18 | MSG_PRIO_MAX 19 | }EMsgPriority; 20 | typedef struct stMsgQueue { 21 | boost::condition_variable cond_put; 22 | void **ppbuf; 23 | int capacity; 24 | int datasize; 25 | int putloc; 26 | int getloc; 27 | int waitingputthreadnum; 28 | 29 | stMsgQueue(int size):capacity(size),datasize(0),putloc(0),getloc(0),waitingputthreadnum(0){ ppbuf = new void *[size]; } 30 | ~stMsgQueue(){ delete []ppbuf; } 31 | bool IsFull() { return capacity == datasize;} 32 | bool IsEmpty() { return datasize <= 0;} 33 | }MsgQueue; 34 | public: 35 | MsgQueuePrio(int num_highqueuesize=512,int num_mediumqueuesize=DEFAULT_MEDIUMQUEUESIZE,int num_lowqueuesize=512); 36 | ~MsgQueuePrio(); 37 | bool PutQ(void *pdata, int num_seconds = 0, EMsgPriority en_prio = MSG_MEDIUM); 38 | void *GetQ(int num_seconds = 1); 39 | int GetCapacity(EMsgPriority en_prio = MSG_MEDIUM); 40 | int GetUsed(EMsgPriority en_prio = MSG_MEDIUM); 41 | bool IsEmpty(); 42 | void Dump(); 43 | private: 44 | MsgQueue *queue_; 45 | 46 | int waitinggetthreadnum_; 47 | boost::condition_variable cond_get_; 48 | boost::mutex m_mut; 49 | }; 50 | } 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /frame/common/msgtimerthread.cc: -------------------------------------------------------------------------------- 1 | #include "msgtimerthread.h" 2 | #include "loghelper.h" 3 | 4 | namespace ape { 5 | namespace common { 6 | MsgTimerThread::MsgTimerThread():self_priority_(true), is_running_(false), public_queue_(NULL) {} 7 | MsgTimerThread::MsgTimerThread(MsgQueuePrio *public_queue, bool self_priority) : self_priority_(self_priority), is_running_(false), public_queue_(public_queue) {} 8 | MsgTimerThread::~MsgTimerThread() {} 9 | 10 | void MsgTimerThread::Start() { 11 | thread_ = boost::thread(boost::bind(&MsgTimerThread::Run,this)); 12 | } 13 | void MsgTimerThread::Stop() { 14 | is_running_ = false; 15 | //thread_.interrupt(); 16 | thread_.join(); 17 | } 18 | bool MsgTimerThread::PutQ(void *pdata, int num_seconds, MsgQueuePrio::EMsgPriority en_prio) { 19 | return queue_.PutQ(pdata, num_seconds, en_prio); 20 | } 21 | void MsgTimerThread::Run() { 22 | is_running_ = true; 23 | StartInThread(); 24 | void *pdata = NULL; 25 | 26 | while (1) { 27 | if (self_priority_) { 28 | if(public_queue_ != NULL && !public_queue_->IsEmpty()) 29 | { 30 | pdata = public_queue_->GetQ(1); 31 | if(pdata!=NULL) 32 | Deal(pdata); 33 | } 34 | pdata = queue_.GetQ(1); 35 | if(pdata != NULL) { 36 | Deal(pdata); 37 | } 38 | } else { 39 | if(!queue_.IsEmpty()) 40 | { 41 | pdata = queue_.GetQ(1); 42 | if(pdata!=NULL) 43 | Deal(pdata); 44 | } 45 | if (public_queue_ != NULL) { 46 | pdata = public_queue_->GetQ(1); 47 | if (pdata) { 48 | Deal(pdata); 49 | } 50 | } 51 | } 52 | if (!is_running_) { 53 | StopInThread(); 54 | break; 55 | } 56 | DetectTimerList(); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /frame/common/msgtimerthread.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_MSG_TIMERTHREAD_H_ 2 | #define _APE_COMMON_MSG_TIMERTHREAD_H_ 3 | #include "msgqueueprio.h" 4 | #include "timermanager.h" 5 | #include 6 | 7 | namespace ape { 8 | namespace common { 9 | class MsgTimerThread : public CTimerManager { 10 | public: 11 | MsgTimerThread(); 12 | MsgTimerThread(MsgQueuePrio *public_queue, bool self_priority = false); 13 | virtual ~MsgTimerThread(); 14 | 15 | void Start(); 16 | void Stop(); 17 | bool IsRunning() {return is_running_;} 18 | bool PutQ(void *pdata, int num_seconds = 0, MsgQueuePrio::EMsgPriority en_prio = MsgQueuePrio::MSG_MEDIUM); 19 | virtual void StartInThread() {} 20 | virtual void StopInThread() {} 21 | virtual void Deal(void *pdata) {} 22 | virtual void Dump() {CTimerManager::Dump();} 23 | 24 | private: 25 | void Run(); 26 | 27 | private: 28 | boost::thread thread_; 29 | bool self_priority_; 30 | volatile bool is_running_; 31 | MsgQueuePrio queue_; 32 | MsgQueuePrio *public_queue_; 33 | }; 34 | } 35 | } 36 | 37 | #endif -------------------------------------------------------------------------------- /frame/common/soloader.cc: -------------------------------------------------------------------------------- 1 | #include "soloader.h" 2 | #include "loghelper.h" 3 | #include "dirreader.h" 4 | #include 5 | 6 | namespace ape { 7 | namespace common { 8 | #ifdef WIN32 9 | #define CST_PATH_SEP "\\" 10 | #else 11 | #define CST_PATH_SEP "/" 12 | #endif 13 | 14 | #ifndef MAX_PATH 15 | #define MAX_PATH 256 16 | #endif 17 | 18 | 19 | int CSoLoader::Load(const std::string &strdir, const std::string &strfilter, std::vector &vecunit) { 20 | BS_XLOG(XLOG_DEBUG,"CSoLoader::%s, dir[%s],filter[%s]\n",__FUNCTION__,strdir.c_str(),strfilter.c_str()); 21 | CDirReader oDirReader(strfilter.c_str()); 22 | if(!oDirReader.OpenDir(strdir.c_str())) { 23 | BS_XLOG(XLOG_DEBUG,"CSoLoader::%s,open dir error[%s]\n",__FUNCTION__,strdir.c_str()); 24 | return -1; 25 | } 26 | 27 | char szfilename[MAX_PATH] = {0}; 28 | 29 | if(!oDirReader.GetFirstFilePath(szfilename)) { 30 | BS_XLOG(XLOG_DEBUG,"CSoLoader::%s,GetFirstFilePath error, dir[%s]\n",__FUNCTION__,strdir.c_str()); 31 | return 0; 32 | } 33 | 34 | do { 35 | SSoUnit sounit; 36 | if(0 != GetSoUnit(szfilename,sounit)) { 37 | BS_XLOG(XLOG_ERROR,"CSoLoader::%s,GetSoUnit[%s] error\n",__FUNCTION__,szfilename); 38 | continue; 39 | } 40 | vecunit.push_back(sounit); 41 | }while(oDirReader.GetNextFilePath(szfilename)); 42 | 43 | return 0; 44 | } 45 | 46 | 47 | int CSoLoader::GetSoUnit(const char *szsoname, SSoUnit &sounit) { 48 | BS_XLOG(XLOG_DEBUG,"CSoLoader::%s, SoName[%s]\n",__FUNCTION__,szsoname); 49 | 50 | void *handle = NULL; 51 | if(NULL == (handle = dlopen(szsoname, RTLD_LAZY))) { 52 | BS_XLOG(XLOG_ERROR,"CSoLoader::%s,dlopen[%s] error[%s]\n", __FUNCTION__,szsoname,dlerror()); 53 | return -1; 54 | } 55 | 56 | create_obj create_unit = (create_obj)dlsym(handle, "create"); 57 | char* dlsym_error = dlerror(); 58 | if (dlsym_error) { 59 | BS_XLOG(XLOG_ERROR,"CSoLoader::%s,dlsym create[%s] error[%s]\n",__FUNCTION__,szsoname,dlsym_error); 60 | return -1; 61 | } 62 | 63 | destroy_obj destroy_unit = (destroy_obj)dlsym(handle, "destroy"); 64 | dlsym_error = dlerror(); 65 | if (dlsym_error) { 66 | BS_XLOG(XLOG_ERROR,"CSoLoader::%s,dlsym destroy[%s] error[%s]\n",__FUNCTION__,szsoname,dlsym_error); 67 | return -1; 68 | } 69 | 70 | sounit.strsoname = szsoname; 71 | sounit.phandle = handle; 72 | sounit.pfuncreate = create_unit; 73 | sounit.pfundestroy = destroy_unit; 74 | 75 | return 0; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /frame/common/soloader.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_SO_LODER_H_ 2 | #define _APE_COMMON_SO_LODER_H_ 3 | 4 | #include 5 | #include 6 | 7 | namespace ape { 8 | namespace common { 9 | 10 | typedef void *(*create_obj)(int nthreadid); 11 | typedef void (*destroy_obj)(void*); 12 | 13 | typedef struct stSoUnit { 14 | std::string strsoname; 15 | void *phandle; 16 | create_obj pfuncreate; 17 | destroy_obj pfundestroy; 18 | 19 | stSoUnit(const std::string &strname, create_obj funcreate, destroy_obj fundestroy) { 20 | phandle = NULL; 21 | strsoname = strname; 22 | pfuncreate = funcreate; 23 | pfundestroy = fundestroy; 24 | } 25 | stSoUnit():phandle(NULL),pfuncreate(NULL),pfundestroy(NULL){} 26 | }SSoUnit; 27 | 28 | template 29 | struct SSoClassInfo { 30 | std::string strsoname; 31 | Interface* pobj; 32 | destroy_obj pfundestroy; 33 | 34 | SSoClassInfo(const std::string &strname, Interface* obj, destroy_obj fundestroy) { 35 | strsoname = strname; 36 | pobj = obj; 37 | pfundestroy = fundestroy; 38 | } 39 | SSoClassInfo():pobj(NULL),pfundestroy(NULL){} 40 | }; 41 | 42 | 43 | class CSoLoader 44 | { 45 | public: 46 | int Load(const std::string &strdir, const std::string &strfilter, std::vector &vecunit); 47 | 48 | private: 49 | int GetSoUnit(const char *szsoname, SSoUnit &sounit); 50 | }; 51 | } 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /frame/common/threadtimer.cc: -------------------------------------------------------------------------------- 1 | #include "threadtimer.h" 2 | #include 3 | #include "loghelper.h" 4 | 5 | namespace ape { 6 | namespace common { 7 | CThreadTimer::~CThreadTimer() { 8 | //BS_XLOG(XLOG_DEBUG, "CTimerManager::%s, interval[%u], entype_[%d], status[%u]\n", __FUNCTION__, dwinterval_, entype_, status_); 9 | } 10 | bool CThreadTimer::Start() { 11 | Stop(); 12 | status_ = TIME_OUT; 13 | timernode_ = powner_->AddTimer(dwinterval_, this); 14 | return timernode_ == NULL ? false : true; 15 | } 16 | void CThreadTimer::Stop() { 17 | status_ = USER_CANCLE; 18 | if (timernode_) { 19 | powner_->RemoveTimer(timernode_); 20 | timernode_ = NULL; 21 | } 22 | } 23 | void CThreadTimer::Callback() { 24 | timernode_ = NULL; 25 | if (entype_ == TIMER_CIRCLE) { 26 | Start(); 27 | } 28 | callback_(); //must at the last line; timer may be deleted in callback_(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /frame/common/threadtimer.h: -------------------------------------------------------------------------------- 1 | #ifndef APE_COMMON_THREAD_TIMER_H_ 2 | #define APE_COMMON_THREAD_TIMER_H_ 3 | 4 | #include "timermanager.h" 5 | #include 6 | #include 7 | #include 8 | namespace ape { 9 | namespace common { 10 | class CThreadTimer { 11 | public: 12 | typedef enum { TIMER_ONCE=0, TIMER_CIRCLE }ETimerType; 13 | typedef enum { WAITING=0, TIME_OUT, USER_CANCLE}EStatus; 14 | CThreadTimer() : powner_(NULL), status_(WAITING), data_(NULL), timernode_(NULL){} 15 | template 16 | CThreadTimer(CTimerManager *o, uint32_t i=0, Func f=0, ETimerType t=TIMER_ONCE, void *data=NULL) : 17 | powner_(o), dwinterval_(i), entype_(t), status_(WAITING), callback_(f), timernode_(NULL), data_(data) { } 18 | template 19 | void Init(CTimerManager *o, uint32_t i=0, Func f=0, ETimerType t=TIMER_ONCE, void *data=NULL) { 20 | powner_ = o; 21 | dwinterval_ = i; 22 | callback_ = f; 23 | entype_ = t; 24 | data_ = data; 25 | } 26 | bool Start(); 27 | void Stop(); 28 | int GetStatus(){return status_;} 29 | void SetData(void *data) {data_ = data;} 30 | void *GetData() {return data_;} 31 | ~CThreadTimer(); 32 | 33 | public: 34 | void Callback(); 35 | void SetInterval(uint32_t i) { dwinterval_ = i;} 36 | uint32_t GetInterval() { return dwinterval_;} 37 | 38 | private: 39 | CTimerManager *powner_; 40 | uint32_t dwinterval_; //unit : ms 41 | ETimerType entype_; 42 | EStatus status_; 43 | 44 | boost::function callback_; 45 | STimerNode *timernode_; 46 | void *data_; 47 | }; 48 | } 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /frame/common/timermanager.h: -------------------------------------------------------------------------------- 1 | #ifndef APE_COMMON_TIMER_MANAGER_H_ 2 | #define APE_COMMON_TIMER_MANAGER_H_ 3 | #include 4 | #include 5 | namespace ape{ 6 | namespace common{ 7 | class CThreadTimer; 8 | #define GRANULARITY 10 //10ms 9 | #define WHEEL_BITS1 8 10 | #define WHEEL_BITS2 6 11 | #define WHEEL_SIZE1 (1 << WHEEL_BITS1) //256 12 | #define WHEEL_SIZE2 (1 << WHEEL_BITS2) //64 13 | #define WHEEL_MASK1 (WHEEL_SIZE1 - 1) 14 | #define WHEEL_MASK2 (WHEEL_SIZE2 - 1) 15 | #define WHEEL_NUM 5 16 | typedef struct stNodeLink { 17 | stNodeLink *prev; 18 | stNodeLink *next; 19 | stNodeLink() {prev = next = this;} //circle 20 | }SNodeLink; 21 | typedef struct stTimerNode { 22 | SNodeLink link; 23 | uint64_t dead_time; 24 | CThreadTimer *timer; 25 | stTimerNode(CThreadTimer *t, uint64_t dt) : dead_time(dt), timer(t) {} 26 | }STimerNode; 27 | typedef struct stWheel { 28 | SNodeLink *spokes; 29 | uint32_t size; 30 | uint32_t spokeindex; 31 | stWheel(uint32_t n) : size(n), spokeindex(0){ 32 | spokes = new SNodeLink[n]; 33 | } 34 | ~stWheel() { 35 | if (spokes) { 36 | for (int j = 0; j < size; ++j) { 37 | SNodeLink *link = (spokes + j)->next; 38 | while (link != spokes + j) { 39 | STimerNode *node = (STimerNode *)link; 40 | link = node->link.next; 41 | delete node; 42 | } 43 | } 44 | delete []spokes; 45 | spokes = NULL; 46 | } 47 | } 48 | }SWheel; 49 | 50 | class CTimerManager { 51 | public: 52 | CTimerManager(); 53 | virtual ~CTimerManager(); 54 | void DetectTimerList(); 55 | STimerNode* AddTimer(uint32_t seconds, CThreadTimer *timer); 56 | void RemoveTimer(STimerNode* node); 57 | virtual void Dump(); 58 | 59 | private: 60 | uint32_t Cascade(uint32_t wheelindex); 61 | void AddTimerNode(uint32_t milseconds, STimerNode *node); 62 | void AddToReadyNode(STimerNode *node); 63 | void DoTimeOutCallBack(); 64 | 65 | private: 66 | SWheel *wheels_[WHEEL_NUM]; 67 | uint64_t checktime_; 68 | SNodeLink readynodes_; 69 | }; 70 | } 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /frame/common/xmlconfigparser.cc: -------------------------------------------------------------------------------- 1 | #include "xmlconfigparser.h" 2 | #include 3 | namespace ape{ 4 | namespace common{ 5 | CXmlConfigParser::CXmlConfigParser() : root_(NULL) { 6 | } 7 | void CXmlConfigParser::SetXmlError() { 8 | if (xmldoc_.Error()) { 9 | char szcode[16] = {0}; 10 | snprintf(szcode, 15, "id=%d ", xmldoc_.ErrorID()); 11 | error_ = "XMLDocument error "; 12 | error_.append(szcode); 13 | error_.append(tinyxml2::GetError(xmldoc_.ErrorID())); 14 | error_.append(" str1="); 15 | if (xmldoc_.GetErrorStr1()) { 16 | error_.append(xmldoc_.GetErrorStr1()); 17 | } 18 | error_.append(" str2="); 19 | if (xmldoc_.GetErrorStr2()) { 20 | error_.append(xmldoc_.GetErrorStr2()); 21 | } 22 | } 23 | } 24 | int CXmlConfigParser::ParseFile(const std::string &file) { 25 | if (tinyxml2::XML_SUCCESS != xmldoc_.LoadFile(file.c_str())) { 26 | SetXmlError(); 27 | return -1; 28 | } 29 | if( NULL == (root_ = xmldoc_.RootElement())) { 30 | error_ = "no root node!"; 31 | return -1; 32 | } 33 | return 0; 34 | } 35 | int CXmlConfigParser::ParseBuffer(const char *buffer) { 36 | xmldoc_.Parse(buffer); 37 | if (xmldoc_.Error()) { 38 | SetXmlError(); 39 | return -1; 40 | } 41 | if( NULL == (root_ = xmldoc_.RootElement())) { 42 | error_ = "no root node!"; 43 | return -1; 44 | } 45 | return 0; 46 | } 47 | int CXmlConfigParser::ParseDetailBuffer(const char *buffer) { 48 | std::string str = ""; 49 | str.append(buffer); 50 | str.append(""); 51 | return ParseBuffer(str.c_str()); 52 | } 53 | std::string CXmlConfigParser::GetString() { 54 | tinyxml2::XMLPrinter printer; 55 | xmldoc_.Accept(&printer); 56 | return printer.CStr(); 57 | } 58 | int CXmlConfigParser::GetParameter(const std::string &path, int defaultvalue) { 59 | std::string result = GetParameter(path); 60 | return result.empty() ? defaultvalue : atoi(result.c_str()); 61 | } 62 | std::string CXmlConfigParser::GetParameter(const std::string &path, const std::string& defaultvalue) { 63 | std::string result = GetParameter(path); 64 | return result.empty() ? defaultvalue : result; 65 | } 66 | std::string CXmlConfigParser::GetParameter(const std::string &path) { 67 | tinyxml2::XMLElement *ele = root_; 68 | if (ele == NULL){ 69 | return ""; 70 | } 71 | std::string key; 72 | std::size_t begin = 0, end = 0; 73 | while (std::string::npos != (end = path.find("/", begin))) { 74 | key = path.substr(begin, end - begin); 75 | begin = end + 1; 76 | if (key.empty()) { 77 | return ""; 78 | } 79 | if (NULL == (ele = ele->FirstChildElement(key.c_str()))) { 80 | return ""; 81 | } 82 | } 83 | key = path.substr(begin); 84 | if(key.empty() || NULL == (ele = ele->FirstChildElement(key.c_str()))) { 85 | return ""; 86 | } 87 | tinyxml2::XMLPrinter printer; 88 | ele->InnerAccept(&printer); 89 | return printer.CStr(); 90 | } 91 | std::vector CXmlConfigParser::GetParameters(const std::string &path) { 92 | std::vector result; 93 | tinyxml2::XMLElement *ele = root_; 94 | if (ele == NULL){ 95 | return result; 96 | } 97 | std::string key; 98 | size_t begin = 0, end = 0; 99 | while (std::string::npos != (end = path.find("/", begin))) { 100 | key = path.substr(begin, end - begin); 101 | begin = end + 1; 102 | if (key.empty()) { 103 | return result; 104 | } 105 | if (NULL == (ele = ele->FirstChildElement(key.c_str()))) { 106 | return result; 107 | } 108 | } 109 | key = path.substr(begin); 110 | if(key.empty() || NULL == (ele = ele->FirstChildElement(key.c_str()))) { 111 | return result; 112 | } 113 | do { 114 | tinyxml2::XMLPrinter printer; 115 | ele->InnerAccept(&printer); 116 | result.push_back(printer.CStr()); 117 | } while(NULL != (ele = ele->NextSiblingElement(key.c_str()))); 118 | 119 | return result; 120 | } 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /frame/common/xmlconfigparser.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_XML_CONFIG_PARSER_H_ 2 | #define _APE_COMMON_XML_CONFIG_PARSER_H_ 3 | #include 4 | #include 5 | #include "tinyxml2.h" 6 | namespace ape{ 7 | namespace common{ 8 | class CXmlConfigParser { 9 | public: 10 | CXmlConfigParser(); 11 | int ParseFile(const std::string &file); 12 | int ParseBuffer(const char *buffer); 13 | int ParseDetailBuffer(const char *buffer); 14 | std::string GetParameter(const std::string &path); 15 | int GetParameter(const std::string &path, int defaultvalue); 16 | std::string GetParameter(const std::string &path, const std::string& defaultvalue); 17 | std::vector GetParameters(const std::string & path); 18 | const std::string& GetErrorMessage()const{return error_;} 19 | std::string GetString(); 20 | private: 21 | void SetXmlError(); 22 | private: 23 | tinyxml2::XMLDocument xmldoc_; 24 | tinyxml2::XMLElement *root_; 25 | std::string error_; 26 | }; 27 | } 28 | } 29 | #endif -------------------------------------------------------------------------------- /frame/event/events.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_EVENTS_H_ 2 | #define _APE_COMMON_EVENTS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "protocol.h" 12 | 13 | namespace ape { 14 | namespace message { 15 | 16 | typedef struct stEvent { 17 | int id; 18 | stEvent(int i = -1) : id(i) {} 19 | virtual ~stEvent(){} 20 | virtual std::string NoticeInfo() {return "";}; 21 | virtual void Dump() {}; 22 | }SEvent; 23 | 24 | template 25 | struct SEventType : public BaseClass { 26 | enum {ID=tid}; 27 | SEventType() : BaseClass(tid) {} 28 | virtual ~SEventType() {} 29 | }; 30 | 31 | typedef struct stNetEvent : public SEvent { 32 | char ip[16]; 33 | unsigned int port; 34 | unsigned int connid; 35 | struct timeval time; 36 | std::string session_name; 37 | stNetEvent(int id=-1) : SEvent(id), port(0), connid(0) {memset(ip, 0, 16);} 38 | virtual ~stNetEvent(){} 39 | virtual std::string NoticeInfo() { 40 | char sz[32] = {0}; 41 | snprintf(sz, 31, "%s:%u", ip, port); 42 | return std::string(sz); 43 | } 44 | virtual std::string BriefInfo() {return NoticeInfo();} 45 | virtual void Init(const char *iip, unsigned int pt) { 46 | memcpy(ip, iip, strlen(iip)); 47 | port = pt; 48 | gettimeofday(&time, NULL); 49 | } 50 | virtual void Dump(){} 51 | }SNetEvent; 52 | 53 | typedef struct stConnectedEvent : public SEventType<101, SNetEvent> { 54 | virtual ~stConnectedEvent(){} 55 | }SConnectedEvent; 56 | typedef struct stPeerCloseEvent : public SEventType<102, SNetEvent> { 57 | virtual ~stPeerCloseEvent(){} 58 | }SPeerCloseEvent; 59 | 60 | 61 | typedef struct stContext { 62 | uint64_t token; 63 | virtual ~stContext() {} 64 | }SContext; 65 | 66 | typedef struct stNetMessage : public SNetEvent { 67 | typedef enum {E_Request = 0, E_Response, E_One_Way}SMessageDirection; 68 | SMessageDirection direction; 69 | bool isheartbeat; 70 | int code; 71 | SContext *ctx; 72 | void SetReply(int n = 0) {direction = E_Response; code = n;} 73 | bool IsReply() {return direction == E_Response;} 74 | virtual unsigned int GetSequenceId() {return 0;}; 75 | virtual bool IsOk() {return code == 0;} 76 | stNetMessage(int id=-1) : SNetEvent(id), direction(E_Request), isheartbeat(false), code(-1), ctx(NULL){} 77 | virtual ~stNetMessage(){ } 78 | virtual std::string BriefInfo() {return "";} 79 | }SNetMessage; 80 | 81 | } 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /frame/event/httpmessage.cc: -------------------------------------------------------------------------------- 1 | #include "httpmessage.h" 2 | #include "loghelper.h" 3 | 4 | namespace ape { 5 | namespace message { 6 | 7 | void SHttpMessage::AddHeader(const std::string &key, const std::string &value) { 8 | headers[key] = value; 9 | } 10 | void SHttpMessage::SetCookie(const std::string &key, const std::string &value, 11 | const std::string &path, const std::string &domain, time_t e) 12 | { 13 | cookies[key] = SCookie(value, path, domain, e); 14 | } 15 | std::string SHttpMessage::NoticeInfo() { 16 | std::string indent = " "; 17 | std::string info = indent; 18 | if (direction == SNetMessage::E_Request) { 19 | info += method + " " + url + " " + (httpversion == HTTP_1_1 ? "HTTP/1.1" : "HTTP/1.0") + "\r\n"; 20 | } else { 21 | info.append(httpversion == HTTP_1_1 ? "HTTP/1.1 " : "HTTP/1.0 "); 22 | char szcode[32] = {0}; 23 | snprintf(szcode, 31, "%d \r\n", code); 24 | info.append(szcode); 25 | } 26 | 27 | boost::unordered_map::const_iterator itr = headers.begin(); 28 | for (; itr != headers.end(); ++itr) { 29 | info += indent + itr->first + ": " + itr->second + "\r\n"; 30 | } 31 | 32 | boost::unordered_map::const_iterator itrc = cookies.begin(); 33 | for (; itrc != cookies.end(); ++itrc) { 34 | info += indent + "Cookie: " + itrc->first + "=" + itrc->second.value + 35 | ";path=" + itrc->second.path + "; domain=" + itrc->second.domain + "\r\n"; 36 | } 37 | info += indent + body; 38 | return info; 39 | } 40 | std::string SHttpMessage::BriefInfo() { 41 | std::string info; 42 | if (direction == SNetMessage::E_Request) { 43 | info += method + " " + url + " " + (httpversion == HTTP_1_1 ? "HTTP/1.1" : "HTTP/1.0") + "\r\n"; 44 | } else { 45 | info.append(httpversion == HTTP_1_1 ? "HTTP/1.1 " : "HTTP/1.0 "); 46 | char szcode[32] = {0}; 47 | snprintf(szcode, 31, "%d \r\n", code); 48 | info.append(szcode); 49 | } 50 | return info; 51 | } 52 | void SHttpMessage::Dump() { 53 | BS_XLOG(XLOG_DEBUG,"SHttpMessage::%s, keepalive[%d], no[%d]\n%s\n",__FUNCTION__, keepalive, requestno, NoticeInfo().c_str()); 54 | } 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /frame/event/httpmessage.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_MESSAGE_HTTP_MESSAGE_EVENTS_H_ 2 | #define _APE_MESSAGE_HTTP_MESSAGE_EVENTS_H_ 3 | 4 | #include "events.h" 5 | 6 | namespace ape { 7 | namespace message { 8 | 9 | typedef struct stHttpMessage : public SEventType { 10 | typedef struct stSCookie { 11 | std::string value; 12 | std::string path; 13 | std::string domain; 14 | time_t expires; 15 | stSCookie() :expires (0) {} 16 | stSCookie(const std::string &v, const std::string &p, const std::string &d, time_t e = 0) : 17 | value(v), path(p), domain(d), expires(e) {} 18 | }SCookie; 19 | typedef enum { HTTP_1_0 = 0, HTTP_1_1 = 1} EHttpVersion; 20 | 21 | bool keepalive; 22 | unsigned int requestno; 23 | EHttpVersion httpversion; 24 | std::string method; 25 | std::string url; 26 | std::string xforwordip; 27 | std::string body; 28 | boost::unordered_map headers; 29 | boost::unordered_map cookies; 30 | 31 | stHttpMessage() : keepalive(false), requestno(0), httpversion(HTTP_1_0) {} 32 | virtual ~stHttpMessage(){} 33 | virtual unsigned int GetSequenceId(){return 0;} 34 | virtual bool IsOk() {return code == 200;} 35 | virtual std::string NoticeInfo(); 36 | virtual void Dump(); 37 | virtual std::string BriefInfo(); 38 | 39 | void AddHeader(const std::string &key, const std::string &value); 40 | void SetCookie(const std::string &key, const std::string &value, const std::string &path, const std::string &domain, time_t e = 0); 41 | }SHttpMessage; 42 | 43 | 44 | } 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /frame/event/thriftmessage.cc: -------------------------------------------------------------------------------- 1 | #include "thriftmessage.h" 2 | #include "loghelper.h" 3 | 4 | namespace ape { 5 | namespace message { 6 | 7 | SThriftMessage::~stThriftMessage() { 8 | } 9 | std::string SThriftMessage::NoticeInfo() { 10 | const char *indent = " "; 11 | std::string info; 12 | info.append(indent); 13 | info.append(method); 14 | char sz[64] = {0}; 15 | snprintf(sz, 63, ", seq[%d], code[%d]", seqid, code); 16 | info.append(sz); 17 | info.append(1,'\n'); 18 | 19 | if (!body.empty()) 20 | info.append(GetBinaryDumpInfo(body.c_str(), body.length(), 6)); 21 | return info; 22 | } 23 | std::string SThriftMessage::BriefInfo() { 24 | std::string info; 25 | info.append(method); 26 | char sz[64] = {0}; 27 | snprintf(sz, 63, ", seq[%d], code[%d]", seqid, code); 28 | info.append(sz); 29 | return info; 30 | } 31 | void SThriftMessage::Dump() { 32 | BS_XLOG(XLOG_DEBUG,"SThriftMessage::%s\n%s\n",__FUNCTION__, NoticeInfo().c_str()); 33 | } 34 | 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /frame/event/thriftmessage.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_MESSAGE_THRIFT_MESSAGE_H_ 2 | #define _APE_MESSAGE_THRIFT_MESSAGE_H_ 3 | 4 | #include "events.h" 5 | 6 | namespace ape { 7 | namespace message { 8 | 9 | typedef struct stThriftMessage : public SEventType { 10 | unsigned int seqid; 11 | std::string method; 12 | std::string body; 13 | stThriftMessage() : seqid(0) {} 14 | virtual ~stThriftMessage(); 15 | virtual unsigned int GetSequenceId(){return seqid;} 16 | virtual std::string NoticeInfo(); 17 | virtual std::string BriefInfo(); 18 | virtual void Dump(); 19 | }SThriftMessage; 20 | 21 | 22 | } 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /frame/interface/buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_BUFFER_H_ 2 | #define _APE_COMMON_BUFFER_H_ 3 | #include 4 | #include 5 | 6 | namespace ape{ 7 | namespace common{ 8 | const int BUFFER_INIT_CAPACITY = 10240; 9 | 10 | #define BUFFER_ALIGN(size) (((size) + 2047) & ~2047) //SAP_ALIGN(size, 2048) 11 | class CBuffer { 12 | public: 13 | CBuffer(int capacity = BUFFER_INIT_CAPACITY) : capacity_(capacity), loc_(0) { 14 | base_ = (char *)malloc(capacity); 15 | } 16 | void add_capacity() { 17 | capacity_ += capacity_; 18 | base_ = (char *)realloc(base_, capacity_); 19 | } 20 | void add_capacity(int nLeft) { 21 | capacity_ += nLeft; 22 | base_ = (char *)realloc(base_,capacity_); 23 | } 24 | void append(const char *p) { 25 | append(p, strlen(p)); 26 | } 27 | void append(const char *p, int len) { 28 | if (loc_ + len > capacity_) { 29 | add_capacity(capacity_ + len + capacity_); 30 | } 31 | memcpy(base_ + loc_, p, len); 32 | loc_ += len; 33 | } 34 | char * base() const {return base_;} 35 | char * top() const {return base_ + loc_;} 36 | void inc_loc(unsigned int loc){loc_ += loc;} 37 | void reset_loc(int loc){loc_ = loc;} 38 | unsigned int capacity() const {return capacity_-loc_;} 39 | unsigned int len() const{return loc_;} 40 | ~CBuffer(){free(base_);} 41 | private: 42 | char *base_; 43 | unsigned int capacity_; 44 | unsigned int loc_; 45 | }; 46 | } 47 | } 48 | #endif 49 | 50 | 51 | -------------------------------------------------------------------------------- /frame/interface/errorcode.h: -------------------------------------------------------------------------------- 1 | #ifndef APE_COMMON_ERROR_CODE_H_ 2 | #define APE_COMMON_ERROR_CODE_H_ 3 | 4 | namespace ape { 5 | namespace common { 6 | 7 | typedef enum { 8 | SUCCESS = 0, 9 | ERROR_TIME_OUT = -10260001, 10 | ERROR_PEER_CLOSE = -10260002, 11 | ERROR_USER_CLOSE = -10260003, 12 | ERROR_UNDEFINED = -10260100 13 | }EErrorCode; 14 | 15 | } 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /frame/interface/handleralloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_HANDLER_ALLOC_H_ 2 | #define _APE_COMMON_HANDLER_ALLOC_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ape{ 9 | namespace common{ 10 | class CHandlerAllocator : private boost::noncopyable { 11 | public: 12 | CHandlerAllocator() : in_use_(false) { } 13 | 14 | void* allocate(std::size_t size) { 15 | if (!in_use_ && size < storage_.size) { 16 | in_use_ = true; 17 | return storage_.address(); 18 | } else { 19 | return ::operator new(size); 20 | } 21 | } 22 | 23 | void deallocate(void* pointer) { 24 | if (pointer == storage_.address()) { 25 | in_use_ = false; 26 | } else { 27 | ::operator delete(pointer); 28 | } 29 | } 30 | 31 | private: 32 | boost::aligned_storage<160> storage_; 33 | bool in_use_; 34 | }; 35 | 36 | template 37 | class CAllocHandler { 38 | public: 39 | CAllocHandler(CHandlerAllocator& a, Handler h) : allocator_(a), handler_(h) { } 40 | 41 | template 42 | void operator()(Arg1 arg1) { 43 | handler_(arg1); 44 | } 45 | 46 | template 47 | void operator()(Arg1 arg1, Arg2 arg2) { 48 | handler_(arg1, arg2); 49 | } 50 | 51 | friend void* asio_handler_allocate(std::size_t size, CAllocHandler* this_handler) { 52 | return this_handler->allocator_.allocate(size); 53 | } 54 | 55 | friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/, CAllocHandler* this_handler) { 56 | this_handler->allocator_.deallocate(pointer); 57 | } 58 | 59 | private: 60 | CHandlerAllocator& allocator_; 61 | Handler handler_; 62 | }; 63 | 64 | template 65 | inline CAllocHandler MakeAllocHandler(CHandlerAllocator& a, Handler h) { 66 | return CAllocHandler(a, h); 67 | } 68 | 69 | } 70 | } 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /frame/interface/loghelper.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_LOG_HELPER_H_ 2 | #define _APE_LOG_HELPER_H_ 3 | 4 | #include "LogManager.h" 5 | #include 6 | #include 7 | 8 | const int BUSINESS_MODULE = 102; 9 | DEFINE_MODULE_XLOG(BUSINESS_MODULE, BS_XLOG) 10 | #define BS_SLOG(Level,Event) SLOG(BUSINESS_MODULE,Level,Event) 11 | 12 | const int SELF_CHECK_MODULE = 91; 13 | DEFINE_MODULE_XLOG(SELF_CHECK_MODULE,SELF_CHECK_XLOG) 14 | 15 | 16 | static inline char GetVisibleAscii(char c) { return (c >= 33 && c <= 126) ? c : '.'; } 17 | static std::string GetBinaryDumpInfo(const char *buf, int len, int indent = 4) { 18 | std::string info; 19 | std::string strindent(indent, ' '); 20 | 21 | int line = len >> 3; 22 | int last = (len & 0x7); 23 | int i = 0; 24 | for (i = 0; i < line; ++i) { 25 | char szbuf[128] = {0}; 26 | const unsigned char * base = (const unsigned char *)(buf + (i << 3)); 27 | sprintf(szbuf,"%s[%2d] %02x %02x %02x %02x %02x %02x %02x %02x %c %c %c %c %c %c %c %c\n", 28 | strindent.c_str(), i,*(base),*(base+1),*(base+2),*(base+3),*(base+4),*(base+5),*(base+6),*(base+7), 29 | GetVisibleAscii(*(base)), GetVisibleAscii(*(base+1)), GetVisibleAscii(*(base+2)), GetVisibleAscii(*(base+3)), 30 | GetVisibleAscii(*(base+4)), GetVisibleAscii(*(base+5)), GetVisibleAscii(*(base+6)), GetVisibleAscii(*(base+7))); 31 | info.append(szbuf); 32 | } 33 | if (last > 0) { 34 | const unsigned char * base = (const unsigned char *)(buf + (i << 3)); 35 | char szhex[32] = {0}; 36 | char szascii[32] = {0}; 37 | for(int j = 0; j < last; ++j) { 38 | sprintf(szhex + j * 3, " %02x", *(base + j)); 39 | sprintf(szascii + j * 2, " %c", GetVisibleAscii(*(base + j))); 40 | } 41 | char szbuf[128] = {0}; 42 | sprintf(szbuf, "%s[%2d] %s", strindent.c_str(), i, szhex); 43 | info.append(szbuf); 44 | info.append((8 - last)*3 + 3, ' '); 45 | info.append(szascii); 46 | info.append(1,'\n'); 47 | } 48 | return info; 49 | } 50 | 51 | #endif 52 | 53 | 54 | -------------------------------------------------------------------------------- /frame/interface/urlcode.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOOL_URL_CODE_H_ 2 | #define _TOOL_URL_CODE_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class UrlEncoder { 9 | public: 10 | static std::string encode(const char *pValue, size_t len){ 11 | std::string ret = ""; 12 | size_t i=0; 13 | for (i=0;i='a'&&ch<='z') || (ch>='0'&&ch<='9')) { 30 | return true; 31 | } 32 | return false; 33 | } 34 | }; 35 | 36 | class URLDecoder { 37 | public: 38 | static std::string decode(const char *pValue, size_t len) { 39 | std::string ret = ""; 40 | URLDecoder::decode(pValue, len, &ret); 41 | return ret; 42 | } 43 | static void decode(const char *pValue, size_t len, std::string *out) { 44 | size_t i=0; 45 | for (i=0;iappend(" "); 48 | } else if(pValue[i] == '%') { 49 | char tmp[4]; 50 | char hex[4]; 51 | hex[0] = pValue[++i]; 52 | hex[1] = pValue[++i]; 53 | hex[2] = '\0'; 54 | sprintf(tmp,"%c",convertToDec(hex)); 55 | out->append(tmp); 56 | } else { 57 | out->append(1, pValue[i]); 58 | } 59 | } 60 | } 61 | 62 | static int convertToDec(const char* hex) { 63 | char buff[12]; 64 | sprintf(buff,"%s",hex); 65 | int ret = 0; 66 | size_t len = strlen(buff); 67 | size_t i=0; 68 | size_t j=0; 69 | for(i=0;i 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | namespace ape{ 18 | namespace net{ 19 | class CSession; 20 | class CConnection : public boost::enable_shared_from_this, private boost::noncopyable { 21 | public: 22 | typedef struct stLenMsg { 23 | int len; 24 | void *buf; 25 | }SLenMsg; 26 | CConnection(boost::asio::io_service &io_service, ape::protocol::EProtocolType pro, CSession *o); 27 | ~CConnection(); 28 | void AsyncConnect(const std::string &ip, unsigned int port, int timeout = 3); 29 | void AsyncRead(); 30 | void AsyncWrite(ape::message::SNetMessage *msg, bool close = false); 31 | void HandleSendResponse(const std::string &strResponse); 32 | void OnPeerClose(); 33 | void Dump(); 34 | void SetOwner(CSession *o) {session_ = o;} 35 | unsigned int Id(){return id_;} 36 | boost::asio::ip::tcp::socket& Socket(){return socket_;} 37 | const std::string & GetRemoteIp(); 38 | unsigned int GetRemotePort(); 39 | ape::protocol::CBaseParser *GetParser() const { return parser_;} 40 | private: 41 | void HandleResolve(const boost::system::error_code& err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); 42 | void HandleConnected(const boost::system::error_code& err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator); 43 | void HandleConnectTimeout(const boost::system::error_code& err); 44 | void ConnectFinish(int result); 45 | void AsyncReadInner(); 46 | void HandleRead(const boost::system::error_code& err,std::size_t size); 47 | void HandleWrite(const boost::system::error_code& err); 48 | private: 49 | boost::asio::io_service &io_service_; 50 | boost::asio::ip::tcp::socket socket_; 51 | boost::asio::ip::tcp::resolver resolver_; 52 | boost::asio::deadline_timer conn_timer_; 53 | ape::common::CBuffer buffer_; 54 | ape::common::CBuffer writebuf_; 55 | unsigned int id_; 56 | static unsigned int sm_mark_; 57 | std::string remoteip_; 58 | unsigned int remoteport_; 59 | ape::common::CHandlerAllocator conn_alloc_; 60 | ape::common::CHandlerAllocator timer_alloc_; 61 | ape::common::CHandlerAllocator read_alloc_; 62 | ape::common::CHandlerAllocator write_alloc_; 63 | bool connected_; 64 | bool close_after_write_; 65 | CSession *session_; 66 | ape::protocol::CBaseParser *parser_; 67 | std::deque out_queue_; 68 | bool is_dealing_read_; 69 | }; 70 | 71 | typedef boost::shared_ptr Connection_ptr; 72 | } 73 | } 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /frame/net/ioservicethread.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "ioservicethread.h" 6 | #include "loghelper.h" 7 | 8 | namespace ape { 9 | namespace net { 10 | 11 | const int SELF_CHECK_INTERVAL = 2000; 12 | 13 | CIoServiceThread::CIoServiceThread():threadid_(0), isalive_(false), dealline_timer_(ioservice_){ 14 | InitInner(); 15 | } 16 | CIoServiceThread::CIoServiceThread(int threadid):threadid_(threadid), isalive_(false), dealline_timer_(ioservice_) { 17 | InitInner(); 18 | } 19 | CIoServiceThread::~CIoServiceThread() { 20 | } 21 | void CIoServiceThread::InitInner() { 22 | tm_selfcheck_.Init(this, SELF_CHECK_INTERVAL, boost::bind(&CIoServiceThread::DoSelfCheck, this), ape::common::CThreadTimer::TIMER_CIRCLE); 23 | } 24 | void CIoServiceThread::Start() { 25 | BS_XLOG(XLOG_DEBUG,"CIoServiceThread::%s, threadid_[%d]\n",__FUNCTION__, threadid_); 26 | work_ = new boost::asio::io_service::work(ioservice_); 27 | thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &ioservice_)); 28 | ioservice_.post(boost::bind(&CIoServiceThread::StartInThread, this)); 29 | 30 | isalive_ = true; 31 | dealline_timer_.expires_from_now(boost::posix_time::microseconds(200000)); 32 | dealline_timer_.async_wait(ape::common::MakeAllocHandler(alloc_timer, boost::bind(&CIoServiceThread::DoTimer, this))); 33 | } 34 | void CIoServiceThread::StartInThread() { 35 | BS_XLOG(XLOG_DEBUG,"CIoServiceThread::%s, threadid_[%d]\n",__FUNCTION__, threadid_); 36 | isalive_ = true; 37 | tm_selfcheck_.Start(); 38 | } 39 | void CIoServiceThread::StopInThread() { 40 | BS_XLOG(XLOG_DEBUG,"CIoServiceThread::%s, threadid_[%d]\n",__FUNCTION__, threadid_); 41 | tm_selfcheck_.Stop(); 42 | } 43 | void CIoServiceThread::DoTimer() { 44 | //BS_XLOG(XLOG_TRACE,"CIoServiceThread::%s\n",__FUNCTION__); 45 | DetectTimerList(); 46 | if(isalive_) { 47 | dealline_timer_.expires_from_now(boost::posix_time::microseconds(200000)); 48 | dealline_timer_.async_wait(ape::common::MakeAllocHandler(alloc_timer, boost::bind(&CIoServiceThread::DoTimer, this))); 49 | } 50 | } 51 | void CIoServiceThread::Stop() { 52 | BS_XLOG(XLOG_DEBUG,"CIoServiceThread::%s, threadid_[%d]\n",__FUNCTION__, threadid_); 53 | isalive_ = false; 54 | ioservice_.post(boost::bind(&CIoServiceThread::StopInThread, this)); 55 | delete work_; 56 | thread_.join(); 57 | ioservice_.reset(); 58 | } 59 | void CIoServiceThread::GetSelfCheck(bool &isalive) { 60 | isalive = isalive_; 61 | isalive_ = false; 62 | } 63 | void CIoServiceThread::DoSelfCheck() { 64 | //BS_XLOG(XLOG_DEBUG,"CIoServiceThread::%s\n",__FUNCTION__); 65 | isalive_ = true; 66 | } 67 | void CIoServiceThread::Dump() { 68 | CTimerManager::Dump(); 69 | } 70 | } 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /frame/net/ioservicethread.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_NET_IO_THREAD_H_ 2 | #define _APE_NET_IO_THREAD_H_ 3 | #include 4 | #include 5 | #include 6 | #include "timermanager.h" 7 | #include "threadtimer.h" 8 | #include "handleralloc.h" 9 | 10 | namespace ape { 11 | namespace net { 12 | 13 | class CIoServiceThread : public ape::common::CTimerManager { 14 | public: 15 | CIoServiceThread(); 16 | CIoServiceThread(int threadid); 17 | ~CIoServiceThread(); 18 | void Start(); 19 | void Stop(); 20 | int GetThreadId(){return threadid_;} 21 | void GetSelfCheck(bool &isalive); 22 | 23 | virtual boost::asio::io_service *GetIoService(){return &ioservice_;} 24 | virtual void StartInThread(); 25 | virtual void StopInThread(); 26 | virtual void Dump(); 27 | 28 | private: 29 | void InitInner(); 30 | void DoTimer(); 31 | void DoSelfCheck(); 32 | 33 | protected: 34 | int threadid_; 35 | boost::asio::io_service ioservice_; 36 | boost::asio::io_service::work *work_; 37 | boost::thread thread_; 38 | 39 | volatile bool isalive_; 40 | boost::asio::deadline_timer dealline_timer_; 41 | ape::common::CHandlerAllocator alloc_timer; 42 | 43 | ape::common::CThreadTimer tm_selfcheck_; 44 | }; 45 | } 46 | } 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /frame/net/netservice.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_NET_SERVICE_H_ 2 | #define _APE_COMMON_NET_SERVICE_H_ 3 | #include 4 | #include "timermanager.h" 5 | namespace ape { 6 | namespace net { 7 | class CNetService { 8 | public: 9 | virtual boost::asio::io_service *GetIoService() = 0; 10 | virtual ape::common::CTimerManager *GetTimerManager() = 0; 11 | /** if add_reuse is false, the name should be unique */ 12 | virtual int OnConnect(const std::string &name, const std::string &addr, bool autoreconnect = false, int heartbeat = 0, bool addr_reuse = true) = 0; 13 | virtual int DoConnect(const std::string &name, const std::string &addr, bool autoreconnect = false, int heartbeat = 0, bool addr_reuse = true) = 0; 14 | virtual void OnSendTo(const std::string &name, void *para, int timeout = 30) = 0; 15 | virtual void DoSendTo(const std::string &name, void *para, int timeout = 30) = 0; 16 | virtual void OnClose(const std::string &name, unsigned int connid) = 0; 17 | virtual void DoClose(const std::string &name, unsigned int connid) = 0; 18 | virtual void OnSendBack(unsigned int connid, void *para) = 0; 19 | virtual void DoSendBack(unsigned int connid, void *para) = 0; 20 | }; 21 | class CHandle { 22 | public: 23 | virtual void StartInThread(int threadid, CNetService *service, ape::common::CTimerManager *owner) = 0; 24 | virtual void StopInThread(int threadid) = 0; 25 | virtual void OnEvent(int threadid, void *event) = 0; 26 | virtual void Release() {delete this;} 27 | virtual ~CHandle(){} 28 | }; 29 | class HandleFactory { 30 | public: 31 | virtual CHandle* NewHandler() = 0; 32 | virtual ~HandleFactory() {} 33 | }; 34 | template 35 | class NetHandleFactory : public HandleFactory { 36 | public: 37 | virtual CHandle* NewHandler() { 38 | return new HANDLER(); 39 | } 40 | virtual ~NetHandleFactory() {} 41 | }; 42 | } 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /frame/net/netthreadholder.cc: -------------------------------------------------------------------------------- 1 | #include "netthreadholder.h" 2 | #include "tcpsocketserver.h" 3 | #include "sessionmanager.h" 4 | #include 5 | #include "loghelper.h" 6 | #include 7 | #include 8 | 9 | namespace ape { 10 | namespace net { 11 | void CNetThreadHolder::Start(HandleFactory *f, int threadnum) { 12 | BS_XLOG(XLOG_DEBUG,"CNetThreadHolder::Start[%d]...\n",threadnum); 13 | threadnum_ = threadnum + 1; 14 | ppthreads_ = new CSessionManager *[threadnum_]; 15 | 16 | for (int i = 0; i < threadnum_; ++i) { 17 | CSessionManager *thread = new CSessionManager(f, i); 18 | ppthreads_[i] = thread; 19 | thread->Start(); 20 | } 21 | } 22 | int CNetThreadHolder::StartServer(const std::vector &addrs) { 23 | std::vector::const_iterator itr = addrs.begin(); 24 | for(; itr != addrs.end(); ++itr) { 25 | CTcpSocketServer *server = new CTcpSocketServer(*(GetAcceptIoService()), this); 26 | servers_.push_back(server); 27 | if (0 != server->StartServer(*itr)) { 28 | return -1; 29 | } 30 | } 31 | return 0; 32 | } 33 | void CNetThreadHolder::Stop() { 34 | BS_XLOG(XLOG_DEBUG,"CNetThreadHolder::Stop\n"); 35 | for(std::vector::iterator itr = servers_.begin(); itr != servers_.end(); ++itr) { 36 | (*itr)->StopServer(); 37 | //delete *itr; 38 | } 39 | for(int i = 0; i < threadnum_; ++i) { 40 | CSessionManager *thread = ppthreads_[i]; 41 | thread->Stop(); 42 | delete thread; 43 | } 44 | for(std::vector::iterator itr = servers_.begin(); itr != servers_.end(); ++itr) { 45 | delete *itr; 46 | } 47 | servers_.clear(); 48 | 49 | delete[] ppthreads_; 50 | } 51 | 52 | boost::asio::io_service *CNetThreadHolder::GetAcceptIoService() { 53 | return ppthreads_[threadnum_-1]->GetIoService(); 54 | } 55 | CSessionCallBack *CNetThreadHolder::GetSessionCallBack() { 56 | if (threadnum_ <= 1) { 57 | return ppthreads_[0]; 58 | } 59 | int i = (index_++) % (threadnum_ - 1); 60 | return ppthreads_[i]; 61 | } 62 | 63 | void CNetThreadHolder::GetThreadStatus(int &threadnum, int &deadthreadnum) { 64 | BS_XLOG(XLOG_DEBUG,"CNetThreadHolder::%s..\n", __FUNCTION__); 65 | threadnum = threadnum_; 66 | for(int i = 0; i < threadnum_; ++i) { 67 | CSessionManager *thread = ppthreads_[i]; 68 | bool isalive; 69 | thread->GetSelfCheck(isalive); 70 | if(!isalive) 71 | deadthreadnum++; 72 | } 73 | } 74 | 75 | void CNetThreadHolder::Dump() { 76 | for(int i = 0; i < threadnum_; ++i) { 77 | CSessionManager *thread = ppthreads_[i]; 78 | BS_XLOG(XLOG_DEBUG,"\n\n\n=====DUMP[%d], manager[%p]\n", i, thread); 79 | thread->Dump(); 80 | } 81 | } 82 | } 83 | } 84 | 85 | -------------------------------------------------------------------------------- /frame/net/netthreadholder.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_NET_NET_THREAD_HOLDER_H_ 2 | #define _APE_NET_NET_THREAD_HOLDER_H_ 3 | #include "netservice.h" 4 | #include "sessioncallback.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace ape { 10 | namespace net { 11 | class CTcpSocketServer; 12 | class CSessionManager; 13 | class CNetThreadHolder : public CNetServiceHolder { 14 | public: 15 | CNetThreadHolder():ppthreads_(NULL), threadnum_(1), index_(0){} 16 | void Start(HandleFactory *f, int threadnum = 3); 17 | int StartServer(const std::vector &addrs); 18 | void Stop(); 19 | 20 | virtual CSessionCallBack *GetSessionCallBack(); 21 | boost::asio::io_service *GetAcceptIoService(); 22 | void GetThreadStatus(int &threadnum, int &deadthreadnum); 23 | void Dump(); 24 | 25 | private: 26 | CSessionManager **ppthreads_; 27 | std::vector servers_; 28 | int threadnum_; 29 | unsigned int index_; 30 | }; 31 | } 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /frame/net/sessioncallback.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_NET_SESSION_CALLBACK_H_ 2 | #define _APE_NET_SESSION_CALLBACK_H_ 3 | #include 4 | namespace ape { 5 | namespace net { 6 | class CSessionCallBack { 7 | public: 8 | virtual boost::asio::io_service *GetIoService() = 0; 9 | virtual int GetThreadId() = 0; 10 | virtual void OnAccept(void *session) = 0; 11 | virtual void OnConnected(void *session) = 0; 12 | virtual int OnPeerClose(void *session) = 0; 13 | virtual void OnRead(void *session, void *para) = 0; 14 | virtual ~CSessionCallBack() {} 15 | }; 16 | class CNetServiceHolder { 17 | public: 18 | virtual CSessionCallBack *GetSessionCallBack() = 0; 19 | virtual ~CNetServiceHolder() {} 20 | }; 21 | } 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /frame/net/sessionmanager.cc: -------------------------------------------------------------------------------- 1 | #include "sessionmanager.h" 2 | #include "protocolhelper.h" 3 | #include "loghelper.h" 4 | #include "events.h" 5 | 6 | 7 | namespace ape { 8 | namespace net { 9 | const int CHECK_SESSION_INTERVAL = 15000; //30s 10 | CSessionManager::CSessionManager(HandleFactory *f, int threadid) : CIoServiceThread(threadid), 11 | CNetService(), CSessionCallBack(), CSocSessionManager(&ioservice_), CSosSessionManager(&ioservice_), factory(f) { 12 | handle_ = factory->NewHandler(); 13 | InitInner(); 14 | } 15 | CSessionManager::~CSessionManager() { 16 | BS_XLOG(XLOG_TRACE,"CSessionManager::%s, threadid[%d]\n",__FUNCTION__, GetThreadId()); 17 | handle_->Release(); 18 | } 19 | void CSessionManager::InitInner() { 20 | tm_check_session_.Init(this, CHECK_SESSION_INTERVAL, boost::bind(&CSessionManager::DoCheckSession, this), ape::common::CThreadTimer::TIMER_CIRCLE); 21 | } 22 | 23 | void CSessionManager::StartInThread() { 24 | CIoServiceThread::StartInThread(); 25 | tm_check_session_.Start(); 26 | handle_->StartInThread(GetThreadId(), this, this); 27 | } 28 | void CSessionManager::StopInThread() { 29 | tm_check_session_.Stop(); 30 | CIoServiceThread::StopInThread(); 31 | handle_->StopInThread(GetThreadId()); 32 | } 33 | int CSessionManager::OnPeerClose(void *session) { 34 | CSession *p = (CSession*)session; 35 | ape::message::SPeerCloseEvent *event = new ape::message::SPeerCloseEvent; 36 | event->Init(p->GetRemoteIp().c_str(), p->GetRemotePort()); 37 | int ret = CSocSessionManager::OnPeerClose(session); 38 | if (0 != ret) { 39 | ret = CSosSessionManager::OnPeerClose(session); 40 | } 41 | OnRead(session, event); 42 | 43 | return ret; 44 | } 45 | void CSessionManager::OnRead(void *session, void *para) { 46 | ape::message::SNetEvent *event = (ape::message::SNetEvent *)para; 47 | if (session) { 48 | event->connid = ((CSession*)session)->Id(); 49 | event->session_name = ((CSession*)session)->GetName(); 50 | } 51 | handle_->OnEvent(GetThreadId(), (ape::message::SEvent *)para); 52 | } 53 | void CSessionManager::DoCheckSession() { 54 | CSocSessionManager::DoCheckSession(); 55 | CSosSessionManager::DoCheckSession(); 56 | //Dump(); 57 | } 58 | void CSessionManager::Dump() { 59 | CIoServiceThread::Dump(); 60 | CSocSessionManager::Dump(); 61 | CSosSessionManager::Dump(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /frame/net/sessionmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_SESSION_MANAGER_H_ 2 | #define _APE_COMMON_SESSION_MANAGER_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "ioservicethread.h" 8 | #include "events.h" 9 | #include "sossessionmanager.h" 10 | #include "socsessionmanager.h" 11 | #include "session.h" 12 | 13 | namespace ape { 14 | namespace net { 15 | 16 | class CSessionManager : public CIoServiceThread, public CSosSessionManager, public CSocSessionManager { 17 | public: 18 | CSessionManager(HandleFactory *f, int threadid); 19 | virtual ~CSessionManager(); 20 | virtual void StartInThread(); 21 | virtual void StopInThread(); 22 | virtual void Dump(); 23 | 24 | virtual boost::asio::io_service *GetIoService() {return CIoServiceThread::GetIoService();} 25 | virtual ape::common::CTimerManager *GetTimerManager() {return this;} 26 | virtual int GetThreadId() {return CIoServiceThread::GetThreadId();} 27 | virtual void OnRead(void *session, void *para); 28 | virtual int OnPeerClose(void *session); 29 | 30 | private: 31 | void InitInner(); 32 | void DoCheckSession(); 33 | 34 | private: 35 | HandleFactory *factory; 36 | CHandle *handle_; 37 | ape::common::CThreadTimer tm_check_session_; 38 | }; 39 | } 40 | } 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /frame/net/socsessionmanager.cc: -------------------------------------------------------------------------------- 1 | #include "socsessionmanager.h" 2 | #include "protocolhelper.h" 3 | #include "loghelper.h" 4 | 5 | 6 | namespace ape { 7 | namespace net { 8 | 9 | CSocSessionManager::~CSocSessionManager() { 10 | BS_XLOG(XLOG_TRACE,"CSocSessionManager::%s\n",__FUNCTION__); 11 | std::map::iterator itr = sessions_.begin();; 12 | for(; itr != sessions_.end(); ++itr) { 13 | delete itr->second; 14 | } 15 | sessions_.clear(); 16 | } 17 | 18 | void CSocSessionManager::OnAccept(void *session) { 19 | CSession *p = (CSession*)session; 20 | BS_XLOG(XLOG_DEBUG,"CSocSessionManager::%s, sessionid[%d], addr[%s:%u]\n",__FUNCTION__, p->Id(), p->GetRemoteIp().c_str(), p->GetRemotePort()); 21 | sessions_[p->Id()] = p; 22 | } 23 | 24 | int CSocSessionManager::OnPeerClose(void *session) { 25 | CSession *p = (CSession*)session; 26 | BS_XLOG(XLOG_DEBUG,"CSocSessionManager::%s, addr[%s:%u]\n",__FUNCTION__, p->GetRemoteIp().c_str(), p->GetRemotePort()); 27 | 28 | std::map::iterator itr = sessions_.find(p->Id()); 29 | if(itr != sessions_.end()) { 30 | p->SetStatus(CSession::CLOSED); 31 | //delete itr->second; 32 | //sessions_.erase(itr); 33 | return 0; 34 | } 35 | return -1; 36 | } 37 | 38 | void CSocSessionManager::OnSendBack(unsigned int connid, void *para) { 39 | io_service_->post(boost::bind(&CSocSessionManager::DoSendBack, this, connid, para)); 40 | } 41 | void CSocSessionManager::DoSendBack(unsigned int connid, void *para) { 42 | std::map::iterator itr = sessions_.find(connid); 43 | if(itr != sessions_.end()) { 44 | itr->second->DoSendBack(para); 45 | } else { 46 | BS_XLOG(XLOG_WARNING,"CSocSessionManager::%s, connection has be closed, message[%s]\n",__FUNCTION__, ((ape::message::SEvent *)para)->NoticeInfo().c_str()); 47 | } 48 | } 49 | 50 | void CSocSessionManager::DoCheckSession() { 51 | //BS_XLOG(XLOG_TRACE,"CSocSessionManager::%s, sessions_.size[%u]...\n",__FUNCTION__, sessions_.size()); 52 | std::map::iterator itr = sessions_.begin();; 53 | while(itr != sessions_.end()) { 54 | std::map::iterator tmp = itr++; 55 | CSession *p = tmp->second; 56 | if(p == NULL){ continue;} 57 | CSession::EStatus status = p->GetStatus(); 58 | if(status == CSession::CONNECTED){ 59 | p->SetStatus(CSession::TIME_OUT); 60 | } else if(status == CSession::TIME_OUT || status == CSession::CLOSED) { 61 | p->Close(); /** will notify OnEvent **/ 62 | sessions_.erase(tmp); 63 | delete p; 64 | } 65 | } 66 | } 67 | 68 | void CSocSessionManager::Dump() { 69 | BS_XLOG(XLOG_TRACE,"CSocSessionManager::%s, session_.size[%u]\n",__FUNCTION__, sessions_.size()); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /frame/net/socsessionmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_NET_SOC_SESSION_MANAGER_H_ 2 | #define _APE_NET_SOC_SESSION_MANAGER_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "events.h" 8 | #include "session.h" 9 | #include "sessioncallback.h" 10 | #include "netservice.h" 11 | 12 | namespace ape { 13 | namespace net { 14 | 15 | class CSocSessionManager : public virtual CNetService, public virtual CSessionCallBack { 16 | public: 17 | CSocSessionManager(boost::asio::io_service *io_service) : CNetService(), CSessionCallBack(), io_service_(io_service) {} 18 | virtual void OnAccept(void *session); 19 | virtual int OnPeerClose(void *session); 20 | virtual void OnSendBack(unsigned int connid, void *para); 21 | virtual void DoSendBack(unsigned int connid, void *para); 22 | virtual void DoCheckSession(); 23 | virtual void Dump(); 24 | virtual ~CSocSessionManager(); 25 | private: 26 | boost::asio::io_service *io_service_; 27 | std::map sessions_; 28 | }; 29 | } 30 | } 31 | #endif 32 | 33 | -------------------------------------------------------------------------------- /frame/net/sossessionmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_NET_SOS_SESSION_MANAGER_H_ 2 | #define _APE_NET_SOS_SESSION_MANAGER_H_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "ioservicethread.h" 8 | #include "events.h" 9 | #include "session.h" 10 | #include "sessioncallback.h" 11 | #include "netservice.h" 12 | 13 | namespace ape { 14 | namespace net { 15 | 16 | class CSosSessionManager : public virtual CSessionCallBack, public virtual CNetService { 17 | class CSessionContainer; 18 | class CShortSessionContainer; 19 | class CPersistentSessionContainer; 20 | public: 21 | CSosSessionManager(boost::asio::io_service *io_service); 22 | virtual void OnConnected(void *session); 23 | virtual int OnConnect(const std::string &name, const std::string &addr, bool autoreconnect = false, int heartbeat = 0, bool addr_reuse = true); 24 | virtual int DoConnect(const std::string &name, const std::string &addr, bool autoreconnect = false, int heartbeat = 0, bool addr_reuse = true); 25 | virtual void OnSendTo(const std::string &name, void *para, int timeout = 30); 26 | virtual void DoSendTo(const std::string &name, void *para, int timeout = 30); 27 | virtual int OnPeerClose(void *session); 28 | virtual void OnClose(const std::string &name, unsigned int connid); 29 | virtual void DoClose(const std::string &name, unsigned int connid); 30 | virtual ~CSosSessionManager(); 31 | virtual void Dump(); 32 | virtual void DoCheckSession(); 33 | 34 | private: 35 | boost::asio::io_service *io_service_; 36 | CSessionContainer *short_sessions_; 37 | CSessionContainer *persistent_sessions_; 38 | }; 39 | } 40 | } 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /frame/net/tcpsocketserver.cc: -------------------------------------------------------------------------------- 1 | #include "tcpsocketserver.h" 2 | #include "loghelper.h" 3 | #include "session.h" 4 | #include "protocolhelper.h" 5 | #include 6 | #include 7 | 8 | namespace ape { 9 | namespace net{ 10 | CTcpSocketServer::CTcpSocketServer(boost::asio::io_service &io_service, CNetServiceHolder *h): 11 | io_service_(io_service), acceptor_(io_service), holder_(h), running_(false) 12 | {} 13 | int CTcpSocketServer::StartServer(const std::string &addr) { 14 | BS_XLOG(XLOG_DEBUG,"CTcpSocketServer::%s, addr[%s]...\n",__FUNCTION__, addr.c_str()); 15 | char ip[32] = {0}; 16 | unsigned int port; 17 | 18 | if (0 != ape::protocol::ParseAddr(addr.c_str(), &proto_, ip, &port)) { 19 | BS_XLOG(XLOG_FATAL,"CTcpSocketServer::%s, bad addr[%s]...\n",__FUNCTION__, addr.c_str()); 20 | return -1; 21 | } 22 | boost::system::error_code ec; 23 | acceptor_.open(boost::asio::ip::tcp::v4(),ec); 24 | if(ec) { 25 | BS_SLOG(XLOG_ERROR,"CTcpSocketServer::"<<__FUNCTION__<<",open socket error:" <GetSessionCallBack(); 62 | CSession *session = ape::net::SessionFactory::CreateSession(proto_); 63 | session->Init(*(session_callback->GetIoService()), proto_, session_callback, NULL); 64 | acceptor_.async_accept(session->GetConnectPrt()->Socket(), 65 | MakeAllocHandler(alloc_, boost::bind(&CTcpSocketServer::HandleAccept, this, session, 66 | boost::asio::placeholders::error))); 67 | } 68 | 69 | void CTcpSocketServer::HandleAccept(CSession *session, const boost::system::error_code &err) { 70 | BS_XLOG(XLOG_DEBUG,"CTcpSocketServer::%s\n",__FUNCTION__); 71 | if (!err) { 72 | Connection_ptr conn = session->GetConnectPrt(); 73 | conn->Socket().get_io_service().post(boost::bind(&CSession::OnAccept, session)); 74 | conn->AsyncRead(); 75 | StartAccept(); 76 | } else if(running_) { 77 | BS_SLOG(XLOG_WARNING,"CTcpSocketServer::HandleAccept, error:"<< err.message() << "\n"); 78 | acceptor_.async_accept(session->GetConnectPrt()->Socket(), 79 | MakeAllocHandler(alloc_, boost::bind(&CTcpSocketServer::HandleAccept, this, session, 80 | boost::asio::placeholders::error))); 81 | } else { 82 | BS_SLOG(XLOG_WARNING,"CTcpSocketServer::HandleAccept, stop. error:"<< err.message() << "\n"); 83 | } 84 | } 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /frame/net/tcpsocketserver.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_MONITOR_SOCKET_SERVER_H_ 2 | #define _APE_MONITOR_SOCKET_SERVER_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "handleralloc.h" 8 | #include "protocol.h" 9 | #include "netservice.h" 10 | #include "session.h" 11 | 12 | namespace ape { 13 | namespace net{ 14 | class CTcpSocketServer { 15 | public: 16 | CTcpSocketServer(boost::asio::io_service &io_service, CNetServiceHolder *h); 17 | virtual ~CTcpSocketServer(){} 18 | virtual int StartServer(const std::string &addr); 19 | virtual void StopServer(); 20 | private: 21 | void StartAccept(); 22 | void HandleStop(); 23 | void HandleAccept(CSession *session, const boost::system::error_code &err); 24 | private: 25 | boost::asio::io_service &io_service_; 26 | boost::asio::ip::tcp::acceptor acceptor_; 27 | ape::common::CHandlerAllocator alloc_; 28 | CNetServiceHolder *holder_; 29 | ape::protocol::EProtocolType proto_; 30 | bool running_; 31 | }; 32 | } 33 | } 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /frame/protocol/baseparser.cc: -------------------------------------------------------------------------------- 1 | #include "baseparser.h" 2 | #include "loghelper.h" 3 | #include "httpparser.h" 4 | #include "thriftparser.h" 5 | //#include "ftdparser.h" 6 | 7 | namespace ape{ 8 | namespace protocol{ 9 | 10 | /** init static parser factory here, make sure the init sequence*/ 11 | 12 | ParserFactory *ParserFactory::factories_[E_PROTOCOL_ALL] = {NULL}; 13 | HttpParserFactory HttpParserFactory::http_parser_factory_; 14 | ThriftParserFactory ThriftParserFactory::thrift_parser_factory_; 15 | //FtdParserFactory FtdParserFactory::ftd_parser_factory_; 16 | 17 | CBaseParser *ParserFactory::CreateParser(EProtocolType protocol) { 18 | if (protocol >= E_PROTOCOL_ALL || factories_[protocol] == NULL) { 19 | BS_XLOG(XLOG_ERROR, "ParserFactory::%s, bad protocol[%d]\n", __FUNCTION__, protocol); 20 | return NULL; 21 | } 22 | 23 | return factories_[protocol]->CreateParser(); 24 | } 25 | void ParserFactory::RegisterFactory(EProtocolType protocol, ParserFactory*factory) { 26 | factories_[protocol] = factory; 27 | } 28 | void ParserFactory::Dump() 29 | { 30 | for (int i = 0; i < E_PROTOCOL_ALL; ++i) { 31 | fprintf(stdout, "ParserFactory::%s, protocol[%d], factory[0X%0X]\n", __FUNCTION__, i, factories_[i]); 32 | } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /frame/protocol/baseparser.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_BASE_PARSER_H_ 2 | #define _APE_BASE_PARSER_H_ 3 | #include "events.h" 4 | #include "buffer.h" 5 | #include "protocol.h" 6 | #include 7 | #include 8 | 9 | namespace ape{ 10 | namespace protocol{ 11 | 12 | class CBaseParser { 13 | public: 14 | virtual ape::message::SNetMessage *CreateMessage() = 0; 15 | virtual ape::message::SNetMessage *CreateHeartBeatMessage(ape::message::SNetMessage::SMessageDirection direction = ape::message::SNetMessage::E_Request) = 0; 16 | /** return value p 17 | p == NULL //error 18 | p == buf incomplete packet, continue to read 19 | p == buf + len //complete 20 | p < buf + len //more than one packet; p point to the next packet address 21 | */ 22 | virtual const char *Decode(const char *buf, int len, ape::message::SNetMessage *msg) = 0; 23 | virtual int Encode(const ape::message::SNetMessage *msg, ape::common::CBuffer *out) = 0; 24 | virtual void Release() = 0; 25 | virtual ~CBaseParser() {} 26 | }; 27 | class ParserFactory { 28 | public: 29 | ParserFactory() {} 30 | virtual ~ParserFactory() {} 31 | virtual CBaseParser *CreateParser() = 0; 32 | void RegisterFactory(EProtocolType protocol, ParserFactory*factory); 33 | static CBaseParser *CreateParser(EProtocolType protocol); 34 | static void Dump(); 35 | private: 36 | static ParserFactory *factories_[E_PROTOCOL_ALL]; 37 | }; 38 | 39 | 40 | } 41 | } 42 | #endif 43 | 44 | -------------------------------------------------------------------------------- /frame/protocol/httpparser.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_HTTP_PARSER_H_ 2 | #define _APE_HTTP_PARSER_H_ 3 | #include "baseparser.h" 4 | #include "httpmessage.h" 5 | #include "loghelper.h" 6 | #include 7 | 8 | namespace ape{ 9 | namespace protocol{ 10 | 11 | class CHttpParser : public CBaseParser{ 12 | public: 13 | CHttpParser(); 14 | virtual ape::message::SNetMessage *CreateMessage() {return new ape::message::SHttpMessage;} 15 | virtual ape::message::SNetMessage *CreateHeartBeatMessage(ape::message::SNetMessage::SMessageDirection direction = ape::message::SNetMessage::E_Request); 16 | virtual const char *Decode(const char *buf, int len, ape::message::SNetMessage *e); 17 | virtual int Encode(const ape::message::SNetMessage *e, ape::common::CBuffer *out); 18 | virtual void Release() {delete this;} 19 | virtual ~CHttpParser() {} 20 | private: 21 | void ParseHeader(const std::string &key, const std::string &value, ape::message::SHttpMessage *message); 22 | int EncodeRequest(const ape::message::SHttpMessage *msg, ape::common::CBuffer *out); 23 | int EncodeResponse(const ape::message::SHttpMessage *msge, ape::common::CBuffer *out); 24 | void DecodeCookie(const char *buf, int len, ape::message::SHttpMessage *message); 25 | private: 26 | static std::map sm_default_header_; 27 | static std::map sm_default_request_header_; 28 | std::list default_header_list_; 29 | int contentlen_; 30 | bool ischunked_; 31 | }; 32 | 33 | class HttpParserFactory: public ParserFactory { 34 | public: 35 | HttpParserFactory() { 36 | ParserFactory::RegisterFactory(E_PROTOCOL_HTTP, this); 37 | } 38 | virtual CBaseParser *CreateParser() { 39 | return new CHttpParser(); 40 | } 41 | virtual ~HttpParserFactory() {} 42 | private: 43 | static HttpParserFactory http_parser_factory_; 44 | }; 45 | } 46 | } 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /frame/protocol/protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_PTOTOCOL_PROTOCOL_H_ 2 | #define _APE_PTOTOCOL_PROTOCOL_H_ 3 | 4 | namespace ape { 5 | namespace protocol { 6 | typedef enum { E_TCP = 0, E_UDP, E_SOCKET } ESocketType; 7 | 8 | typedef enum { 9 | E_PROTOCOL_ERROR = 0, 10 | E_PROTOCOL_HTTP, 11 | E_PROTOCOL_THRIFT, 12 | E_PROTOCOL_FTD, 13 | E_PROTOCOL_ALL 14 | }EProtocolType; 15 | 16 | } 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /frame/protocol/protocolhelper.cc: -------------------------------------------------------------------------------- 1 | #include "protocolhelper.h" 2 | #include "httpsession.h" 3 | #include "httpparser.h" 4 | #include "thriftparser.h" 5 | 6 | namespace ape { 7 | namespace protocol { 8 | 9 | int ParseAddr(const char *addr, EProtocolType *proto, char *ip, unsigned int *port) { 10 | char pro[32] = {0}; 11 | int ret = sscanf(addr, "%31[^:]://%[^:]:%u", pro, ip, port); 12 | if (3 != ret && 2 != ret) { 13 | return -1; 14 | } 15 | 16 | if (0 == strncasecmp("http", pro, 4)) { 17 | if (ret == 2) { 18 | *port = 80; 19 | } 20 | *proto = E_PROTOCOL_HTTP; 21 | } else if (0 == strncasecmp("thrift", pro, 6)) { 22 | *proto = E_PROTOCOL_THRIFT; 23 | } else if (0 == strncasecmp("ftd", pro, 3)) { 24 | *proto = E_PROTOCOL_FTD; 25 | } else { 26 | return -2; 27 | } 28 | return 0; 29 | } 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /frame/protocol/protocolhelper.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_PTOTOCOL_PROTOCOL_HELPER_H_ 2 | #define _APE_PTOTOCOL_PROTOCOL_HELPER_H_ 3 | 4 | #include "protocol.h" 5 | #include "session.h" 6 | 7 | namespace ape { 8 | namespace protocol { 9 | int ParseAddr(const char *addr, EProtocolType *proto, char *ip, unsigned int *port); 10 | 11 | } 12 | } 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /frame/protocol/thriftparser.cc: -------------------------------------------------------------------------------- 1 | #include "thriftparser.h" 2 | #include "loghelper.h" 3 | #include "urlcode.h" 4 | #include 5 | #include 6 | #include 7 | 8 | namespace ape{ 9 | namespace protocol{ 10 | 11 | typedef struct stThriftHead { 12 | uint32_t size; 13 | uint16_t version; 14 | uint16_t type; 15 | uint32_t methodlen; 16 | }SThriftHead; 17 | enum ThriftMessageType { 18 | T_CALL = 1, 19 | T_REPLY = 2, 20 | T_EXCEPTION = 3, 21 | T_ONEWAY = 4 22 | }; 23 | static const int16_t VERSION_1 = (int16_t)0x8001; 24 | 25 | CThriftParser::CThriftParser() { 26 | } 27 | const char *CThriftParser::Decode(const char *buf, int len, ape::message::SNetMessage *msg) { 28 | uint32_t skip = sizeof(SThriftHead); 29 | if (len < skip) { 30 | return buf; 31 | } 32 | SThriftHead head = *((SThriftHead *)buf); 33 | head.size = ntohl(head.size); 34 | head.version = ntohs(head.version); 35 | head.type = ntohs(head.type); 36 | head.methodlen = ntohl(head.methodlen); 37 | if (head.size + 4 > len) { 38 | return buf; 39 | } 40 | 41 | ape::message::SThriftMessage *message = (ape::message::SThriftMessage *)msg; 42 | if (head.type == T_CALL || head.type == T_ONEWAY) { 43 | message->direction = ape::message::SNetMessage::E_Request; 44 | } else if (head.type == T_REPLY){ 45 | message->direction = ape::message::SNetMessage::E_Response; 46 | } else { 47 | BS_XLOG(XLOG_WARNING,"CThriftParser::%s, invalidate type[%d], method[%s]\n", __FUNCTION__, head.type, message->method.c_str()); 48 | return NULL; 49 | } 50 | if (skip + head.methodlen > len) { 51 | return NULL; 52 | } 53 | message->method.assign(buf + skip, head.methodlen); 54 | if (17 == head.methodlen && 0 == strncasecmp(message->method.c_str(), "AllsparkHeartBeat", 17)) { 55 | message->isheartbeat = true; 56 | } 57 | skip += head.methodlen; 58 | message->seqid = *((uint32_t *)(buf + skip)); 59 | skip += 4; 60 | uint32_t bodylen = head.size + 4 - skip; 61 | message->body.assign(buf + skip, bodylen); 62 | return buf + skip + bodylen; 63 | } 64 | int CThriftParser::Encode(const ape::message::SNetMessage *msg, ape::common::CBuffer *out) { 65 | ape::message::SThriftMessage *message = (ape::message::SThriftMessage *)msg; 66 | SThriftHead head; 67 | head.size = sizeof(SThriftHead) + message->method.length() + message->body.length(); // -4 + 4 68 | head.size = htonl(head.size); 69 | head.version = htons(VERSION_1); 70 | head.type = htons(message->IsReply() ? T_REPLY : T_CALL); 71 | head.methodlen = htonl(message->method.length()); 72 | out->append((char *)(&head), sizeof(SThriftHead)); 73 | out->append(message->method.c_str(), message->method.length()); 74 | uint32_t seqid = htonl(message->seqid); 75 | out->append((char *)&seqid, 4); 76 | out->append(message->body.c_str(), message->body.length()); 77 | return 0; 78 | } 79 | 80 | ape::message::SNetMessage *CThriftParser::CreateHeartBeatMessage(ape::message::SNetMessage::SMessageDirection direction) { 81 | ape::message::SThriftMessage *msg = new ape::message::SThriftMessage; 82 | msg->method = "HeartBeat"; 83 | msg->seqid = 0; 84 | msg->direction = direction; 85 | msg->isheartbeat = true; 86 | return msg; 87 | } 88 | } 89 | } 90 | 91 | -------------------------------------------------------------------------------- /frame/protocol/thriftparser.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_THRIFT_PARSER_H_ 2 | #define _APE_COMMON_THRIFT_PARSER_H_ 3 | #include "baseparser.h" 4 | #include "thriftmessage.h" 5 | 6 | namespace ape{ 7 | namespace protocol{ 8 | 9 | class CThriftParser : public CBaseParser{ 10 | public: 11 | CThriftParser(); 12 | virtual ape::message::SNetMessage *CreateMessage() {return new ape::message::SThriftMessage;} 13 | virtual ape::message::SNetMessage *CreateHeartBeatMessage(ape::message::SNetMessage::SMessageDirection direction = ape::message::SNetMessage::E_Request); 14 | virtual const char *Decode(const char *buf, int len, ape::message::SNetMessage *e); 15 | virtual int Encode(const ape::message::SNetMessage *e, ape::common::CBuffer *out); 16 | virtual void Release() {delete this;} 17 | virtual ~CThriftParser() {} 18 | }; 19 | 20 | class ThriftParserFactory: public ParserFactory { 21 | public: 22 | ThriftParserFactory() { 23 | ParserFactory::RegisterFactory(E_PROTOCOL_THRIFT, this); 24 | } 25 | virtual CBaseParser *CreateParser() { 26 | return new CThriftParser(); 27 | } 28 | virtual ~ThriftParserFactory() {} 29 | private: 30 | static ThriftParserFactory thrift_parser_factory_; 31 | }; 32 | } 33 | } 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /frame/session/httpsession.cc: -------------------------------------------------------------------------------- 1 | #include "httpsession.h" 2 | #include "sessionmanager.h" 3 | #include "loghelper.h" 4 | 5 | namespace ape{ 6 | namespace net{ 7 | 8 | CHttpSession::~CHttpSession() { 9 | while( !request_deque_.empty()) { 10 | if (NULL != request_deque_.begin()->response) { 11 | delete request_deque_.begin()->response; 12 | } 13 | request_deque_.pop_front(); 14 | } 15 | } 16 | void CHttpSession::OnRead(ape::message::SNetMessage *msg) { 17 | if (msg->direction == ape::message::SNetMessage::E_Request) { 18 | ((ape::message::SHttpMessage *)msg)->requestno = ++dwseq; 19 | request_deque_.push_back(SResponseItem(((ape::message::SHttpMessage *)msg)->requestno)); 20 | } 21 | CSession::OnRead(msg); 22 | } 23 | void CHttpSession::DoSendBack(void *para, bool close) { 24 | ape::message::SHttpMessage *message = (ape::message::SHttpMessage *)para; 25 | BS_XLOG(XLOG_DEBUG,"CHttpSession::%s, no[%d]\n", __FUNCTION__, message->requestno); 26 | std::deque::iterator itr = request_deque_.begin(); 27 | if (itr->no == message->requestno) { 28 | CSession::DoSendBack(message, !message->keepalive); 29 | request_deque_.pop_front(); 30 | while( !request_deque_.empty() && NULL != request_deque_.begin()->response) { 31 | message = (ape::message::SHttpMessage *)(request_deque_.begin()->response); 32 | CSession::DoSendBack(message, !message->keepalive); 33 | request_deque_.pop_front(); 34 | } 35 | return; 36 | } else { 37 | for(++itr; itr != request_deque_.end(); ++itr) { 38 | if(itr->no == message->requestno) { 39 | itr->response = message; 40 | return; 41 | } 42 | } 43 | } 44 | BS_XLOG(XLOG_WARNING,"CHttpSession::%s, no request to response, no[%d]\n", __FUNCTION__, message->requestno); 45 | delete message; 46 | } 47 | void CHttpSession::Dump() { 48 | CSession::Dump(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /frame/session/httpsession.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_HTTP_SESSION_H_ 2 | #define _APE_COMMON_HTTP_SESSION_H_ 3 | 4 | #include "session.h" 5 | #include "httpmessage.h" 6 | #include 7 | 8 | namespace ape{ 9 | namespace net{ 10 | 11 | class CHttpSession : public CSession { 12 | public: 13 | typedef struct stResponseItem { 14 | unsigned int no; 15 | ape::message::SNetMessage *response; 16 | stResponseItem() : no(0), response(NULL) {}; 17 | stResponseItem(unsigned int n) : no(n), response(NULL) {}; 18 | }SResponseItem; 19 | CHttpSession() : dwseq(0) {} 20 | virtual void OnRead(ape::message::SNetMessage *msg); 21 | virtual void DoSendBack(void *para, bool close = false); 22 | virtual void Dump(); 23 | virtual ~CHttpSession(); 24 | 25 | private: 26 | unsigned int dwseq; 27 | std::deque request_deque_; 28 | }; 29 | 30 | class HttpSessionFactory: public SessionFactory { 31 | public: 32 | HttpSessionFactory() { 33 | SessionFactory::RegisterFactory(ape::protocol::E_PROTOCOL_HTTP, this); 34 | } 35 | virtual CSession *CreateSession() { 36 | return new CHttpSession(); 37 | } 38 | virtual ~HttpSessionFactory() {} 39 | private: 40 | static HttpSessionFactory http_session_factory_; 41 | }; 42 | 43 | } 44 | } 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /frame/session/session.h: -------------------------------------------------------------------------------- 1 | #ifndef _APE_COMMON_SESSION_H_ 2 | #define _APE_COMMON_SESSION_H_ 3 | 4 | #include "connection.h" 5 | #include "sessioncallback.h" 6 | #include "protocol.h" 7 | #include "timermanager.h" 8 | 9 | namespace ape{ 10 | namespace net{ 11 | typedef boost::shared_ptr Connection_ptr; 12 | class CSession { 13 | public: 14 | typedef enum { WAITING = 0, CONNECTED, TIME_OUT, CONNECTING, CLOSED} EStatus; 15 | CSession(); 16 | virtual void Init(boost::asio::io_service &io, ape::protocol::EProtocolType pro, CSessionCallBack *o, 17 | ape::common::CTimerManager *tm = NULL, bool autoreconnect = false, int heartbeat = 0); 18 | virtual void Connect(const std::string &ip, unsigned int port); 19 | virtual void DoConnect(); 20 | virtual void ConnectResult(int result); 21 | virtual void OnAccept(); 22 | virtual void OnConnected(); 23 | virtual void OnPeerClose(); 24 | virtual void OnRead(ape::message::SNetMessage *msg); 25 | virtual void DoSendTo(void *para, int timeout); 26 | virtual void DoSendBack(void *para, bool close = false); 27 | virtual void Close(); 28 | virtual void Dump(); 29 | virtual ~CSession(); 30 | 31 | void SetOwner(CSessionCallBack *o) {owner_ = o;} 32 | CSessionCallBack *GetOwner(){return owner_;} 33 | void SetTimerManager(ape::common::CTimerManager *o) {timer_owner_ = o;} 34 | ape::common::CTimerManager *GetTimerManager(){return timer_owner_;} 35 | unsigned int Id() {return ptrconn_->Id();} 36 | Connection_ptr GetConnectPrt() const {return ptrconn_;} 37 | void SetAddr(const std::string &addr){addr_ = addr;} 38 | void SetName(const std::string &name){session_name_ = name;} 39 | const std::string &GetName() const {return session_name_;} 40 | const std::string &GetAddr() const {return addr_;} 41 | const std::string &GetRemoteIp(){return ptrconn_->GetRemoteIp();} 42 | unsigned int GetRemotePort(){return ptrconn_->GetRemotePort();} 43 | EStatus GetStatus(){return status_;} 44 | void SetStatus(EStatus s){status_ = s;} 45 | void CleanRequestAndCallBack(); 46 | private: 47 | void DealWaitingList(); 48 | void DoRequestTimeOut(void *para); 49 | void DoHeartBeat(); 50 | void DoSendRequest(ape::message::SNetMessage *msg, int timeout); 51 | private: 52 | EStatus status_; 53 | ape::protocol::EProtocolType proto_; 54 | Connection_ptr ptrconn_; 55 | CSessionCallBack *owner_; 56 | ape::common::CTimerManager *timer_owner_; 57 | std::string session_name_; 58 | std::string addr_; 59 | std::string ip_; 60 | unsigned int port_; 61 | bool autoreconnect_; 62 | int heartbeatinterval_; 63 | ape::common::CThreadTimer *timer_reconn_; 64 | ape::common::CThreadTimer *timer_heartbeat_; 65 | 66 | typedef std::multimap > RequestHistory; 67 | RequestHistory request_history_; 68 | typedef struct stReadyPacket { 69 | void *packet; 70 | int timeout; 71 | stReadyPacket() : packet(NULL), timeout(0) {} 72 | stReadyPacket(void *p, int t) : packet(p), timeout(t) {} 73 | }SReadyPacket; 74 | std::deque waitinglist_; 75 | 76 | }; 77 | //typedef boost::shared_ptr Session_Ptr; 78 | 79 | class SessionFactory { 80 | public: 81 | SessionFactory() {} 82 | virtual ~SessionFactory() {} 83 | virtual CSession *CreateSession() = 0; 84 | 85 | static void RegisterFactory(ape::protocol::EProtocolType protocol, SessionFactory *factory); 86 | static CSession *CreateSession(ape::protocol::EProtocolType protocol); 87 | private: 88 | static SessionFactory *factories_[ape::protocol::E_PROTOCOL_ALL]; 89 | }; 90 | 91 | } 92 | } 93 | #endif 94 | 95 | -------------------------------------------------------------------------------- /frame/session/sessionfactory.cc: -------------------------------------------------------------------------------- 1 | #include "session.h" 2 | #include "loghelper.h" 3 | #include "httpsession.h" 4 | 5 | namespace ape{ 6 | namespace net{ 7 | 8 | SessionFactory *SessionFactory::factories_[ape::protocol::E_PROTOCOL_ALL] = {NULL}; 9 | HttpSessionFactory HttpSessionFactory::http_session_factory_; 10 | 11 | CSession *SessionFactory::CreateSession(ape::protocol::EProtocolType protocol) { 12 | if (protocol >= ape::protocol::E_PROTOCOL_ALL) { 13 | BS_XLOG(XLOG_ERROR, "SessionFactory::%s, bad protocol[%d]\n", __FUNCTION__, protocol); 14 | return NULL; 15 | } 16 | 17 | return factories_[protocol] != NULL ? factories_[protocol]->CreateSession() : new CSession(); 18 | } 19 | void SessionFactory::RegisterFactory(ape::protocol::EProtocolType protocol, SessionFactory *factory) { 20 | factories_[protocol] = factory; 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /frame/unit_test/Makefile: -------------------------------------------------------------------------------- 1 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 2 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 3 | VER_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo 'X86-64'; else echo 'X86'; fi;)LIB_PT=$(shell bit=`getconf LONG_BIT`;if [ $$bit -eq 64 ]; then echo '_X86-64'; else echo ''; fi;) 4 | 5 | OS=$(shell uname)$(shell uname -a | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 6 | GCC=$(shell gcc --version | sed -n '1p' | perl -nle 'print $$1 if /\s+([0-9]\.\d+)/') 7 | CC=g++ 8 | VER=1.0.0.0 9 | GTEST=$(HOME)/local/gtest 10 | XLOG=$(HOME)/local/xlog 11 | MONGOC=$(HOME)/local/mongo-c-driver 12 | JSON=$(HOME)/local/json 13 | BOOST=$(HOME)/local/boost 14 | 15 | DIR_LIST = ../interface ../common ../net ../protocol ../tinyxml2 ../session ../event ../compressutil 16 | DIR_LIST += ./src ./helper 17 | 18 | OutPut=build/test/ 19 | NEW_CODE_PATH=./ 20 | #SOURCE CODE 21 | CC_SRC=$(shell find $(DIR_LIST) -name "*.cc" ) 22 | CC_SRC2=$(shell find $(DIR_LIST) -name "*.c" ) 23 | CC_SRC3=$(shell find $(DIR_LIST) -name "*.cpp" ) 24 | 25 | #OBJECTS 26 | CC_OBJS=$(patsubst %.cc,./$(OutPut)/%.o,$(CC_SRC)) 27 | CC_OBJS2=$(patsubst %.c,./$(OutPut)/%.o,$(CC_SRC2)) 28 | CC_OBJS3=$(patsubst %.cpp,./$(OutPut)/%.o,$(CC_SRC3)) 29 | OBJS=$(CC_OBJS) 30 | OBJS2=$(CC_OBJS2) 31 | OBJS3=$(CC_OBJS3) 32 | #DEPS 33 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 34 | 35 | define OBJ_MKDIR 36 | OBJ_DIRS+=./$(OutPut)/$(1) 37 | endef 38 | CC_DIRS=$(shell find $(DIR_LIST) -type d|sed -e '/.svn/d') 39 | #@echo $(CC_DIRS) 40 | $(foreach dir,$(CC_DIRS),$(eval $(call OBJ_MKDIR,$(dir)))) 41 | 42 | #DEPS 43 | DEPS=$(patsubst %.o,%.d,$(OBJS)) 44 | INC_DIR= 45 | #INCLUDE DIR 46 | define SAFE_MKDIR 47 | INC_DIR+=-I $(1) 48 | endef 49 | $(foreach dir,$(CC_DIRS),$(eval $(call SAFE_MKDIR,$(dir)))) 50 | 51 | 52 | INC_DIR+=-I$(GTEST)/include -I$(XLOG)/include #-I$(MONGOC)/include/libbson-1.0 #-I$(MONGOC)/include/libmongoc-1.0 53 | INC_DIR+= -I$(BOOST)/include 54 | #LIB_DIR 55 | 56 | LIB_DIR=-L $(GTEST)/lib $(XLOG)/lib/libxlog.a -L$(BOOST)/lib 57 | #LIB_DIR+=-L$(MONGOC)/lib #$(MONGOC)/lib/libbson-1.0.a 58 | 59 | LIBS=-lz -lgtest -lboost_thread -lboost_system -lpthread -Wall -ldl -Wl 60 | 61 | LDFLAGS=$(LIB_DIR) $(LIBS) 62 | CPPFLAGS=$(INC_DIR) $(DFLAGS) -DTIXML_USE_STL 63 | 64 | EXE1=./test 65 | 66 | all:$(EXE1) 67 | $(shell mkdir -p $(sort $(OBJ_DIRS))) 68 | include $(DEPS) 69 | 70 | $(EXE1):$(OBJS) $(OBJS2) $(OBJS3) 71 | $(CC) -g -O2 -o $@ $^ $(LDFLAGS) 72 | 73 | 74 | ./$(OutPut)/%.o:%.cc 75 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 76 | ./$(OutPut)/%.d:%.cc 77 | @set -e; rm -f $@; \ 78 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 79 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 80 | rm -f $@.$$$$ 81 | 82 | ./$(OutPut)/%.o:%.cpp 83 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 84 | ./$(OutPut)/%.d:%.cpp 85 | @set -e; rm -f $@; \ 86 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 87 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 88 | rm -f $@.$$$$ 89 | 90 | ./$(OutPut)/%.o:%.c 91 | $(CC) -g -O2 -o $@ -c -fPIC $< $(CPPFLAGS) 92 | ./$(OutPut)/%.d:%.c 93 | @set -e; rm -f $@; \ 94 | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ 95 | sed 's,.*\.o[ :]*,$(patsubst %.d,%.o,$@) $@ : ,g' < $@.$$$$ > $@; \ 96 | rm -f $@.$$$$ 97 | 98 | clean: 99 | rm -Rf ./build 100 | rm -rf $(EXE1) 101 | codelen: 102 | find $(NEW_CODE_PATH) \( -name "*.cc" -name "*.cpp" -o -name "*.h" -o -name "*.c" \) -exec cat {} \;|sed -e 's/\"/\n\"\n/g;s/\([^\/]\)\(\/\*\)/\1\n\2\n/g;'|sed -e '/^\"/{:a;N;/\".*\"/!ba;s/\".*\".*//;N;/\"/!d;b}' -e '/^\/\*/{s/\/\*.*\*\///;/\/\*/{:b;N;/\/\*.*\*\//!bb;s/\/\*.*\*\///}}' -e 's/\/\/.*//g' |sed -e '/^[[:space:]]*$$/d'|wc -l 103 | srczip: 104 | zip -r ./$(EXE1)_src_$(VER).zip * -x *.o *.d *.svn *.zip *.a *.so $(EXE1) *.svn-work *.svn-base *.so.* *.d.* *.svn/* 105 | binzip: 106 | if [ ! -d "release" ]; then mkdir release; fi; 107 | cd release;if [ ! -d "lib" ]; then mkdir lib; fi; 108 | cd release;if [ ! -d "plugin" ]; then mkdir plugin; fi; 109 | cp ./AutoTestServer ./release 110 | cp -r ./service ./release 111 | cp ./log.properties ./release/log.properties 112 | cp ./*.xml ./release/ 113 | 114 | ldd ./AutoTestServer>sys_so_111_232_876_23;cp `awk '{if(substr($$3,1,4)!="/lib"&&substr($$3,1,8)!="/usr/lib")print $$3}' sys_so_111_232_876_23` ./release/lib/;rm -rf sys_so_111_232_876_23 115 | cd release; zip -r ../AutoTestServer_$(VER)_$(OS)_Gcc$(GCC)_X86.zip * 116 | rm -rf release 117 | 118 | 119 | -------------------------------------------------------------------------------- /frame/unit_test/helper/buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _BUFFER_H_ 2 | #define _BUFFER_H_ 3 | #include 4 | #include 5 | 6 | 7 | #define BUFFER_ALIGN(size) (((size) + 2047) & ~2047) //SAP_ALIGN(size, 2048) 8 | class CBuffer { 9 | public: 10 | const static int BUFFER_INIT_CAPACITY = 10240; 11 | CBuffer(int capacity = BUFFER_INIT_CAPACITY) : capacity_(capacity), loc_(0) { 12 | base_ = (char *)malloc(capacity); 13 | } 14 | void add_capacity() { 15 | capacity_ += capacity_; 16 | base_ = (char *)realloc(base_, capacity_); 17 | } 18 | void add_capacity(int nLeft) { 19 | capacity_ += nLeft; 20 | base_ = (char *)realloc(base_,capacity_); 21 | } 22 | void append(const char *p) { 23 | append(p, strlen(p)); 24 | } 25 | void append(const char *p, int len) { 26 | if (loc_ + len > capacity_) { 27 | add_capacity(capacity_ + len + capacity_); 28 | } 29 | memcpy(base_ + loc_, p, len); 30 | loc_ += len; 31 | } 32 | char * base() const {return base_;} 33 | char * top() const {return base_ + loc_;} 34 | void inc_loc(unsigned int loc){loc_ += loc;} 35 | void reset_loc(int loc){loc_ = loc;} 36 | unsigned int capacity() const {return capacity_-loc_;} 37 | unsigned int len() const{return loc_;} 38 | ~CBuffer(){free(base_);} 39 | private: 40 | char *base_; 41 | unsigned int capacity_; 42 | unsigned int loc_; 43 | }; 44 | 45 | #endif 46 | 47 | 48 | -------------------------------------------------------------------------------- /frame/unit_test/helper/compresscoder.cc: -------------------------------------------------------------------------------- 1 | #include "compresscoder.h" 2 | #include "CompressUtil.h" 3 | #include 4 | 5 | namespace protocol { 6 | CCompressEncoder::CCompressEncoder(ECompressMethod method, EProtocolType type, const void *body, int bodylen) { 7 | SCompressHeader *header = (SCompressHeader *)buf_.base(); 8 | header->type = (uint8_t)type; 9 | header->method = (uint8_t)method; 10 | 11 | buf_.reset_loc(sizeof(SCompressHeader)); 12 | SetBody(body, bodylen); 13 | } 14 | 15 | void CCompressEncoder::SetBody(const void *data, int len) { 16 | if (len <= 0 || data == NULL) { 17 | return; 18 | } 19 | 20 | if (buf_.capacity() < len) { 21 | buf_.add_capacity(len + buf_.capacity()); 22 | } 23 | 24 | SCompressHeader *header = (SCompressHeader *)buf_.base(); 25 | unsigned char *headend = (unsigned char *)(buf_.base() + sizeof(SCompressHeader)); 26 | if (header->method == E_COMPRESS_ZERO) { 27 | unsigned long outlen = 0; 28 | CompressUtil::Zerocompress((const unsigned char*)data, (long unsigned int)len, headend, outlen); 29 | buf_.inc_loc(outlen); 30 | } else { 31 | memcpy(headend, data, len); 32 | buf_.inc_loc(len); 33 | } 34 | } 35 | 36 | 37 | CCompressDecoder::CCompressDecoder(const void *data, int len) : body_(NULL) { 38 | memset(&header_, 0, sizeof(SCompressHeader)); 39 | Decode(data, len); 40 | } 41 | int CCompressDecoder::Decode(const void *data, int len) { 42 | if (data == NULL || len == 0) { 43 | return -100; 44 | } 45 | if (len < sizeof(SCompressHeader)) { 46 | return -1; 47 | } 48 | memcpy(&header_, data, sizeof(SCompressHeader)); 49 | body_ = (const char *)data + sizeof(SCompressHeader); 50 | int bodylen = len - sizeof(SCompressHeader); 51 | 52 | if (header_.method == E_COMPRESS_ZERO) { 53 | unsigned long outlen = 0; 54 | CompressUtil::Zerodecompress((const unsigned char*)body_, (long unsigned int)bodylen, (unsigned char*)(buf_.base()), outlen); 55 | buf_.reset_loc(outlen); 56 | body_ = buf_.base(); 57 | return outlen; 58 | } 59 | 60 | return bodylen; 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /frame/unit_test/helper/compresscoder.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ape2010/ape_cpp_server/4372ca5e294abb4b56a12d9188550754ed5e0dfd/frame/unit_test/helper/compresscoder.h -------------------------------------------------------------------------------- /frame/unit_test/helper/fieldbuffer.cc: -------------------------------------------------------------------------------- 1 | #include "fieldbuffer.h" 2 | #include 3 | 4 | namespace protocol { 5 | 6 | CField::CField() { 7 | memset(buf_.base(), 0, sizeof(SFieldHeader)); 8 | buf_.inc_loc(sizeof(SFieldHeader)); 9 | } 10 | CField::CField(uint16_t fieldid) { 11 | memset(buf_.base(), 0, sizeof(SFieldHeader)); 12 | buf_.inc_loc(sizeof(SFieldHeader)); 13 | SetFieldId(fieldid); 14 | } 15 | void CField::SetFieldId(uint16_t fieldid) { 16 | SFieldHeader *header = (SFieldHeader *)buf_.base(); 17 | header->fieldid = htons(fieldid); 18 | } 19 | void CField::AddValue(int32_t value) { 20 | int32_t netvalue = htonl(value); 21 | AddValue((const char *)&netvalue, 4, 4); 22 | } 23 | void CField::AddUint16(uint16_t value) { 24 | int32_t netvalue = htonl(value); 25 | AddValue((const char *)&netvalue, 2, 2); 26 | } 27 | void CField::AddUint8(uint8_t value) { 28 | int32_t netvalue = htonl(value); 29 | AddValue((const char *)&netvalue, 1, 1); 30 | } 31 | void CField::AddValue(const std::string &value, int32_t maxlen) { 32 | AddValue(value.c_str(), value.length(), maxlen + 1); 33 | } 34 | void CField::AddValue(const char *value, int32_t maxlen) { 35 | AddValue(value, strlen(value), maxlen + 1); 36 | } 37 | void CField::AddValue(const void *value, int32_t len, int32_t maxlen) { 38 | if (buf_.capacity() < maxlen + sizeof(SFieldHeader)) { 39 | buf_.add_capacity(maxlen + sizeof(SFieldHeader) + buf_.capacity()); 40 | } 41 | SFieldHeader *header = (SFieldHeader *)buf_.base(); 42 | uint16_t fieldlen = ntohs(header->len); 43 | char *loc = buf_.base() + sizeof(SFieldHeader) + fieldlen; 44 | if (len < maxlen) { 45 | memcpy(loc, value, len); 46 | memset(loc + len, 0, maxlen - len); 47 | } else { 48 | memcpy(loc, value, maxlen); 49 | } 50 | header->len = htons(fieldlen + maxlen); 51 | buf_.inc_loc(maxlen); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /frame/unit_test/helper/fieldbuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef _FIELD_BUFFER_H_ 2 | #define _FIELD_BUFFER_H_ 3 | 4 | #include 5 | #include 6 | #include "buffer.h" 7 | 8 | namespace protocol { 9 | 10 | typedef struct stFieldHeader 11 | { 12 | uint16_t fieldid; 13 | uint16_t len; 14 | }SFieldHeader; 15 | 16 | class CField { 17 | public: 18 | CField(); 19 | CField(uint16_t fieldid); 20 | void SetFieldId(uint16_t fieldid); 21 | void AddValue(int32_t value); 22 | void AddUint16(uint16_t value); 23 | void AddUint8(uint8_t value); 24 | void AddValue(const std::string &value, int32_t maxlen); 25 | void AddValue(const char *value, int32_t maxlen); 26 | void AddValue(const void *value, int32_t len, int32_t maxlen); 27 | 28 | const void *GetBuffer() const {return buf_.base();} 29 | int GetLen() const {return buf_.len();} 30 | 31 | private: 32 | CBuffer buf_; 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /frame/unit_test/helper/ftdcoder.cc: -------------------------------------------------------------------------------- 1 | #include "ftdcoder.h" 2 | #include "fieldbuffer.h" 3 | #include 4 | 5 | namespace protocol { 6 | 7 | CFtdEncoder::CFtdEncoder() { 8 | memset(buf_.base(), 0, sizeof(SFtdHeader)); 9 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 10 | header->version = 1; 11 | header->chain = E_FTD_CHAIN_LAST; 12 | buf_.inc_loc(sizeof(SFtdHeader)); 13 | } 14 | CFtdEncoder::CFtdEncoder(uint32_t tid, uint32_t requestid, uint32_t seqno, const void *body, int bodylen) { 15 | memset(buf_.base(), 0, sizeof(SFtdHeader)); 16 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 17 | header->version = 1; 18 | header->chain = E_FTD_CHAIN_LAST; 19 | header->transactionid = htonl(tid); 20 | header->requestid = htonl(requestid); 21 | header->seqno = htonl(seqno); 22 | buf_.inc_loc(sizeof(SFtdHeader)); 23 | SetBody(body, bodylen); 24 | } 25 | CFtdEncoder::CFtdEncoder(uint32_t tid, uint32_t requestid, uint32_t seqno, EFtdStreamType streamtype, EFtdChainType chain, uint8_t version, const void *body, int bodylen) { 26 | memset(buf_.base(), 0, sizeof(SFtdHeader)); 27 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 28 | header->version = 1; 29 | header->chain = E_FTD_CHAIN_LAST; 30 | header->transactionid = htonl(tid); 31 | header->requestid = htonl(requestid); 32 | header->seqno = htonl(seqno); 33 | header->streamtype = htons(streamtype); 34 | header->version = version; 35 | header->chain = chain; 36 | buf_.inc_loc(sizeof(SFtdHeader)); 37 | SetBody(body, bodylen); 38 | } 39 | void CFtdEncoder::SetVersion(uint8_t version) { 40 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 41 | header->version = 1; 42 | } 43 | void CFtdEncoder::SetChain(EFtdChainType chain) { 44 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 45 | header->chain = chain; 46 | } 47 | void CFtdEncoder::SetStreamType(EFtdStreamType type) { 48 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 49 | header->streamtype = htons(type); 50 | } 51 | void CFtdEncoder::SetTid(uint32_t tid) { 52 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 53 | header->transactionid = htonl(tid); 54 | } 55 | void CFtdEncoder::SetSeqNo(uint32_t seqno) { 56 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 57 | header->seqno = htonl(seqno); 58 | } 59 | void CFtdEncoder::SetSequestId(uint32_t requestid) { 60 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 61 | header->requestid = htonl(requestid); 62 | } 63 | 64 | void CFtdEncoder::AddField(const void *data, uint16_t len) { 65 | if (len <= 0 || data == NULL) { 66 | return; 67 | } 68 | if (buf_.capacity() < len + sizeof(SFtdHeader)) { 69 | buf_.add_capacity(len + sizeof(SFtdHeader) + buf_.capacity()); 70 | } 71 | 72 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 73 | uint16_t bodylen = ntohs(header->bodylen); 74 | char *loc = buf_.base() + sizeof(SFtdHeader) + bodylen; 75 | memcpy(loc, data, len); 76 | 77 | uint16_t fieldcount = ntohs(header->fieldcount) + 1; 78 | header->fieldcount = htons(fieldcount); 79 | 80 | header->bodylen = htons(len + bodylen); 81 | buf_.inc_loc(len); 82 | } 83 | void CFtdEncoder::SetBody(const void *data, int len) { 84 | if (len <= 0 || data == NULL) { 85 | return; 86 | } 87 | if (buf_.capacity() < len) { 88 | buf_.add_capacity(len + buf_.capacity()); 89 | } 90 | 91 | uint16_t fieldcount = 0; 92 | const char *p = (const char *)data; 93 | const char *end = (const char *)data + len; 94 | while(p < end) { 95 | SFieldHeader *fieldheader = (SFieldHeader *)p; 96 | p += ntohs(fieldheader->len) + sizeof(SFieldHeader); 97 | ++fieldcount; 98 | } 99 | 100 | SFtdHeader *header = (SFtdHeader *)buf_.base(); 101 | header->fieldcount = htons(fieldcount); 102 | header->bodylen = htons(len); 103 | 104 | char *headend = buf_.base() + sizeof(SFtdHeader); 105 | memcpy(headend, data, len); 106 | buf_.inc_loc(len); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /frame/unit_test/helper/ftdcoder.h: -------------------------------------------------------------------------------- 1 | #ifndef _FTD_CODER_H_ 2 | #define _FTD_CODER_H_ 3 | 4 | #include 5 | #include "buffer.h" 6 | 7 | namespace protocol { 8 | typedef enum { 9 | E_FTD_CHAIN_CONTINUE = 'C', 10 | E_FTD_CHAIN_LAST = 'L' 11 | } EFtdChainType; 12 | 13 | typedef enum { 14 | E_FTD_STREAM_DIALOG = 1, /** 对话流*/ 15 | E_FTD_STREAM_PRIVATE = 2, /** 会员私有流*/ 16 | E_FTD_STREAM_PUBLIC = 3, /** 公共流*/ 17 | E_FTD_STREAM_QUERY = 4, /** 查询*/ 18 | E_FTD_STREAM_USER = 5, /** 交易员私有流*/ 19 | E_FTD_STREAM_FORQUOTE = 6 /** 询价流*/ 20 | }EFtdStreamType; 21 | 22 | typedef struct stFtdHeader { 23 | uint8_t version; /** 版本号 1 二进制无符号整数。目前版本为1*/ 24 | uint8_t chain; /** 报文链 1 ASCII码字符。*/ 25 | uint16_t streamtype; /** 序列类别号 2 二进制无符号短整数。*/ 26 | uint32_t transactionid; /**(TID) FTD信息正文类型 4 二进制无符号整数。*/ 27 | uint32_t seqno; /**(SeqNo) 序列号 4 二进制无符号整数。*/ 28 | uint16_t fieldcount; /** 数据域数量 2 二进制无符号短整数。*/ 29 | uint16_t bodylen; /** FTDC信息正文长度 2 二进制无符号短整数。以字节为单位。*/ 30 | uint32_t requestid; /** 请求编号(由发送请求者维护,应答中会带回) 4 二进制无符号整数。*/ 31 | }SFtdHeader; 32 | 33 | class CFtdEncoder { 34 | public: 35 | CFtdEncoder(); 36 | CFtdEncoder(uint32_t tid, uint32_t requestid, uint32_t seqno, const void *body = NULL, int bodylen = 0); 37 | CFtdEncoder(uint32_t tid, uint32_t requestid, uint32_t seqno, EFtdStreamType streamtype=E_FTD_STREAM_DIALOG, EFtdChainType chain=E_FTD_CHAIN_LAST, uint8_t version=1, const void *body = NULL, int bodylen = 0); 38 | void SetVersion(uint8_t version); 39 | void SetChain(EFtdChainType chain); 40 | void SetStreamType(EFtdStreamType type); 41 | void SetTid(uint32_t tid); 42 | void SetSeqNo(uint32_t seqno); 43 | void SetSequestId(uint32_t requestid); 44 | void AddField(const void *data, uint16_t len); 45 | virtual void SetBody(const void *data, int len); 46 | 47 | const void *GetBuffer() const {return buf_.base();} 48 | int GetLen() const {return buf_.len();} 49 | 50 | private: 51 | CBuffer buf_; 52 | }; 53 | 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /frame/unit_test/helper/ftdfunc.h: -------------------------------------------------------------------------------- 1 | #include "ftdcoder.h" 2 | #include "fieldbuffer.h" 3 | #include "compresscoder.h" 4 | #include "xmpcoder.h" 5 | #include "loghelper.h" 6 | 7 | const uint32_t FTD_TID_ReqUserLogin = 0x00001001; 8 | const uint32_t FTD_TID_ReqUserLogout=0x00001003; 9 | 10 | const uint32_t FTD_FID_Dissemination=0x0001; 11 | const uint32_t FTD_FID_ReqUserLogin = 0x000A; 12 | const uint32_t FTD_FID_ReqUserLogout=0x000C; 13 | 14 | /* 15 | ///信息分发 16 | ///序列系列号 CSequenceSeriesType SequenceSeries; UFWordType 17 | ///序列号 CSequenceNoType SequenceNo; UFIntType 18 | */ 19 | /* 20 | ///交易日 CDateType TradingDay; DefineStringType(8,DateType) 21 | ///交易用户代码 CUserIDType UserID; DefineStringType(15,UserIDType) 22 | ///会员代码 CParticipantIDType ParticipantID; DefineStringType(10,ParticipantIDType) 23 | ///密码 CPasswordType Password; DefineStringType(40,PasswordType) 24 | ///用户端产品信息 CProductInfoType UserProductInfo; DefineStringType(40,ProductInfoType) 25 | ///接口端产品信息 CProductInfoType InterfaceProductInfo; DefineStringType(40,ProductInfoType) 26 | ///协议信息 CProtocolInfoType ProtocolInfo; DefineStringType(40,ProtocolInfoType) 27 | ///数据中心代码 CDataCenterIDType DataCenterID; DefineUFType(UFIntType,DataCenterIDType) 28 | */ 29 | static void CreateUserLoginFtpPacket(protocol::CFtdEncoder &encdoer) { 30 | protocol::CField field(FTD_FID_ReqUserLogin); 31 | 32 | field.AddValue("20120425", 8); 33 | field.AddValue("001002", 15); 34 | field.AddValue("0010", 10); 35 | field.AddValue("111111", 40); 36 | field.AddValue("UserProductInfo", 40); 37 | field.AddValue("InterfaceProductInfo", 40); 38 | field.AddValue("ProtocolInfo", 40); 39 | field.AddValue(1); 40 | 41 | protocol::CField disseminationField(FTD_FID_Dissemination); 42 | disseminationField.AddUint16(100); 43 | disseminationField.AddUint16(0); 44 | BS_XLOG(XLOG_DEBUG, "%s, sizeof(SFieldHeader)[%d], field_len[%d], field:\n%s\n", __FUNCTION__, sizeof(protocol::SFieldHeader), field.GetLen(), 45 | GetBinaryDumpInfo((const char *)(disseminationField.GetBuffer()), disseminationField.GetLen()).c_str()); 46 | 47 | 48 | encdoer.SetStreamType(protocol::E_FTD_STREAM_DIALOG); 49 | encdoer.SetTid(FTD_TID_ReqUserLogin); 50 | encdoer.SetSeqNo(1); 51 | encdoer.SetSequestId(2); 52 | encdoer.AddField(field.GetBuffer(), field.GetLen()); 53 | encdoer.AddField(disseminationField.GetBuffer(), disseminationField.GetLen()); 54 | } 55 | 56 | 57 | /* 58 | ///交易用户代码 CUserIDType UserID; 59 | ///会员代码 CParticipantIDType ParticipantID; 60 | */ 61 | static void CreateUserLogoutFtpPacket(protocol::CFtdEncoder &encdoer) { 62 | protocol::CField field(FTD_FID_ReqUserLogout); 63 | 64 | field.AddValue("001002", 15); 65 | field.AddValue("0010", 10); 66 | //BS_XLOG(XLOG_DEBUG, "%s, sizeof(SFieldHeader)[%d], field_len[%d], field:\n%s\n", __FUNCTION__, sizeof(protocol::SFieldHeader), field.GetLen(), 67 | // GetBinaryDumpInfo((const char *)(field.GetBuffer()), field.GetLen()).c_str()); 68 | 69 | encdoer.SetStreamType(protocol::E_FTD_STREAM_DIALOG); 70 | encdoer.SetTid(FTD_TID_ReqUserLogout); 71 | encdoer.SetSeqNo(2); 72 | encdoer.SetSequestId(3); 73 | encdoer.AddField(field.GetBuffer(), field.GetLen()); 74 | encdoer.AddField(field.GetBuffer(), field.GetLen()); 75 | } 76 | 77 | static void CreateXmpPacket(const protocol::CFtdEncoder &encoder, protocol::CXmpEncoder &xmp, protocol::ECompressMethod compress_method=protocol::E_COMPRESS_NONE) { 78 | BS_XLOG(XLOG_DEBUG, "%s, sizeof(SFtdHeader)[%d], ftd_len[%d], ftd:\n%s\n", __FUNCTION__, sizeof(protocol::SFtdHeader), encoder.GetLen(), 79 | GetBinaryDumpInfo((const char *)(encoder.GetBuffer()), encoder.GetLen()).c_str()); 80 | 81 | protocol::CCompressEncoder compress(compress_method); 82 | //protocol::CCompressEncoder compress(protocol::E_COMPRESS_NONE); 83 | compress.SetBody(encoder.GetBuffer(), encoder.GetLen()); 84 | BS_XLOG(XLOG_DEBUG, "%s, sizeof(SCompressHeader)[%d], compress_len[%d], ftd:\n%s\n", __FUNCTION__, sizeof(protocol::SCompressHeader), compress.GetLen(), 85 | GetBinaryDumpInfo((const char *)(compress.GetBuffer()), compress.GetLen()).c_str()); 86 | 87 | xmp.SetXmpType(protocol::XMPTypeSCP); 88 | const char *ext_header = "extxmpheader"; 89 | xmp.SetExHeader(protocol::XMPTagCompressMethod, ext_header, strlen(ext_header)); 90 | xmp.SetBody(compress.GetBuffer(), compress.GetLen()); 91 | //BS_XLOG(XLOG_DEBUG, "%s, xmp_len[%d], xmp:\n%s\n", __FUNCTION__, xmp.GetLen(), GetBinaryDumpInfo((const char *)(xmp.GetBuffer()), xmp.GetLen()).c_str()); 92 | 93 | /* 94 | protocol::CCompressDecoder compressdecoder; 95 | int len = compressdecoder.Decode(compress.GetBuffer(), compress.GetLen()); 96 | BS_XLOG(XLOG_DEBUG, "%s, compressdecoder:\n%s\n", __FUNCTION__, GetBinaryDumpInfo((const char *)(compressdecoder.GetBody()), len).c_str()); 97 | exit(-1); 98 | */ 99 | } 100 | -------------------------------------------------------------------------------- /frame/unit_test/helper/xmpcoder.cc: -------------------------------------------------------------------------------- 1 | #include "xmpcoder.h" 2 | #include 3 | 4 | namespace protocol { 5 | CXmpEncoder::CXmpEncoder() { 6 | memset(buf_.base(), 0, sizeof(SXmpHeader)); 7 | buf_.reset_loc(sizeof(SXmpHeader)); 8 | } 9 | CXmpEncoder::CXmpEncoder(EXmpType type) { 10 | memset(buf_.base(), 0, sizeof(SXmpHeader)); 11 | SXmpHeader *header = (SXmpHeader *)buf_.base(); 12 | header->type = type; 13 | buf_.reset_loc(sizeof(SXmpHeader)); 14 | } 15 | void CXmpEncoder::SetXmpType(EXmpType type) { 16 | SXmpHeader *header = (SXmpHeader *)buf_.base(); 17 | header->type = type; 18 | } 19 | void CXmpEncoder::SetExHeader(EXmpTagType tag, const void *data, int datalen) { 20 | SXmpHeader *header = (SXmpHeader *)buf_.base(); 21 | uint16_t bodylen = ntohs(header->bodylen); 22 | int len = datalen + 2; 23 | if (buf_.capacity() < len) { 24 | buf_.add_capacity(len + buf_.capacity()); 25 | } 26 | 27 | char *headend = buf_.base() + sizeof(SXmpHeader) + header->extheaderlen; 28 | if (bodylen > 0) { 29 | memmove(headend + len, headend, bodylen); 30 | } 31 | 32 | uint8_t tmplen = (uint8_t)datalen; 33 | memcpy(headend, &tag, 1); 34 | memcpy(++headend, (char *)(&tmplen), 1); 35 | memcpy(++headend, data, datalen); 36 | header->extheaderlen += (uint8_t)len; 37 | buf_.inc_loc(len); 38 | } 39 | 40 | void CXmpEncoder::SetBody(const void *data, int len) { 41 | SXmpHeader *header = (SXmpHeader *)buf_.base(); 42 | if (buf_.capacity() < len) { 43 | buf_.add_capacity(len + buf_.capacity()); 44 | } 45 | 46 | char *headend = buf_.base() + sizeof(SXmpHeader) + header->extheaderlen; 47 | memcpy(headend, data, len); 48 | header->bodylen = htons(len); 49 | buf_.inc_loc(len); 50 | } 51 | 52 | 53 | 54 | CXmpDecoder::CXmpDecoder(const void *data, int len) : body_(NULL) { 55 | memset(&header_, 0, sizeof(SXmpHeader)); 56 | memset(&ext_header_, 0, sizeof(SXmpExtHeader)); 57 | Decode(data, len); 58 | } 59 | int CXmpDecoder::Decode(const void *data, int len) { 60 | if (data == NULL || len == 0) { 61 | return -100; 62 | } 63 | if (len < sizeof(SXmpHeader)) { 64 | return -1; 65 | } 66 | memcpy(&header_, data, sizeof(SXmpHeader)); 67 | header_.bodylen = ntohs(header_.bodylen); 68 | 69 | if (len < sizeof(SXmpHeader) + header_.extheaderlen + header_.bodylen) { 70 | return -1; 71 | } 72 | const char *headend = (const char *)data + sizeof(SXmpHeader); 73 | 74 | if (header_.extheaderlen > 0) { 75 | memcpy(&ext_header_, headend, 2); 76 | if (ext_header_.taglen + 2 == header_.extheaderlen) { 77 | return -100; 78 | } 79 | memcpy(ext_header_.data, headend + 2, ext_header_.taglen); 80 | } 81 | 82 | body_ = headend + header_.extheaderlen; 83 | return header_.bodylen; 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /frame/unit_test/helper/xmpcoder.h: -------------------------------------------------------------------------------- 1 | #ifndef _XMP_CODER_H_ 2 | #define _XMP_CODER_H_ 3 | 4 | #include 5 | #include "buffer.h" 6 | 7 | namespace protocol { 8 | #define XMP_PACKAGE_MAX_SIZE 4096 9 | #define XMP_EXTHEAD_MAX_SIZE 127 10 | 11 | typedef enum { 12 | XMPTypeNone = 0X00, 13 | XMPTypeXTP = 0X01, 14 | XMPTypeSCP = 0X02 15 | } EXmpType; 16 | typedef enum { 17 | XMPTagNone = 0X00, 18 | XMPTagDatetime = 0X01, 19 | XMPTagCompressMethod = 0X02, 20 | XMPTagTransactionId = 0x03, 21 | XMPTagSessionState = 0x04, 22 | XMPTagKeepAlive = 0x05, 23 | XMPTagTradedate = 0x06, 24 | XMPTagHeartbeatTimeOut = 0x07 25 | } EXmpTagType; 26 | 27 | typedef struct stXmpHeader { 28 | uint8_t type; 29 | uint8_t extheaderlen; 30 | uint16_t bodylen; 31 | }SXmpHeader; 32 | 33 | typedef struct stXMPExtHeader { 34 | uint8_t tag; 35 | uint8_t taglen; 36 | uint8_t data[XMP_EXTHEAD_MAX_SIZE]; 37 | }SXmpExtHeader; 38 | 39 | class CXmpEncoder { 40 | public: 41 | CXmpEncoder(); 42 | CXmpEncoder(EXmpType type); 43 | void SetXmpType(EXmpType type); 44 | void SetExHeader(EXmpTagType tag, const void *data, int len); 45 | virtual void SetBody(const void *data, int len); 46 | 47 | const void *GetBuffer() const {return buf_.base();} 48 | int GetLen() const {return buf_.len();} 49 | 50 | private: 51 | CBuffer buf_; 52 | }; 53 | 54 | class CXmpDecoder { 55 | public: 56 | CXmpDecoder(const void *data=NULL, int len=0); 57 | int Decode(const void *data, int len); 58 | const char *GetBody() const {return body_;} 59 | EXmpType GetXmpType() const {return (EXmpType)(header_.type);} 60 | EXmpTagType GetExtTag() const {return (EXmpTagType)(ext_header_.tag);} 61 | const char *GetExtData() const {return (const char *)(ext_header_.data);} 62 | int GetExtDataLen() const {return ext_header_.taglen;} 63 | 64 | private: 65 | SXmpHeader header_; 66 | SXmpExtHeader ext_header_; 67 | const char *body_; 68 | }; 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /frame/unit_test/log.properties: -------------------------------------------------------------------------------- 1 | log4cplus.logger.business=ALL,BUSINESS 2 | log4cplus.additivity.business=false 3 | 4 | log4cplus.appender.STDOUT=log4cplus::ConsoleAppender 5 | log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout 6 | log4cplus.appender.STDOUT.layout.ConversionPattern=%-6p[%t][%D{%m/%d/%y %H:%M:%S %Q}]%m 7 | 8 | log4cplus.appender.BUSINESS=log4cplus::RollingFileAppender 9 | log4cplus.appender.BUSINESS.File=./log/all.log 10 | log4cplus.appender.BUSINESS.MaxFileSize=5MB 11 | log4cplus.appender.BUSINESS.MaxBackupIndex=5 12 | log4cplus.appender.BUSINESS.layout=log4cplus::PatternLayout 13 | log4cplus.appender.BUSINESS.layout.ConversionPattern=%-6p[%t] [%D{%m/%d/%y %H:%M:%S %Q}] %m 14 | 15 | -------------------------------------------------------------------------------- /frame/unit_test/src/controller.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_CONTROLLER_H_ 2 | #define TEST_CONTROLLER_H_ 3 | 4 | //#define Test_QUEUE 5 | //#define Test_Thread 6 | //#define Test_Timer 7 | //#define Test_HttpRequestDecoder 8 | //#define Test_HttpResponseDecoder 9 | //#define Test_HttpResponseEncoder 10 | //#define Test_HttpRequestEncoder 11 | //#define Test_XmlConfigParser 12 | //#define Test_ParserFactory 13 | //#define Test_XmpMessage 14 | //#define Test_Compress_Message 15 | //#define Test_Ftd_Message 16 | 17 | #endif -------------------------------------------------------------------------------- /frame/unit_test/src/func.h: -------------------------------------------------------------------------------- 1 | #ifndef _T_FUNC_H_ 2 | #define _T_FUNC_H_ 3 | 4 | #include 5 | #include 6 | #include "loghelper.h" 7 | #include 8 | 9 | template 10 | void ExecuteYali(Func func, const char *tips, int count = 100000) { 11 | boost::function do_func = boost::function(func); 12 | struct timeval before, end; 13 | struct timezone tz; 14 | gettimeofday(&before, &tz); 15 | BS_XLOG(XLOG_FATAL,"start[%s], count[%d] time[%u,%u]\n",tips,count,before.tv_sec,before.tv_usec); 16 | 17 | for(int i = 0; i < count; ++i) { 18 | do_func(); 19 | } 20 | 21 | gettimeofday(&end, &tz); 22 | float interval = (end.tv_sec - before.tv_sec) + (float)(end.tv_usec - before.tv_usec)/1000000; 23 | BS_XLOG(XLOG_FATAL,"end[%s], time[%u,%u], req/s[%.3f]\n\n",tips,end.tv_sec,end.tv_usec,(float)count/interval); 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /frame/unit_test/src/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "gtest/gtest.h" 5 | #include "loghelper.h" 6 | #include "timermanager.h" 7 | #include "threadtimer.h" 8 | #include "events.h" 9 | #include "testthread.h" 10 | 11 | 12 | using namespace ape::common; 13 | using ::testing::EmptyTestEventListener; 14 | using ::testing::InitGoogleTest; 15 | using ::testing::Test; 16 | using ::testing::TestCase; 17 | using ::testing::TestEventListeners; 18 | using ::testing::TestInfo; 19 | using ::testing::TestPartResult; 20 | using ::testing::UnitTest; 21 | 22 | void clean() { 23 | BS_XLOG(XLOG_DEBUG," ========== %s ========\n", __FUNCTION__); 24 | TestThreadGroup::Release(); 25 | XLOG_DESTROY(); 26 | } 27 | 28 | int main(int argc, char **argv) { 29 | XLOG_INIT("log.properties", true); 30 | XLOG_REGISTER(BUSINESS_MODULE, "business"); 31 | BS_XLOG(XLOG_DEBUG," ========== %s ========\n", __FUNCTION__); 32 | 33 | 34 | atexit(clean); 35 | InitGoogleTest(&argc, argv); 36 | return RUN_ALL_TESTS(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_httprequestencoder.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "httpparser.h" 3 | #include "controller.h" 4 | #include "loghelper.h" 5 | 6 | #ifdef Test_HttpRequestEncoder 7 | using namespace ape::protocol; 8 | using namespace ape::message; 9 | using namespace ape::common; 10 | 11 | TEST(CHttpParser, EncodeRequest1) { 12 | CHttpParser encoder; 13 | SHttpMessage message; 14 | message.code = 0; 15 | message.keepalive = true; 16 | message.method = "POST"; 17 | message.httpversion = SHttpMessage::HTTP_1_1; 18 | message.url = "http://11.1.1.1:9000/hello"; 19 | message.body = "testbody"; 20 | 21 | CBuffer buf; 22 | EXPECT_EQ(0, encoder.Encode(&message, &buf)); 23 | message.Dump(); 24 | BS_XLOG(XLOG_DEBUG,"%s request:\n%s\n",__FUNCTION__, std::string(buf.base(), buf.len()).c_str()); 25 | } 26 | TEST(CHttpParser, EncodeRequest2) { 27 | CHttpParser encoder; 28 | SHttpMessage message; 29 | message.code = 0; 30 | message.keepalive = true; 31 | message.httpversion = SHttpMessage::HTTP_1_1; 32 | message.url = "http://11.1.1.1:9000"; 33 | message.body = "testbody"; 34 | 35 | CBuffer buf; 36 | EXPECT_EQ(0, encoder.Encode(&message, &buf)); 37 | message.Dump(); 38 | BS_XLOG(XLOG_DEBUG,"%s request:\n%s\n",__FUNCTION__, std::string(buf.base(), buf.len()).c_str()); 39 | } 40 | TEST(CHttpParser, EncodeRequest3) { 41 | CHttpParser encoder; 42 | SHttpMessage message; 43 | message.code = 0; 44 | message.keepalive = false; 45 | message.httpversion = SHttpMessage::HTTP_1_0; 46 | message.url = "http://"; 47 | 48 | CBuffer buf; 49 | EXPECT_EQ(0, encoder.Encode(&message, &buf)); 50 | message.Dump(); 51 | BS_XLOG(XLOG_DEBUG,"%s request:\n%s\n",__FUNCTION__, std::string(buf.base(), buf.len()).c_str()); 52 | } 53 | TEST(CHttpParser, EncodeRequest4) { 54 | CHttpParser encoder; 55 | SHttpMessage message; 56 | message.code = 0; 57 | message.keepalive = false; 58 | message.httpversion = SHttpMessage::HTTP_1_0; 59 | message.body = "testbody"; 60 | 61 | message.AddHeader("Content-Encoding", "gzip"); 62 | message.AddHeader("Accept-Language", "Accept-LanguageAccept-Language"); 63 | 64 | message.SetCookie("BDSVRTM", "aaaaaaa", "/", "", time(NULL) + 3600); 65 | message.SetCookie("H_PS_PSSID", "6225_6549_6249_1439_5225", "/", ".baidu.com"); 66 | 67 | CBuffer response; 68 | EXPECT_EQ(0, encoder.Encode(&message, &response)); 69 | message.Dump(); 70 | BS_XLOG(XLOG_DEBUG,"%s response:\n%s\n",__FUNCTION__, std::string(response.base(), response.len()).c_str()); 71 | 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_httpresponsedecoder.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "httpparser.h" 3 | #include "controller.h" 4 | #include "loghelper.h" 5 | 6 | #ifdef Test_HttpResponseDecoder 7 | using namespace ape::protocol; 8 | using namespace ape::message; 9 | 10 | TEST(CHttpParser, ResponseDecode1) { 11 | const char *packet = "HTTP/1.1 200 ok\r\n\ 12 | Date:Fri, 23 May 2014 06:36:18 GMT\r\n\ 13 | Set-Cookie:BDSVRTM=38; path=/; expires=Fri, 23 May 2014 06:36:18 GMT\r\n\ 14 | Set-Cookie:H_PS_PSSID=6225_6549_6249_1439_5225_6583_6505_6476_4760_6017_6427_6441_6529; path=/; domain=.baidu.com\r\n\ 15 | Connection:keep-alive\r\n\r\n"; 16 | 17 | int len = strlen(packet); 18 | CHttpParser decoder; 19 | SHttpMessage message; 20 | EXPECT_EQ(packet + len, decoder.Decode(packet, len, &message)); 21 | EXPECT_TRUE(message.keepalive); 22 | EXPECT_EQ(SHttpMessage::HTTP_1_1, message.httpversion); 23 | EXPECT_EQ(200, message.code); 24 | EXPECT_STREQ(message.headers["date"].c_str(), "Fri, 23 May 2014 06:36:18 GMT"); 25 | EXPECT_STREQ(message.headers["connection"].c_str(), "keep-alive"); 26 | message.Dump(); 27 | } 28 | 29 | //无HTTP版本号信息,error 30 | TEST(CHttpParser, ResponseDecode2) { 31 | const char *packet = "HTTP/1.0 302 rssss\r\n\ 32 | Date:Fri, 23 May 2014 06:36:18 GMT\r\n\ 33 | Set-Cookie:BDSVRTM=38; path=/; expires=Fri, 23 May 2014 06:36:18 GMT\r\n\ 34 | Set-Cookie:H_PS_PSSID=6225_6549_6249_1439_5225_6583_6505_6476_4760_6017_6427_6441_6529; path=/; domain=.baidu.com\r\n\ 35 | Connection:keep-alive\r\n\r\n"; 36 | 37 | int len = strlen(packet); 38 | CHttpParser decoder; 39 | SHttpMessage message; 40 | EXPECT_EQ(packet + len, decoder.Decode(packet, len, &message)); 41 | EXPECT_TRUE(message.keepalive); 42 | EXPECT_EQ(SHttpMessage::HTTP_1_0, message.httpversion); 43 | EXPECT_EQ(302, message.code); 44 | EXPECT_STREQ(message.headers["date"].c_str(), "Fri, 23 May 2014 06:36:18 GMT"); 45 | EXPECT_STREQ(message.headers["connection"].c_str(), "keep-alive"); 46 | message.Dump(); 47 | } 48 | TEST(CHttpParser, ResponseDecode3) { 49 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 50 | Content-Length:9\r\n\r\n\ 51 | post data"; 52 | 53 | int len = strlen(packet); 54 | CHttpParser decoder; 55 | SHttpMessage message; 56 | EXPECT_EQ(packet + len, decoder.Decode(packet, len, &message)); 57 | EXPECT_TRUE(message.keepalive); 58 | EXPECT_EQ(SHttpMessage::HTTP_1_1, message.httpversion); 59 | EXPECT_EQ(302, message.code); 60 | EXPECT_STREQ(message.body.c_str(), "post data"); 61 | message.Dump(); 62 | } 63 | TEST(CHttpParser, ResponseDecode4) { 64 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 65 | Transfer-Encoding:chunked\r\n\r\n\ 66 | 9\r\n\ 67 | post data\r\n\ 68 | 0\r\n"; 69 | 70 | int len = strlen(packet); 71 | CHttpParser decoder; 72 | SHttpMessage message; 73 | EXPECT_EQ(packet + len, decoder.Decode(packet, len, &message)); 74 | EXPECT_TRUE(message.keepalive); 75 | EXPECT_EQ(SHttpMessage::HTTP_1_1, message.httpversion); 76 | EXPECT_EQ(302, message.code); 77 | EXPECT_STREQ(message.body.c_str(), "post data"); 78 | message.Dump(); 79 | } 80 | TEST(CHttpParser, ResponseDecode5) { 81 | const char *packet = "HTTP/1.1302rssss\r\n\ 82 | Transfer-Encoding:chunked\r\n\r\n\ 83 | 9\r\n\ 84 | post data\r\n\ 85 | 0\r\n"; 86 | 87 | int len = strlen(packet); 88 | CHttpParser decoder; 89 | SHttpMessage message; 90 | EXPECT_EQ(NULL, decoder.Decode(packet, len, &message)); 91 | } 92 | TEST(CHttpParser, ResponseDecode6) { 93 | const char *packet = "HTTP/1.1 302rssss\r\n\ 94 | Transfer-Encoding:chunked\r\n\r\n\\r\n\ 95 | 9\r\n\ 96 | post data\r\n\ 97 | 0\r\n"; 98 | 99 | int len = strlen(packet); 100 | CHttpParser decoder; 101 | SHttpMessage message; 102 | EXPECT_EQ(NULL, decoder.Decode(packet, len, &message)); 103 | } 104 | TEST(CHttpParser, ResponseDecode7) { 105 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 106 | Transfer-Encoding:chunked\r\n\r\n\ 107 | 20\r\n\ 108 | post data\r\n\ 109 | 0\r\n"; 110 | 111 | int len = strlen(packet); 112 | CHttpParser decoder; 113 | SHttpMessage message; 114 | EXPECT_EQ(packet, decoder.Decode(packet, len, &message)); 115 | } 116 | 117 | TEST(CHttpParser, ResponseDecode8) { 118 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 119 | Content-Length:19\r\n\r\n\ 120 | post data"; 121 | 122 | int len = strlen(packet); 123 | CHttpParser decoder; 124 | SHttpMessage message; 125 | EXPECT_EQ(packet, decoder.Decode(packet, len, &message)); 126 | } 127 | 128 | TEST(CHttpParser, ResponseDecode9) { 129 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 130 | Content-Length:9\r\n\r\n\ 131 | post data"; 132 | int len = strlen(packet); 133 | 134 | char sz[10240] = {0}; 135 | memcpy(sz, packet, len); 136 | memcpy(sz + len, packet, len); 137 | memcpy(sz + 2 * len, packet, len / 2); 138 | CHttpParser decoder; 139 | SHttpMessage message; 140 | char *p = sz; 141 | for (int i = 0; i < 2; ++i) { 142 | char *last = p; 143 | p = (char *)decoder.Decode(p, strlen(p), &message); 144 | BS_XLOG(XLOG_DEBUG," ----------sz[%p], len[%d], last[%p], (last+len)[%p] p[%p], \n%s\n", 145 | sz, len, last, last + len, p, p); 146 | EXPECT_EQ(last + len, p); 147 | EXPECT_TRUE(message.keepalive); 148 | EXPECT_EQ(SHttpMessage::HTTP_1_1, message.httpversion); 149 | EXPECT_EQ(302, message.code); 150 | EXPECT_STREQ(message.body.c_str(), "post data"); 151 | message.Dump(); 152 | } 153 | EXPECT_EQ(p, decoder.Decode(p, strlen(p), &message)); 154 | } 155 | TEST(CHttpParser, ResponseDecode10) { 156 | const char *packet = "HTTP/1.1 302 rssss\r\n\ 157 | Transfer-Encoding:chunked\r\n\r\n\ 158 | 9\r\n\ 159 | post data\r\n\ 160 | 0\r\n"; 161 | int len = strlen(packet); 162 | 163 | char sz[10240] = {0}; 164 | memcpy(sz, packet, len); 165 | memcpy(sz + len, packet, len); 166 | memcpy(sz + 2 * len, packet, len / 2); 167 | CHttpParser decoder; 168 | char *p = sz; 169 | for (int i = 0; i < 2; ++i) { 170 | char *last = p; 171 | SHttpMessage message; 172 | p = (char *)decoder.Decode(p, strlen(p), &message); 173 | BS_XLOG(XLOG_DEBUG," -----%s-----sz[%p], len[%d], last[%p], (last+len)[%p] p[%p], \n%s\n", 174 | __FUNCTION__, sz, len, last, last + len, p, p); 175 | EXPECT_EQ(last + len, p); 176 | EXPECT_TRUE(message.keepalive); 177 | EXPECT_EQ(SHttpMessage::HTTP_1_1, message.httpversion); 178 | EXPECT_EQ(302, message.code); 179 | EXPECT_STREQ(message.body.c_str(), "post data"); 180 | message.Dump(); 181 | } 182 | SHttpMessage message; 183 | EXPECT_EQ(p, decoder.Decode(p, strlen(p), &message)); 184 | } 185 | #endif 186 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_httpresponseencoder.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "httpparser.h" 3 | #include "controller.h" 4 | #include "loghelper.h" 5 | 6 | #ifdef Test_HttpResponseEncoder 7 | using namespace ape::protocol; 8 | using namespace ape::message; 9 | using namespace ape::common; 10 | 11 | TEST(CHttpParser, Encode1) { 12 | CHttpParser encoder; 13 | SHttpMessage message; 14 | message.code = 200; 15 | message.keepalive = true; 16 | message.httpversion = SHttpMessage::HTTP_1_1; 17 | message.body = "testbody"; 18 | 19 | CBuffer response; 20 | EXPECT_EQ(0, encoder.Encode(&message, &response)); 21 | message.Dump(); 22 | BS_XLOG(XLOG_DEBUG,"%s response:\n%s\n",__FUNCTION__, std::string(response.base(), response.len()).c_str()); 23 | } 24 | TEST(CHttpParser, Encode2) { 25 | CHttpParser encoder; 26 | SHttpMessage message; 27 | message.code = 200; 28 | message.keepalive = false; 29 | message.httpversion = SHttpMessage::HTTP_1_0; 30 | message.body = "testbody"; 31 | 32 | message.AddHeader("Content-Encoding", "gzip"); 33 | message.AddHeader("Content-Type", "Content-TypeContent-TypeContent-Type"); 34 | 35 | message.SetCookie("BDSVRTM", "aaaaaaa", "/", "", time(NULL) + 3600); 36 | message.SetCookie("H_PS_PSSID", "6225_6549_6249_1439_5225", "/", ".baidu.com"); 37 | 38 | CBuffer response; 39 | EXPECT_EQ(0, encoder.Encode(&message, &response)); 40 | message.Dump(); 41 | BS_XLOG(XLOG_DEBUG,"%s response:\n%s\n",__FUNCTION__, std::string(response.base(), response.len()).c_str()); 42 | 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_parser_factory.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "controller.h" 3 | 4 | #ifdef Test_ParserFactory 5 | 6 | #include "loghelper.h" 7 | #include "baseparser.h" 8 | 9 | TEST(ParserFactory, CreateParser) { 10 | ape::protocol::CBaseParser *parser = ape::protocol::ParserFactory::CreateParser(ape::protocol::E_PROTOCOL_HTTP); 11 | BS_XLOG(XLOG_DEBUG, "%s, parser[0X%0X]\n", typeid(this).name(), parser); 12 | EXPECT_NE(NULL, (long)parser); 13 | } 14 | #endif 15 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_queue.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "msgqueueprio.h" 3 | #include "threadtimer.h" 4 | #include "controller.h" 5 | #include "loghelper.h" 6 | 7 | #ifdef Test_QUEUE 8 | using namespace ape::common; 9 | 10 | TEST(MsgQueuePrio, Dump) { 11 | MsgQueuePrio queue; 12 | EXPECT_EQ(0, queue.GetUsed()); 13 | queue.PutQ((void *)0X001, 1); 14 | queue.PutQ((void *)0X002, 1); 15 | queue.Dump(); 16 | EXPECT_EQ(2, queue.GetUsed()); 17 | void *P = queue.GetQ(); 18 | queue.Dump(); 19 | //EXPECT_EQ(0X001, p); 20 | EXPECT_EQ(1, queue.GetUsed()); 21 | P = queue.GetQ(); 22 | //EXPECT_EQ(0X002, p); 23 | EXPECT_EQ(0, queue.GetUsed()); 24 | } 25 | 26 | MsgQueuePrio public_queue; 27 | void *thread_run(void *) 28 | { 29 | BS_XLOG(XLOG_DEBUG, "%s, \n", __FUNCTION__); 30 | while (1) { 31 | void *pdata = public_queue.GetQ(1000); 32 | //BS_XLOG(XLOG_DEBUG, "data[0X%0X]\n", pdata); 33 | if (pdata) { 34 | BS_XLOG(XLOG_DEBUG, "data[0X%0X]\n", pdata); 35 | } 36 | } 37 | } 38 | TEST(MsgQueuePrio, PutMessage) { 39 | pthread_t id[5]; 40 | for (int i = 0; i < 1; ++i) { 41 | int ret = pthread_create(&id[i], NULL, &thread_run, NULL); 42 | if(ret!=0){ 43 | BS_XLOG(XLOG_DEBUG, "Create pthread error!\n"); 44 | exit (1); 45 | } 46 | } 47 | for (int i = 1; i < 10; ++i) { 48 | usleep(10); 49 | BS_XLOG(XLOG_DEBUG, "put [0X%0X]\n", i); 50 | public_queue.PutQ((void *)i, 1); 51 | } 52 | 53 | for(int i=0;i<5;i++){ 54 | pthread_join(id[i],NULL); 55 | } 56 | } 57 | 58 | TEST(MsgQueuePrio, Sleep) { 59 | while(1) { 60 | sleep(3); 61 | } 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_timer.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "timermanager.h" 3 | #include "threadtimer.h" 4 | #include "controller.h" 5 | #include "loghelper.h" 6 | 7 | #ifdef Test_Timer 8 | using namespace ape::common; 9 | 10 | void callback1() { BS_XLOG(XLOG_DEBUG, "----%s--\n", __FUNCTION__);} 11 | void callback1_1() { BS_XLOG(XLOG_DEBUG, "----%s--\n", __FUNCTION__);} 12 | void callback2() { BS_XLOG(XLOG_DEBUG, "----%s--\n", __FUNCTION__);} 13 | void callback3() { BS_XLOG(XLOG_DEBUG, "----%s--\n", __FUNCTION__);} 14 | void callback4(void *p) { BS_XLOG(XLOG_DEBUG, "----%s--, p[%p]--\n", __FUNCTION__, p);} 15 | 16 | TEST(CTimerManager, Dump) { 17 | CTimerManager timermanager; 18 | CThreadTimer timer1(&timermanager, 1000, (boost::function)(&callback1), CThreadTimer::TIMER_CIRCLE); 19 | CThreadTimer timer1_1(&timermanager, 1001, (boost::function)(&callback1_1)); 20 | CThreadTimer timer2(&timermanager, 2000, (boost::function)(&callback2)); 21 | CThreadTimer timer3(&timermanager, 3000, (boost::function)(&callback3), CThreadTimer::TIMER_CIRCLE); 22 | CThreadTimer timer4(&timermanager, (unsigned int)2550, (boost::function)(boost::bind(&callback4, (void*)0X001)), CThreadTimer::TIMER_CIRCLE); 23 | timer1.Start(); 24 | timer1_1.Start(); 25 | timer2.Start(); 26 | timer3.Start(); 27 | timer4.Start(); 28 | timermanager.Dump(); 29 | 30 | timer2.Stop(); 31 | timermanager.Dump(); 32 | 33 | timer1.Stop(); 34 | timer3.Stop(); 35 | timermanager.Dump(); 36 | 37 | timer1.Start(); 38 | timer3.Start(); 39 | timer2.Start(); 40 | timermanager.Dump(); 41 | timer1.Start(); 42 | 43 | for (int i = 0; i < 10; ++i) { 44 | timermanager.DetectTimerList(); 45 | //usleep(100000); 46 | sleep(1); 47 | 48 | //timermanager.Dump(); 49 | } 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_timerthread.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "timermanager.h" 3 | #include "testthread.h" 4 | #include "controller.h" 5 | #include "loghelper.h" 6 | 7 | #ifdef Test_Thread 8 | using namespace ape::common; 9 | 10 | TEST(TestTimerThread, Dump) { 11 | TestThreadGroup::GetInstance()->Start(3); 12 | TestThreadGroup::GetInstance()->OnPrivateMsg(); 13 | for (int i = 0; i < 10; ++i) { 14 | TestThreadGroup::GetInstance()->OnPublicMsg(i); 15 | //sleep(1); 16 | } 17 | } 18 | TEST(TestTimerThread, Sleep) { 19 | sleep(3); 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /frame/unit_test/src/t_xmlconfigparser.cc: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "xmlconfigparser.h" 3 | #include "controller.h" 4 | #include "loghelper.h" 5 | #include "func.h" 6 | 7 | #ifdef Test_XmlConfigParser 8 | using namespace ape::common; 9 | void ParseSosList(const std::string &str) { 10 | CXmlConfigParser parserdetail; 11 | parserdetail.ParseDetailBuffer(str.c_str()); 12 | BS_XLOG(XLOG_DEBUG, "[%s]\n", parserdetail.GetParameter("ServiceId").c_str()); 13 | 14 | std::vector vec = parserdetail.GetParameters("ServerAddr"); 15 | std::vector::iterator itr = vec.begin(); 16 | for (; itr != vec.end(); ++itr) { 17 | BS_XLOG(XLOG_DEBUG, "addr[%s]\n", itr->c_str()); 18 | } 19 | } 20 | TEST(CXmlConfigParser, Dump) { 21 | CXmlConfigParser parser; 22 | EXPECT_EQ(0, parser.ParseFile("testfile/config.xml")); 23 | EXPECT_STREQ( "43210", parser.GetParameter("CohPort").c_str()); 24 | EXPECT_EQ( 43210, parser.GetParameter("CohPort", 0)); 25 | EXPECT_STREQ( "", parser.GetParameter("NULL").c_str()); 26 | EXPECT_EQ( 10, parser.GetParameter("NULL", 10)); 27 | EXPECT_STREQ("mothername", parser.GetParameter("family/mother/name", "name").c_str()); 28 | EXPECT_EQ(50, parser.GetParameter("family/mother/age", 50)); 29 | EXPECT_EQ(50, parser.GetParameter("/family/mother/age/", 50)); 30 | EXPECT_STREQ("", parser.GetParameter("/family/mother/age/").c_str()); 31 | 32 | std::vector vec = parser.GetParameters("array/item"); 33 | EXPECT_STREQ("aaa", vec[0].c_str()); 34 | EXPECT_STREQ("bbb", vec[1].c_str()); 35 | EXPECT_STREQ("ccc", vec[2].c_str()); 36 | 37 | vec = parser.GetParameters("Sos/SosList"); 38 | std::vector::iterator itr = vec.begin(); 39 | for (; itr != vec.end(); ++itr) { 40 | ParseSosList(*itr); 41 | } 42 | //BS_XLOG(XLOG_DEBUG, "[%s]\n", parser.GetParameter("Sos").c_str()); 43 | //BS_XLOG(XLOG_DEBUG, "[%s]\n", parser.GetParameter("Sos/SosList").c_str()); 44 | //BS_XLOG(XLOG_DEBUG, "[%s]\n", parser.GetString().c_str()); 45 | 46 | CXmlConfigParser parser2; 47 | EXPECT_EQ(-1, parser2.ParseFile("testfile/badconfig.xml")); 48 | BS_XLOG(XLOG_DEBUG, "parse failed, [%s]\n", parser2.GetErrorMessage().c_str()); 49 | } 50 | TEST(CXmlConfigParser, fail) { 51 | CXmlConfigParser parser2; 52 | EXPECT_EQ(-1, parser2.ParseFile("testfile/badconfig.xml")); 53 | BS_XLOG(XLOG_DEBUG, "parse failed, [%s]\n", parser2.GetErrorMessage().c_str()); 54 | 55 | EXPECT_EQ(-1, parser2.ParseFile("testfile/nnn.xml")); 56 | BS_XLOG(XLOG_DEBUG, "parse failed, [%s]\n", parser2.GetErrorMessage().c_str()); 57 | } 58 | 59 | 60 | void testparser(const char *file) { 61 | CXmlConfigParser parser; 62 | EXPECT_EQ(0, parser.ParseFile(file)); 63 | } 64 | TEST(CXmlConfigParser, yali) { 65 | ExecuteYali(boost::bind(testparser, "testfile/config.xml"), "testparser", 100); 66 | } 67 | 68 | TEST(CXmlConfigParser, test_fail) { 69 | //EXPECT_EQ(0, 1); 70 | char *p = new char[1024]; 71 | delete p; 72 | delete p; 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /frame/unit_test/src/testthread.cc: -------------------------------------------------------------------------------- 1 | #include "testthread.h" 2 | #include "loghelper.h" 3 | 4 | const int SELF_CHECK_INTERVAL = 3000; //3s 5 | TestTimerThread::TestTimerThread(MsgQueuePrio *queue, int id) : MsgTimerThread(queue), id_(id), 6 | timerselfcheck_(this, SELF_CHECK_INTERVAL, boost::bind(&TestTimerThread::SelfCheck, this), CThreadTimer::TIMER_CIRCLE) { 7 | } 8 | void TestTimerThread::StartInThread() { 9 | BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d]\n", __FUNCTION__, id_); 10 | timerselfcheck_.Start(); 11 | } 12 | void TestTimerThread::StopInThread() { 13 | BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d]\n", __FUNCTION__, id_); 14 | timerselfcheck_.Stop(); 15 | } 16 | void TestTimerThread::Deal(void *pdata) { 17 | SMsg *msg = (SMsg *)pdata; 18 | //BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d], msgid[%d]\n", __FUNCTION__, id_, msg->id); 19 | if (msg->id == 0) { 20 | DoPrivateMsg(msg); 21 | } else if (msg->id == 1) { 22 | DoPublicMsg(msg); 23 | } 24 | delete (SMsg *)pdata; 25 | } 26 | void TestTimerThread::DoPublicMsg(SMsg *msg) { 27 | SPublicMsg *pubmsg = (SPublicMsg *)msg; 28 | BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d], index[%d]\n", __FUNCTION__, id_, pubmsg->index); 29 | } 30 | void TestTimerThread::DoPrivateMsg(SMsg *msg) { 31 | BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d]\n", __FUNCTION__, id_); 32 | } 33 | void TestTimerThread::SelfCheck() { 34 | BS_XLOG(XLOG_DEBUG,"TestTimerThread::%s, id[%d]\n", __FUNCTION__, id_); 35 | } 36 | 37 | /************************************************************************************/ 38 | /*********************** TestThreadGroup ******************************************/ 39 | /************************************************************************************/ 40 | TestThreadGroup *TestThreadGroup::sminstance_ = NULL; 41 | TestThreadGroup *TestThreadGroup::GetInstance() { 42 | if (sminstance_ == NULL) { 43 | sminstance_ = new TestThreadGroup(); 44 | } 45 | return sminstance_; 46 | } 47 | void TestThreadGroup::Release() { 48 | if(sminstance_) { 49 | delete sminstance_; 50 | } 51 | } 52 | TestThreadGroup::TestThreadGroup() { 53 | } 54 | TestThreadGroup::~TestThreadGroup() { 55 | Stop(); 56 | } 57 | void TestThreadGroup::Start(int threads) { 58 | BS_XLOG(XLOG_DEBUG,"TestThreadGroup::%s, threads[%d]\n", __FUNCTION__, threads); 59 | for (int i = 0; i < threads; ++i) { 60 | TestTimerThread *thread = new TestTimerThread(&queue_, i); 61 | threads_.push_back(thread); 62 | thread->Start(); 63 | } 64 | } 65 | void TestThreadGroup::Stop() { 66 | BS_XLOG(XLOG_DEBUG,"TestThreadGroup::%s\n", __FUNCTION__); 67 | std::vector::iterator itr; 68 | for (itr = threads_.begin(); itr != threads_.end(); ++itr) { 69 | (*itr)->Stop(); 70 | } 71 | sleep(1); 72 | for (itr = threads_.begin(); itr != threads_.end(); ++itr) { 73 | delete (*itr); 74 | } 75 | threads_.clear(); 76 | } 77 | void TestThreadGroup::OnPublicMsg(int index) { 78 | BS_XLOG(XLOG_DEBUG,"TestThreadGroup::%s, [%d]\n", __FUNCTION__, index); 79 | SPublicMsg *msg = new SPublicMsg; 80 | msg->index = index; 81 | queue_.PutQ(msg, 3); 82 | } 83 | void TestThreadGroup::OnPrivateMsg() { 84 | BS_XLOG(XLOG_DEBUG,"TestThreadGroup::%s\n", __FUNCTION__); 85 | std::vector::iterator itr; 86 | for (itr = threads_.begin(); itr != threads_.end(); ++itr) { 87 | SPrivateMsg *msg = new SPrivateMsg; 88 | (*itr)->PutQ(msg); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /frame/unit_test/src/testthread.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_THREAD_H_ 2 | #define _TEST_THREAD_H_ 3 | #include "msgtimerthread.h" 4 | #include "threadtimer.h" 5 | using namespace ape::common; 6 | 7 | typedef struct stMsg { 8 | int id; 9 | stMsg(int i):id(i) {} 10 | virtual ~stMsg(){} 11 | } SMsg; 12 | typedef struct stPrivateMsg : SMsg { 13 | stPrivateMsg():SMsg(0){} 14 | virtual ~stPrivateMsg(){} 15 | } SPrivateMsg; 16 | typedef struct stPublicMsg : SMsg { 17 | stPublicMsg():SMsg(1){} 18 | int index; 19 | virtual ~stPublicMsg(){} 20 | } SPublicMsg; 21 | 22 | class TestTimerThread : public MsgTimerThread{ 23 | public: 24 | TestTimerThread(MsgQueuePrio *queue, int id); 25 | virtual void StartInThread(); 26 | virtual void StopInThread(); 27 | virtual void Deal(void *pdata); 28 | private: 29 | void DoPublicMsg(SMsg *msg); 30 | void DoPrivateMsg(SMsg *msg); 31 | void SelfCheck(); 32 | public: 33 | int id_; 34 | CThreadTimer timerselfcheck_; 35 | }; 36 | class TestThreadGroup { 37 | public: 38 | static TestThreadGroup *GetInstance(); 39 | static void Release(); 40 | ~TestThreadGroup(); 41 | void Start(int threads = 5); 42 | void Stop(); 43 | void OnPublicMsg(int index); 44 | void OnPrivateMsg(); 45 | private: 46 | TestThreadGroup(); 47 | private: 48 | static TestThreadGroup *sminstance_; 49 | MsgQueuePrio queue_; 50 | std::vector threads_; 51 | }; 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /frame/unit_test/testfile/badconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 43210 4 | 5 | 6 | mothername 7 | 8 | 9 | 10 | 11 | aaa 12 | bbb 13 | ccc 14 | 15 | 3 16 | 17 | 18 | 111,112,113 19 | 10.241.37.35:7001 20 | 10.241.37.35:7002 21 | 22 | 23 | 113 24 | 10.241.37.35:7002 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /frame/unit_test/testfile/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 43210 4 | 5 | 6 | mothername 7 | 8 | 9 | 10 | 11 | aaa 12 | bbb 13 | ccc 14 | 15 | 3 16 | 17 | 18 | 111,112,113 19 | 10.241.37.35:7001 20 | 10.241.37.35:7002 21 | 22 | 23 | 113 24 | 10.241.37.35:7002 25 | 26 | 27 | 28 | --------------------------------------------------------------------------------