#pragma once #include <event2/bufferevent.h> #include <event2/bufferevent_compat.h> #include <event2/buffer.h> #include <event2/listener.h> #include <event2/util.h> #include <event2/event.h> #include <event2/http.h> #include <event2/buffer_compat.h> #include <event2/http_struct.h> #include <event2/bufferevent.h> #include <event2/thread.h> #include "CProtocol.h" #include "base\packet\PacketUtil.h" #include "base\packet\Packet.h" //#include <hash_map> //using namespace stdext; struct _Conn; struct _Worker; //服务器属性封装对象 struct _Server { bool bStart; //服务器是否已经启动 short nPort; //服务器端口 short workernum; //工做线程 unsigned int connnum; //每一个工做线程,能够链接的数量 volatile int nCurrentWorker; //当前线程的Worker数量 int read_timeout; //读数据的超时时间 int write_timeout; //写数据的超时时间 struct evconnlistener *pListener; //监听事件 struct event_base *pBase; //服务器主程事件组 HANDLE hThread; //服务器线程 _Worker *pWorker; //工做线程表 }; //链接对象列表 struct _ConnList { _ConnList() { head=NULL; tail=NULL; plistConn=NULL; } _Conn *head; _Conn *tail; _Conn *plistConn; }; //链接对象 struct _Conn { _Conn() { fd=NULL; bufev=NULL; index=-1; in_buf_len=0; out_buf_len=0; owner = NULL; next = NULL; in_buf = new char[emMaxBuffLen]; out_buf = new char[emMaxBuffLen]; } ~_Conn() { delete[]in_buf; delete[]out_buf; bufferevent_free(bufev); } struct bufferevent *bufev; evutil_socket_t fd; int index; char *in_buf; short in_buf_len; char *out_buf; short out_buf_len; _Worker *owner; _Conn *next; }; //工做线程封装对象. struct _Worker { _Worker() { pWokerbase=NULL; hThread = INVALID_HANDLE_VALUE; pListConn=NULL; } struct event_base *pWokerbase; HANDLE hThread; _ConnList *pListConn; inline _Conn* GetFreeConn() { _Conn* pItem=NULL; if(pListConn->head != pListConn->tail) { pItem=pListConn->head; printf("pItem addr:%d\n", pItem); pListConn->head = pListConn->head->next; } if (pItem == NULL) { printf("connection reach max connection num\n"); } return pItem; } inline void PutFreeConn(_Conn *pItem) { if (pItem) { printf("Close Conn Free Connecton! fd=%d\n", pItem->fd); } pListConn->tail->next=pItem; pListConn->tail=pItem; } }; typedef struct _Server Server; typedef struct _Worker Worker; typedef struct _Conn Conn; typedef struct _ConnList ConnList;
#pragma once typedef enum HeadStx { CHECKSTX = 860805 }; typedef enum emConfig { emMaxBuffLen = 8192, emMaxPackageType = 65535 }; //命令号 typedef enum emFunID { emFunNull = -1, emFunClosed = 0, emFunTimeout = 1, emFunError = 2, emFunConnected = 3, emFunDisConnected = 4, emFunBase = 1000, //emFunLogin = emFunBase + 1, LOGIN_CS_IN = emFunBase + 1, //int uid; //用户名 LOGIN_SC_IN = emFunBase + 2, //int uid; LOGIN_CS_OUT = emFunBase + 3, LOGIN_SC_OUT = emFunBase + 4, CONNECT_SC_CLOSE = emFunBase + 5, emFunLogout = emFunBase + 6 }; typedef enum emFunReturn { emFunReturClose=1, emFunReturnSend, emFunReturnRecv }; /************************************************************************/ /* 包头 */ /************************************************************************/ typedef struct _Head { int stx; int pkglen; int nFunID; _Head() { stx = 0; pkglen = 0; nFunID = 0; } }Head,*PHead; /************************************************************************/ /* 用户登陆协议 */ /************************************************************************/ typedef struct _Proto_Login_Req { int uid; //用户名 }Proto_Login_Req,*PProto_Login_Req; typedef struct _Proto_Login_Rsp { int uid; }Proto_Login_Rsp,*PProto_Login_Rsp; /************************************************************************/ /* 登出协议 */ /************************************************************************/ typedef struct _ProtoLogout_Req { }ProtoLogout_Req,*PProtoLogout_Req;
#pragma once #include "CLibEventData.h" #include "LibEventFunction.h" #include "LibUserFunction.h" class CLibEvent { public: CLibEvent(void); ~CLibEvent(void); private: //当前服务器对象 Server m_Server; public: bool StartServer(int port, short workernum, unsigned int connnum, int read_timeout, int write_timeout); void StopServer(); private: void LoadFuns(); static void DoAccept(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *sa, int socklen, void *user_data); static void DoError(struct bufferevent *bev, short error, void *ctx); static void CloseConn(Conn *pConn,int nFunID); static void CloseConn(Conn *pConn); static void TimeOut(Conn *pConn, int nFunID); static void TimeOut(Conn *pConn); static int DispatchFunction(struct bufferevent *bev, CPacketHead* header, Conn *pConn); static void DoRead(struct bufferevent *bev, void *ctx); static void SetConnTimeOut(struct bufferevent *bev, timeval& timeOutRead, timeval& timeOutWrite); static void DeleteSingleton(); static DWORD WINAPI ThreadServer(LPVOID lPVOID); static DWORD WINAPI ThreadWorkers(LPVOID lPVOID); };
#include "StdAfx.h" #include "LibEventFunction.h" lpFunPtr CLibEventFunction::m_FunPtrList[emMaxPackageType]={0}; int CLibEventFunction::m_stx=0; CLibEventFunction::CLibEventFunction(void) { } CLibEventFunction::~CLibEventFunction(void) { } void CLibEventFunction::RegistFunc(int id, lpFunPtr func) { m_FunPtrList[id] = func; } void CLibEventFunction::RegistConnectedFunc(lpFunPtr func) { m_FunPtrList[emFunConnected]=func; } void CLibEventFunction::RegistDisconnectedFunc(lpFunPtr func) { //m_FunPtrList[emFunTimeout] = func; //m_FunPtrList[emFunClosed] = func; //m_FunPtrList[emFunError] = func; m_FunPtrList[emFunDisConnected] = func; } void CLibEventFunction::RegistTimeoutFunc(lpFunPtr func) { m_FunPtrList[emFunTimeout] = func; } void CLibEventFunction::RegistClosedFunc(lpFunPtr func) { m_FunPtrList[emFunClosed] = func; } void CLibEventFunction::RegistErrorFunc(lpFunPtr func) { m_FunPtrList[emFunError]=func; } void CLibEventFunction::RegistStx(int stx) { m_stx=stx; } int CLibEventFunction::LoadStx() { return m_stx; } int CLibEventFunction::DispatchFunction(int nFunID,Conn*pItem) { bool bFind = 0; if (m_FunPtrList[nFunID]) { bFind = 1; if (pItem) { return m_FunPtrList[nFunID](pItem); } } return bFind; }
#pragma once #include "CLibEventData.h" #include "LibUserFunction.h" #include <map> using namespace std; class CLibEventFunction { public: CLibEventFunction(void); ~CLibEventFunction(void); public: /************************************************************************/ /* 注册业务处理函数 */ /************************************************************************/ static void RegistFunc(int id, lpFunPtr func); /************************************************************************/ /* 注册接受客户端链接时响应函数 */ /************************************************************************/ static void RegistConnectedFunc(lpFunPtr func); /************************************************************************/ /* 注册客户端断开处理函数 */ /************************************************************************/ static void RegistDisconnectedFunc(lpFunPtr func); /************************************************************************/ /* 注册网络超时处理函数 */ /************************************************************************/ static void RegistTimeoutFunc(lpFunPtr func); /************************************************************************/ /* 注册客户端链接关闭处理函数 */ /************************************************************************/ static void RegistClosedFunc(lpFunPtr func); /************************************************************************/ /* 注册网络错误处理函数 */ /************************************************************************/ static void RegistErrorFunc(lpFunPtr func); /************************************************************************/ /* 注册用户自定义头部的同步密码 */ /************************************************************************/ static void RegistStx(int stx); /************************************************************************/ /* 注册用户自定义头部的同步密码 */ /************************************************************************/ static int LoadStx(); public: static int DispatchFunction(int nFunID,Conn*pItem); private: static lpFunPtr m_FunPtrList[emMaxPackageType]; static int m_stx; };
#pragma once #include "CLibEventData.h" class CLibUserFunction { public: CLibUserFunction(void); ~CLibUserFunction(void); public: static int Connect(Conn* c); static int DisConnect(Conn* c); static int TimeOut(Conn* c); static int Login(Conn* c); static int Logout(Conn* c); }; //回调函数指针 typedef int (*lpFunPtr)(Conn* c);
#include "StdAfx.h" #include "LibUserFunction.h" #include "LibEvent.h" #include "base\packet\JobDBQueueEx.h" #include "..\Model.h" CLibUserFunction::CLibUserFunction(void) { } CLibUserFunction::~CLibUserFunction(void) { } int CLibUserFunction::Connect(Conn* c) { static int iConnectNum = 0; iConnectNum++; printf("CLibUserFunction::Connect =%d\n", iConnectNum); return 0; } int CLibUserFunction::DisConnect(Conn* c) { printf("CLibUserFunction::Disconnect: %d\n", c->fd); return 0; } int CLibUserFunction::TimeOut(Conn* c) { printf("CLibUserFunction::TimeOut: %d\n", c->fd); return 0; } int CLibUserFunction::Login(Conn* c) { CPacketHead *hreq = (CPacketHead*)c->in_buf; int PersonStrLen = c->in_buf_len - sizeof(CPacketHead); char szBuffer[8196] = {0}; memcpy(szBuffer, c->in_buf + sizeof(CPacketHead), PersonStrLen); std::string strBuffer = szBuffer; Login::Login_CS loginCS; loginCS.ParseFromString(strBuffer); printf("Client Login: fd=%d,username=%s,PWD=%s,type=%d\n", c->fd, loginCS.username().c_str(), loginCS.userpassword().c_str() , loginCS.isercettype()); //操做数据库验证 CJobDBMsg* pJobMsg = GetDBJobQueueEx()->AllocDBJobMsg(); if (!pJobMsg) return 0; int iSerectType = loginCS.isercettype(); char szUserName[MAX_NAME_LEN] = {0}; char szUserPWD[MAX_PWD_LEN] = { 0 }; int iLen = loginCS.username().size() > MAX_NAME_LEN ? MAX_NAME_LEN : loginCS.username().size(); memcpy(szUserName, loginCS.username().c_str(), iLen); iLen = loginCS.userpassword().size() > MAX_PWD_LEN ? MAX_PWD_LEN : loginCS.userpassword().size(); memcpy(szUserPWD, loginCS.userpassword().c_str(), iLen); int iConnectFD = c->fd; //服务器惟一标识 bool bAdd = false; pJobMsg->Init(ACCOUNT_SD_AUTH); pJobMsg->PushBack(iConnectFD); pJobMsg->PushBack(szUserName, MAX_NAME_LEN); pJobMsg->PushBack(szUserPWD, MAX_PWD_LEN); pJobMsg->PushBack(iSerectType); bAdd = GetDBJobQueueEx()->AddDBJobMsg(pJobMsg); if (!bAdd) { GetDBJobQueueEx()->FreeDBJobMsg(pJobMsg); } return LOGIN_SC_IN; } int CLibUserFunction::Logout(Conn* c) { printf("Logout: %d\n", c->fd); return CONNECT_SC_CLOSE; }