#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; }