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