所有玩家的数据都保存在map<fd, NetCache>里边,
玩家在登陆成功后,会将fd和NetCache保存起来,同时将fd设置在玩家自己的身上,那么在什么时机会关闭fd连接呢?
关闭连接操作如下
void NetHandler::doCloseConnection(int fd)
{
if (fd > 0)
{
FD_CLR(fd, &master);
shutdown(fd, SD_BOTH);
removeConnection(fd);
}
}
移除fd的函数
void NetHandler::removeConnection(int fd)
{
NetCache *cache = getCacheFromFd(fd);
if (cache != NULL)
{
//int64 id = cache->uid;
lockMap();
fdCache.erase(fd);
unlockMap();
delete cache;
}
}
其中NetCache类的结构如下
class ProtocolHandler;
class NetCache//NetCache类维护了一个写和读的缓存
{
public:
int fd;
int64 uid;
bool remove;
bool aborted; // remote disconnected
bool idle; // if idle, should be kicked out
ProtocolHandler *ph;
NetCache(int fd, struct sockaddr_in addr, size_t rsize);
~NetCache(void);
bool read(void);
bool write(bool block=false);
bool prepareWrite(const char *str, size_t size);
bool assemble(string &str);
char *addrstr();
bool waitToWrite();
int getwpos();
inline unsigned short getNextIndex()
{
return ++index_;
}
private:
char *rbuf;
char *cmdbuf;
char *wbuf;
size_t wsize; // write buffer size
size_t rsize; // read buffer size
struct sockaddr_in addr;
int rpos, wpos;
pthread_mutex_t write_mutex;
log4cxx::LoggerPtr logger_;
unsigned short index_;
inline void lockWrite()
{
pthread_mutex_lock(&write_mutex);
}
inline void unlockWrite()
{
pthread_mutex_unlock(&write_mutex);
}
};
玩家NetCache数据清除的情况
1、玩家已经处于在线状态,再次登陆,那么会将之前的玩家顶替掉
代码如下
if(user->fd() != 0 && user->fd() != fd)
{
LOG4CXX_ERROR(logger_, "KickSelf: " << uid << ",oldfd: " << user->fd() << ",newfd: " << fd);
eh_->removeUserFdMap(user->fd(), uid);
}
2、手动进行剔除,比如过系统进行禁言,玩家作弊
只需要将cache类中的一个字段比如bool值remove定义下,就可以进行手动剔除,当每次连接时检查该字段是否被设置为剔除状态,如果是则调用removeConnection(int fd)
3、tcp读写失败的时候
if (!readSucc || (cache->remove && !cache->waitToWrite()))
{
if (uid >= 0 && cache->ph != NULL)
{
cache->ph->leave(uid);
}
doCloseConnection(i);
}