Exemple #1
0
	Bool HawkGateThread::StartSession(SOCKET hSocket, const SocketAddr& sAddr)
	{
		//套接字有效
		if (hSocket == INVALID_SOCKET)
			return false;

		//创建缓存事件
		bufferevent* pEvent = bufferevent_socket_new((event_base*)m_pBase, hSocket, BEV_OPT_CLOSE_ON_FREE);
		if (!pEvent)
			return false;

		//创建会话
		Session* pSession = AllocSession(hSocket, sAddr);
		if (!pSession)
		{
			bufferevent_free(pEvent);
			return false;
		}
		pSession->Event = pEvent;

		//设置回调
		bufferevent_setcb(pEvent, hawk_GateSessionRead, hawk_GateSessionWrite, hawk_GateSessionError, pSession);

		//设置读超时, 可做为心跳机制
		Int32 iTimeout = m_pGateway->GetSessionTimeout();
		if (iTimeout > 0)
		{
			struct timeval tv;
			tv.tv_sec  = iTimeout / 1000;
			tv.tv_usec = (iTimeout % 1000) * 1000; 
			bufferevent_set_timeouts(pEvent, &tv, NULL);
		}
		//开启读写事件
		bufferevent_enable(pEvent, EV_READ | EV_WRITE);

		//添加到会话列表
		m_mSession[pSession->Sid] = pSession;

		//调用性能监视器
		if (m_pGateway->GetProfiler())
			m_pGateway->GetProfiler()->RegConnect(true);		

		//添加日志
		HawkFmtLog("SessionStart, Sid: %u, Address: %s", pSession->Sid, pSession->Addr->ToString().c_str());
		
		return true;
	}
