init
This commit is contained in:
235
Gateway/gateway/srv/game_client_mgr.cc
Normal file
235
Gateway/gateway/srv/game_client_mgr.cc
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "StdAfx.h"
|
||||
#include <map>
|
||||
#include "client/client_obj_mgr.h"
|
||||
#include "event/select_event.h"
|
||||
#include "event/epoll_event.h"
|
||||
|
||||
GameClientMgr::GameClientMgr(const char *name, GateServer *srv) {
|
||||
srv_ = srv;
|
||||
gw_cli_ = new GameWorldClient(srv, this, name);
|
||||
cli_obj_mgr_ = new ClientObjMgr();
|
||||
inner_msg_list_.setLock(&inner_msg_lock_);
|
||||
#if USE_EPOLL
|
||||
event_ = new EpollEvent(this);
|
||||
#else
|
||||
event_ = new SelectEvent(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
GameClientMgr::~GameClientMgr() {
|
||||
cli_obj_mgr_->flush();
|
||||
SafeDelete(cli_obj_mgr_);
|
||||
inner_msg_list_.flush();
|
||||
inner_msg_list_.clear();
|
||||
SafeDelete(gw_cli_);
|
||||
}
|
||||
|
||||
void GameClientMgr::SetMaxSession(int max_session) {
|
||||
cli_obj_mgr_->SetMaxSession(max_session);
|
||||
}
|
||||
|
||||
void GameClientMgr::InitGameWorldClient(const char * ip, int port) {
|
||||
gw_cli_ = new GameWorldClient(srv_, this, GetServiceName());
|
||||
gw_cli_->UseBaseAlloc(true);
|
||||
gw_cli_->SetHost(ip);
|
||||
gw_cli_->SetPort(port);
|
||||
}
|
||||
|
||||
bool GameClientMgr::onConnect(SOCKET nSocket, sockaddr_in * pAddrIn) {
|
||||
if (!gw_cli_->connected()) return false;
|
||||
|
||||
Client *cli = new Client(this, nSocket, pAddrIn);
|
||||
cli_obj_mgr_->setNewClient(cli);
|
||||
cli_obj_mgr_->flush();
|
||||
cli->SetBlockMode(false);
|
||||
GateInterMsg msg;
|
||||
msg.msg_id_ = gcAddClient;
|
||||
msg.data_.fd_ = nSocket;
|
||||
msg.data_.sessidx_ = cli->GetSessionId();
|
||||
PostMsg(msg);
|
||||
OutputMsg(rmTip, _T("[Login] (1) 客户端连接上来: gatekey(%d),socket(%lld),GateIdx(%d),LogicIdx(%d),CurrentThreadId(%d)。"),
|
||||
cli->GetSKey(), nSocket, cli->GetNetId().index_, cli->GetNetId().gate_id_, GetCurrentThreadId());
|
||||
//MSG_TIP("new client connect fd:%d, sid:%d", cli->GetFd(), cli->GetSessionId());
|
||||
return true;
|
||||
}
|
||||
|
||||
int GameClientMgr::Run() {
|
||||
inner_msg_list_.flush();
|
||||
int count = inner_msg_list_.count();
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
GateInterMsg& msg = inner_msg_list_[i];
|
||||
OnRecvSysMsg(msg);
|
||||
}
|
||||
inner_msg_list_.clear();
|
||||
event_->RunOne();
|
||||
return count;
|
||||
}
|
||||
|
||||
void GameClientMgr::OnStart() {
|
||||
MSG_LOG("GameClientMgr::OnStart");
|
||||
event_->init();
|
||||
}
|
||||
|
||||
void GameClientMgr::OnStop() {
|
||||
MSG_LOG("GameClientMgr::OnStop");
|
||||
}
|
||||
|
||||
void GameClientMgr::Stop() {
|
||||
MSG_LOG("%s, start", GetServiceName());
|
||||
while (gw_cli_->GetPacketCount()) {//这里还有包没发完,导致一致没法停止
|
||||
gw_cli_->SingleRun();
|
||||
Sleep(1);
|
||||
}
|
||||
gw_cli_->Stop();
|
||||
Inherited::Stop();
|
||||
MSG_LOG("%s, ok", GetServiceName());
|
||||
}
|
||||
|
||||
void GameClientMgr::OnRecvSysMsg(GateInterMsg & msg)
|
||||
{
|
||||
switch (msg.msg_id_)
|
||||
{
|
||||
case gcAddClient:
|
||||
{
|
||||
event_->AddReadFd(msg.data_.fd_, cli_obj_mgr_->get(msg.data_.sessidx_));
|
||||
break;
|
||||
}
|
||||
case gcServerIdx:
|
||||
{
|
||||
Client* cli = cli_obj_mgr_->get(msg.data_.idx_);
|
||||
if (cli) {
|
||||
cli->GetNetId().gate_id_ = msg.data_.para_;
|
||||
OutputMsg(rmTip, _T("[Login] (5) LogicServer已成功添加玩家Gate: gatekey(%d),socket(%lld),GateIdx(%d),LogicIdx(%d),CurrentThreadId(%d)。"),
|
||||
cli->GetSKey(), cli->GetNetId().socket_, cli->GetNetId().index_, cli->GetNetId().gate_id_, GetCurrentThreadId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gcGWData:
|
||||
{
|
||||
Client* cli = cli_obj_mgr_->get(msg.data_.index_);
|
||||
if (cli) {
|
||||
auto dp = msg.data_.packet_;
|
||||
cli->OnGameWorldRecv(dp->getOffsetPtr(), dp->getAvaliableLength());
|
||||
}
|
||||
gw_cli_->FreeBackUserDataPacket(msg.data_.packet_);
|
||||
break;
|
||||
}
|
||||
case gcGWClose:
|
||||
{
|
||||
Client* cli = cli_obj_mgr_->get(msg.data_.index_);
|
||||
if (cli) {
|
||||
cli->Close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gcChAdd:
|
||||
{
|
||||
uint64_t key = MAKEINT64(msg.data_.channel_, msg.data_.para_);
|
||||
channel_indexs_map_[key].insert(msg.data_.idx_);
|
||||
break;
|
||||
}
|
||||
case gcChDel:
|
||||
{
|
||||
uint64_t key = MAKEINT64(msg.data_.channel_, msg.data_.para_);
|
||||
channel_indexs_map_[key].erase(msg.data_.idx_);
|
||||
break;
|
||||
}
|
||||
case gcChBro:
|
||||
{
|
||||
uint64_t key = MAKEINT64(msg.data_.b_channel_, msg.data_.b_para_);
|
||||
auto &list = channel_indexs_map_[key];
|
||||
for (auto idx:list) {
|
||||
Client* cli = cli_obj_mgr_->get(idx);
|
||||
if (cli) {
|
||||
auto dp = msg.data_.packet_;
|
||||
cli->OnGameWorldRecv(dp->getOffsetPtr(), dp->getAvaliableLength());
|
||||
}
|
||||
}
|
||||
gw_cli_->FreeBackUserDataPacket(msg.data_.dp_);
|
||||
break;
|
||||
}
|
||||
case gcGWDisconn:
|
||||
{
|
||||
CloseAllClient();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientMgr::ProssClient(void) {
|
||||
//cli_obj_mgr_->flush();
|
||||
auto &list = cli_obj_mgr_->getClientMap();
|
||||
std::vector<uint16_t> remove_list;
|
||||
for (auto it:list) {
|
||||
Client *cli = it.second;
|
||||
if(cli)
|
||||
{
|
||||
if (cli->IsClose()) {
|
||||
remove_list.push_back(cli->GetSessionId());
|
||||
continue;
|
||||
}
|
||||
cli->RecvData();
|
||||
cli->PacketHandle();
|
||||
cli->WriteEvent();
|
||||
cli->SendData();
|
||||
}
|
||||
}
|
||||
for (auto idx: remove_list) {
|
||||
Client *cli = cli_obj_mgr_->remove(idx);
|
||||
SafeDelete(cli);
|
||||
}
|
||||
remove_list.clear();
|
||||
}
|
||||
|
||||
void GameClientMgr::HandleReadEvent(SOCKET fd, Client * cli) {
|
||||
if (cli) {
|
||||
cli->RecvData();
|
||||
cli->PacketHandle();
|
||||
event_->AddWriteFd(fd, cli);
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientMgr::HandleWriteEvent(SOCKET fd, Client * cli) {
|
||||
if (cli) {
|
||||
cli->WriteEvent();
|
||||
if (!cli->SendData()) {
|
||||
event_->AddWriteFd(fd, cli);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientMgr::CloseAllClient() {
|
||||
cli_obj_mgr_->flush();
|
||||
auto &list = cli_obj_mgr_->getClientMap();
|
||||
std::vector<uint16_t> remove_list;
|
||||
for (auto it : list) {
|
||||
Client *cli = it.second;
|
||||
cli->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientMgr::HaveData(Client * cli) {
|
||||
if(cli) {
|
||||
event_->AddWriteFd(cli->GetFd(), cli);
|
||||
}
|
||||
}
|
||||
|
||||
void GameClientMgr::CloseClient(Client * cli) {
|
||||
event_->DelFd(cli->GetFd());
|
||||
closesocket(cli->GetFd());
|
||||
if (cli_obj_mgr_->get(cli->GetSessionId()))
|
||||
{
|
||||
cli_obj_mgr_->remove(cli->GetSessionId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool GameClientMgr::Startup() {
|
||||
if (!Inherited::Startup()) {
|
||||
return false;
|
||||
}
|
||||
// 创建发送线程
|
||||
|
||||
return gw_cli_->Startup();
|
||||
}
|
||||
95
Gateway/gateway/srv/game_client_mgr.h
Normal file
95
Gateway/gateway/srv/game_client_mgr.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
typedef union GateInterMsgData {
|
||||
struct {
|
||||
uint32_t b_channel_;
|
||||
uint32_t b_para_;
|
||||
DataPacket* dp_;
|
||||
};
|
||||
struct {
|
||||
uint32_t index_;
|
||||
DataPacket* packet_;
|
||||
};
|
||||
struct {
|
||||
uint32_t idx_;
|
||||
uint32_t para_;
|
||||
uint32_t channel_;
|
||||
};
|
||||
struct {
|
||||
uint32_t sessidx_;
|
||||
SOCKET fd_;
|
||||
};
|
||||
} tagGateInterMsgData;
|
||||
|
||||
typedef struct GateInterMsg
|
||||
{
|
||||
int msg_id_;
|
||||
GateInterMsgData data_;
|
||||
} tagGateInterMsg;
|
||||
|
||||
class GameWorldClient;
|
||||
class BaseEvent;
|
||||
class SocketSrv;
|
||||
class ClientObjMgr;
|
||||
|
||||
enum {
|
||||
gcAddClient = 1, //增加一个新的客户端连接
|
||||
gcGWData = 2, //游戏服给客户端发消息
|
||||
gcGWClose = 3, //游戏服主动关闭客户端
|
||||
gcChBro = 4,//频道广播消息
|
||||
gcChAdd = 5,//频道信息增加
|
||||
gcChDel = 6,//频道信息删除
|
||||
gcGWDisconn = 7,//游戏服断开连接
|
||||
gcServerIdx = 8,//游戏服的玩家对应gateid
|
||||
};
|
||||
|
||||
class GameClientMgr : public SocketSrv {
|
||||
public:
|
||||
typedef SocketSrv Inherited;
|
||||
GameClientMgr(const char *name, GateServer *srv);
|
||||
~GameClientMgr();
|
||||
|
||||
void SetMaxSession(int max_session);
|
||||
|
||||
bool Startup();
|
||||
void InitGameWorldClient(const char *ip, int port);
|
||||
GameWorldClient* GetGameWorldClient(void) { return gw_cli_; }
|
||||
virtual bool onConnect(SOCKET nSocket, sockaddr_in* pAddrIn);
|
||||
|
||||
//单次逻辑处理
|
||||
virtual int Run();
|
||||
virtual void OnStart();
|
||||
virtual void OnStop();
|
||||
virtual void Stop();
|
||||
|
||||
void PostMsg(GateInterMsg& msg) {
|
||||
inner_msg_list_.append(msg);
|
||||
}
|
||||
|
||||
void OnRecvSysMsg(GateInterMsg& msg);
|
||||
|
||||
//select模式使用
|
||||
void ProssClient(void);
|
||||
//epoll模式使用
|
||||
void HandleReadEvent(SOCKET fd, Client* cli);
|
||||
void HandleWriteEvent(SOCKET fd, Client* cli);
|
||||
//断开所有客户端连接
|
||||
void CloseAllClient();
|
||||
void HaveData(Client* cli);
|
||||
|
||||
void CloseClient(Client *cli);
|
||||
|
||||
protected:
|
||||
|
||||
GateServer *srv_;
|
||||
GameWorldClient *gw_cli_;
|
||||
ClientObjMgr *cli_obj_mgr_;
|
||||
std::map<uint64_t, std::set<int> > channel_indexs_map_;
|
||||
|
||||
QueueList<GateInterMsg> inner_msg_list_;//内部消息列表
|
||||
Mutex inner_msg_lock_;//内部消息列表锁
|
||||
BaseEvent *event_;//事件处理
|
||||
};
|
||||
148
Gateway/gateway/srv/socket_srv.cc
Normal file
148
Gateway/gateway/srv/socket_srv.cc
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifdef _MSC_VER
|
||||
#include <Windows.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include "StdAfx.h"
|
||||
#include "socket_srv.h"
|
||||
|
||||
|
||||
SocketSrv::SocketSrv() {
|
||||
srv_stoped_ = true;
|
||||
memset(server_name_, 0, sizeof(server_name_));
|
||||
#ifdef _MSC_VER
|
||||
accept_thread_ = NULL;
|
||||
#else
|
||||
accept_thread_ = 0;
|
||||
#endif
|
||||
accept_exit_ = true;
|
||||
}
|
||||
|
||||
|
||||
SocketSrv::~SocketSrv()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if (NULL != accept_thread_) {
|
||||
CloseHandle(accept_thread_);
|
||||
}
|
||||
accept_thread_ = NULL;
|
||||
#else
|
||||
accept_thread_ = 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
void STDCALL SocketSrv::ServerSocketAcceptThreadRoutine(void* arg) {
|
||||
#else
|
||||
void * SocketSrv::ServerSocketAcceptThreadRoutine(void * arg) {
|
||||
#endif
|
||||
SocketSrv *srv = (SocketSrv*)arg;
|
||||
struct sockaddr_in server_addr;
|
||||
SOCKET listen_fd_ = 0;
|
||||
if ((listen_fd_ = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR) {
|
||||
MSG_ERR("create socket error:%d",errno);
|
||||
assert(false);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
char optval = 1;
|
||||
#else
|
||||
int optval = 1;
|
||||
#endif
|
||||
if (setsockopt(listen_fd_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == SOCKET_ERROR) {
|
||||
MSG_ERR("setsockopt");
|
||||
assert(false);
|
||||
}
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = htons(srv->GetServicePort());
|
||||
server_addr.sin_addr.s_addr = inet_addr(srv->GetServiceHost());
|
||||
memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
|
||||
|
||||
if (::bind(listen_fd_, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
|
||||
MSG_ERR("bind error");
|
||||
assert(false);
|
||||
}
|
||||
if (listen(listen_fd_, 5) == SOCKET_ERROR) {
|
||||
MSG_ERR("listen error");
|
||||
assert(false);
|
||||
}
|
||||
socklen_t len = sizeof(sockaddr);
|
||||
do {
|
||||
sockaddr_in cli_addr;
|
||||
SOCKET nSocket = accept(listen_fd_, (sockaddr*)&cli_addr, &len);
|
||||
if (srv->Started() && !srv->onConnect(nSocket, &cli_addr)) {
|
||||
closesocket(nSocket);
|
||||
}
|
||||
} while (srv->Started());
|
||||
closesocket(listen_fd_);
|
||||
srv->accept_exit_ = true;
|
||||
#ifdef _MSC_VER
|
||||
ExitThread(0);//设置线程退出返回值
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SocketSrv::SetServiceName(const char * sName)
|
||||
{
|
||||
_STRNCPY_A(server_name_, sName);
|
||||
}
|
||||
|
||||
void SocketSrv::SetServiceHost(const char * sHost)
|
||||
{
|
||||
_STRNCPY_A(host_, sHost);
|
||||
}
|
||||
|
||||
void SocketSrv::SetServicePort(const int nPort) {
|
||||
port_ = nPort;
|
||||
}
|
||||
|
||||
bool SocketSrv::Startup() {
|
||||
Inherited:Start();
|
||||
bool ret = true;
|
||||
int err = 0;
|
||||
srv_stoped_ = false;
|
||||
#ifdef _MSC_VER
|
||||
accept_thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ServerSocketAcceptThreadRoutine, this, 0, NULL);
|
||||
if (!accept_thread_) {
|
||||
err = GetLastError();
|
||||
ret = false;
|
||||
}
|
||||
#else
|
||||
|
||||
if (pthread_create(&accept_thread_, NULL, ServerSocketAcceptThreadRoutine, this)) {
|
||||
err = errno;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (!ret) {
|
||||
MSG_ERR("create listen thread error %d", err);
|
||||
return false;
|
||||
}
|
||||
accept_exit_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SocketSrv::Stop() {
|
||||
if (srv_stoped_) return;
|
||||
MSG_LOG("start");
|
||||
srv_stoped_ = true;
|
||||
// while (!accept_exit_) {
|
||||
// Sleep(1);
|
||||
// }
|
||||
//#ifdef _MSC_VER
|
||||
// CloseThread(accept_thread_);
|
||||
//#endif
|
||||
Inherited::Stop();
|
||||
MSG_LOG("ok");
|
||||
}
|
||||
|
||||
void SocketSrv::OnRoutine() {
|
||||
OnStart();
|
||||
while (!terminated()) {
|
||||
if (Run() <= 0)
|
||||
Sleep(1);
|
||||
}
|
||||
OnStop();
|
||||
}
|
||||
55
Gateway/gateway/srv/socket_srv.h
Normal file
55
Gateway/gateway/srv/socket_srv.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
class SocketSrv : public thread::BaseThread {
|
||||
public:
|
||||
typedef thread::BaseThread Inherited;
|
||||
SocketSrv();
|
||||
~SocketSrv();
|
||||
#ifdef _MSC_VER
|
||||
static void STDCALL ServerSocketAcceptThreadRoutine(void* srv);
|
||||
#else
|
||||
static void* ServerSocketAcceptThreadRoutine(void* arg);
|
||||
#endif
|
||||
virtual bool onConnect(SOCKET nSocket, sockaddr_in* pAddrIn) = 0;
|
||||
virtual void OnRoutine();
|
||||
//单次逻辑处理
|
||||
virtual int Run() = 0;
|
||||
virtual void OnStart() = 0;
|
||||
virtual void OnStop() = 0;
|
||||
|
||||
inline const char* GetServiceName()
|
||||
{
|
||||
return server_name_;
|
||||
}
|
||||
inline const char* GetServiceHost()
|
||||
{
|
||||
return host_;
|
||||
}
|
||||
inline int GetServicePort()
|
||||
{
|
||||
return port_;
|
||||
}
|
||||
inline bool Started()
|
||||
{
|
||||
return !srv_stoped_;
|
||||
}
|
||||
void SetServiceName(const char* sName);
|
||||
void SetServiceHost(const char* sHost);
|
||||
void SetServicePort(const int nPort);
|
||||
bool Startup();
|
||||
virtual void Stop();
|
||||
|
||||
private:
|
||||
#ifdef _MSC_VER
|
||||
HANDLE accept_thread_; //接受客户端连接线程
|
||||
#else
|
||||
pthread_t accept_thread_;
|
||||
#endif
|
||||
|
||||
bool srv_stoped_; //是否停止工作线程
|
||||
bool accept_exit_; //监听线程完整退出
|
||||
|
||||
char server_name_[256]; //服务名称
|
||||
char host_[256]; //服务绑定地址
|
||||
int port_; //服务绑定端口
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user