int LSelectServer::CheckForSocketEvent()
{
	if (!m_SelectServerSessionManager.BuildSet())
	{
		return -1;
	}

	fd_set rdset = m_SelectServerSessionManager.GetRecvSet();
	fd_set wrset = m_SelectServerSessionManager.GetSendSet();
	map<int, LSelectServerSession*>* pMapSocket = m_SelectServerSessionManager.GetSessionManagerForEvent();

	struct timeval val;
	val.tv_sec 		= 0;
	val.tv_usec 	= 0;
	int iReturn = select(m_SelectServerSessionManager.GetMaxSocketPlus1(), &rdset, &wrset, NULL, &val);	
	if (iReturn == -1)
	{
		return -1;
	}
	else if (iReturn == 0)
	{
		return 0;
	}
	int nListenSocket = GetSocket(); 
	if (FD_ISSET(nListenSocket, &rdset))
	{
		int nAcceptedSocket = accept(nListenSocket, NULL, NULL);
		if (nAcceptedSocket != -1)
		{
			LSelectServerSession* pSession = AllocSession();
			if (pSession == NULL)
			{
#ifndef WIN32
				close(nAcceptedSocket);
#else
				closesocket(nAcceptedSocket);
#endif
			}
			else
			{
				pSession->SetSocket(nAcceptedSocket);
				if (!AddSession(pSession))
				{
#ifndef WIN32
					close(nAcceptedSocket);
#else
					closesocket(nAcceptedSocket);
#endif
					FreeSession(pSession);
				}
				else
				{ 
					AddOneRecvedPacket(pSession->GetSessionID(), (LPacketSingle*)0xFFFFFFFF);
				}
			}
		}
	}
	map<int, LSelectServerSession*>::iterator _ito = pMapSocket->begin();
	while (_ito != pMapSocket->end())
	{
		int nTempSocket = _ito->first;
		LSelectServerSession* pSelectServerSession = _ito->second;
		if (pSelectServerSession == NULL)
		{
			_ito++;
			continue;
		}
		if (FD_ISSET(nTempSocket, &rdset))
		{
			int nErrorID = pSelectServerSession->SessionRecv();
			if (nErrorID < 0)
			{
				pSelectServerSession->SetSendable(false);
				AddOneCloseSessionWork(pSelectServerSession->GetSessionID());
				_ito++;
				continue;
			}
		}
		if (FD_ISSET(nTempSocket, &wrset))
		{
			pSelectServerSession->SetSendable(true);
		}
		_ito++;
	}

	return 1; 
}
int LSelectServer::ThreadDoing(void* pParam)
{ 
	while (1)
	{
		unsigned short usProcessedCloseWorkCount = 0;
		unsigned int unSessionIDForClose = 0;
		while (GetOneCloseSessionWork(unSessionIDForClose))
		{
			LSelectServerSession* pSession = FindSession(unSessionIDForClose);	
			if (pSession != NULL)
			{
				bool bReconnect = pSession->GetReconnect();
				pSession->ReleaseAllPacketInSendQueue();
#ifndef WIN32
				close(pSession->GetSocket());
#else
				closesocket(pSession->GetSocket());
#endif
				RemoveSession(unSessionIDForClose);
				FreeSession(pSession);
				AddOneRecvedPacket(unSessionIDForClose, NULL);
				if (bReconnect)
				{
					char szIP[32];
					unsigned short usPort = 0;
#ifndef WIN32
					pthread_mutex_lock(&m_mutexForConnectToServer);
#else
					EnterCriticalSection(&m_mutexForConnectToServer);
#endif
					if (!m_ConnectorWorkManager.AddConnectWork(szIP, usPort, NULL, 0))
					{
						//	error print
					}
#ifndef WIN32
					pthread_mutex_unlock(&m_mutexForConnectToServer);
#else
					LeaveCriticalSection(&m_mutexForConnectToServer);
#endif
				}
			}
			usProcessedCloseWorkCount++;
			if (usProcessedCloseWorkCount >= 200)
			{
				break;
			}
		}
		t_Connector_Work_Result cwr;
		memset(&cwr, 0, sizeof(cwr));
		int nProcessConnecttedWorkCount = 0;
		while (GetOneConnectedSession(cwr))
		{ 
			LSelectServerSession* pSession = AllocSession();
			if (pSession == NULL)
			{
#ifndef WIN32
				close(cwr.nSocket);
				pthread_mutex_lock(&m_mutexForConnectToServer);
#else
				closesocket(cwr.nSocket);
				EnterCriticalSection(&m_mutexForConnectToServer);
#endif

				
				if (!m_ConnectorWorkManager.AddConnectWork(cwr.szIP, cwr.usPort, NULL, 0))
				{
					//	error print
				}
#ifndef WIN32
				pthread_mutex_unlock(&m_mutexForConnectToServer);
#else
				LeaveCriticalSection(&m_mutexForConnectToServer);
#endif
				nProcessConnecttedWorkCount++;
				if (nProcessConnecttedWorkCount >= 200)
				{
					break;
				}
				continue;
			}
			else
			{
				pSession->SetSocket(cwr.nSocket);
				if (!AddSession(pSession))
				{
#ifndef WIN32
					close(cwr.nSocket);
					pthread_mutex_lock(&m_mutexForConnectToServer);
#else
					closesocket(cwr.nSocket);
					EnterCriticalSection(&m_mutexForConnectToServer);
#endif
					
					if (!m_ConnectorWorkManager.AddConnectWork(cwr.szIP, cwr.usPort, NULL, 0))
					{
						//	error print
					}
#ifndef WIN32
					pthread_mutex_unlock(&m_mutexForConnectToServer);
#else
					LeaveCriticalSection(&m_mutexForConnectToServer);
#endif
					FreeSession(pSession);
				}
				else
				{ 
					pSession->SetReconnect(true);
					AddOneRecvedPacket(pSession->GetSessionID(), (LPacketSingle*)0xFFFFFFFF);
				}
			}
			nProcessConnecttedWorkCount++;
			if (nProcessConnecttedWorkCount >= 200)
			{
				break;
			}
		}

		int nWorkCount = CheckForSocketEvent();
		if (nWorkCount < 0)
		{
			return 0;
		}
		int nSendWorkCount = SendData();
		if (nWorkCount == 0 && nSendWorkCount == 0)
		{
			//	sched_yield();
#ifndef WIN32
			struct timespec timeReq;
			timeReq.tv_sec 	= 0;
			timeReq.tv_nsec = 10;
			nanosleep(&timeReq, NULL);
#else
			Sleep(0);
#endif
		}
		if (CheckForStop())
		{
			return 0;
		} 
	}
	return 0; 
}