예제 #1
0
bool SessionManager::AcceptSessions()
{
	FastSpinlockGuard guard(mLock);

	while (mCurrentIssueCount - mCurrentReturnCount < MAX_CONNECTION)
	{
		//TODO mFreeSessionList에서 ClientSession* 꺼내서 PostAccept() 해주기.. (위의 ReturnClientSession와 뭔가 반대로 하면 될 듯?)
		ClientSession* newClient = mFreeSessionList.front();
		mFreeSessionList.pop_front(); // pop_back하면 1개일때 에러가...??
		// AddRef()도 당연히 해줘야 하고...
		newClient->AddRef();

		// 실패시 false
		//if (false == newClient->PostAccept())
		//	return false;
		if( false == newClient->PostAccept() ){
			if( GetLastError() == ERROR_IO_PENDING )
				++mCurrentIssueCount;
			else
				return false;
		}
		else
			++mCurrentIssueCount;
	}


	return true;
}
예제 #2
0
bool IocpManager::StartAcceptLoop()
{
	/// listen
	if (SOCKET_ERROR == listen(mListenSocket, SOMAXCONN))
		return false;


	/// accept loop
	while (true)
	{
		SOCKET acceptedSock = accept(mListenSocket, NULL, NULL);
		if (acceptedSock == INVALID_SOCKET)
		{
			printf_s("accept: invalid socket\n");
			continue;
		}

		SOCKADDR_IN clientaddr;
		int addrlen = sizeof(clientaddr);
		getpeername(acceptedSock, (SOCKADDR*)&clientaddr, &addrlen);

		/// 소켓 정보 구조체 할당과 초기화
		ClientSession* client = GSessionManager->CreateClientSession(acceptedSock);

		/// 클라 접속 처리
		if (false == client->OnConnect(&clientaddr))
		{
			client->Disconnect(DR_ONCONNECT_ERROR);
			GSessionManager->DeleteClientSession(client);
		}
	}

	return true;
}
예제 #3
0
	void ClientSessionManager::ReturnClientSession(const std::size_t sessionId)
	{
		const auto f = [=]
		{
			decltype(sessionId) size = mClientSessionList.size();
			if (size > sessionId && mClientSessionList[sessionId])
			{
				ClientSession* client = mClientSessionList[sessionId];
				CRASH_ASSERT(client->mConnected == 0 && client->mRefCount == 0);

				// std::string ip = boost::lexical_cast<std::string>(client->GetSocket().remote_endpoint());
				// BOOST_LOG_TRIVIAL(info) << "클라이언트 접속 종료. " << client->GetSessionId() << ":" << ip;
				// std::cout << "클라이언트 접속 종료. " << client->GetSessionId() << ":" << ip << std::endl;

				client->Reset();
				mClientSessionQueue.insert(static_cast<int>(sessionId));

				++mCurrentReturnCount;

				if (!mIsAccepting)
				{
					AcceptClientSession();
				}
			}
		};
		auto task = mWrapper.wrap(f);
		mDispatcher.post(task);
	}
예제 #4
0
void ForServerMsgHandler::NofityClientExit(BaseSession* pSession, const NetMsgHead* pMsg,int32 nSize)
{
	const SSNofityClientExit* pPacket = static_cast<const SSNofityClientExit*>(pMsg);
	int32 nClientSessionID = pPacket->nClientSessionID;

	ClientSession* pClientSession = ClientSessionMgr::Instance()->GetSession(nClientSessionID);
	ASSERT(pClientSession);

	// 同步或保存重要数据到dp

	// 通知ls,ss
	SSNofityClientExit sMsgExit;
	sMsgExit.nClientSessionID = nClientSessionID;

	pClientSession->SendMsgToLs(&sMsgExit,sMsgExit.GetPackLength());
	if(pClientSession->Status() == ECLIENT_STATUS_IN_SCENE)
	{
		pClientSession->SendMsgToSs(&sMsgExit,sMsgExit.GetPackLength());
	}else
	{
		// 由dp去保存退出操作
		pClientSession->SendMsgToDp(&sMsgExit,sMsgExit.GetPackLength());
	}

	// 删除
	ClientSessionMgr::Instance()->RemoveSession(nClientSessionID);

}
예제 #5
0
	CErrno NetThread::StartupClient(const Json::Value & clients)
	{
		INT32 nCount = clients.size(); 
		for (INT32 i = 0 ;i < nCount; ++ i)
		{     
			Json::Value client = clients[i];

			INT32 bReconnect = client.get("reconnect", 1).asInt();
			std::string strType = client.get("type" , "tcp").asCString();
			std::string strAddress = client.get("address", "127.0.0.1").asCString();
			INT32 nPort = client.get("port", 0000).asInt();
			INT32 nSendBuf = client.get("send_buf", DEFAULT_SOCKET_BUFFER_SIZE).asInt();
			INT32 nRecvBuf = client.get("recv_buf", DEFAULT_SOCKET_BUFFER_SIZE).asInt();
			
			INetHandlerPtr pNetHandler = CreateClientHandler(m_strNetNodeName, "" , strAddress.c_str(), nPort);
			if (!pNetHandler)
			{
				return CErrno::Failure();
			}
			ClientSession * pSession = dynamic_cast<ClientSession*>(pNetHandler->GetSession());
			if (pSession)
			{
				pSession->SetReconnect(bReconnect);
				NetSocket objSocket = pSession->GetSocket();
				if (objSocket != -1)
				{
					NetHelper::SetDefaultSocket(objSocket, nSendBuf, nRecvBuf);
					pSession->SetSendBufSize(nSendBuf);
					pSession->SetSendBufSize(nRecvBuf);
				}
			}
		}
		return CErrno::Success();
	} 
예제 #6
0
bool IOCP_Manager::StartAcceptLoop()
{
    if (listen(mListenSocket, SOMAXCONN) == SOCKET_ERROR)
    {
        printf_s("Listen Error\n");
        return false;
    }

    while (true)
    {
        SOCKET acceptedSock = accept(mListenSocket, NULL, NULL);
        if (acceptedSock == SOCKET_ERROR)
        {
            printf_s("accept : invalid socket\n");
            continue;
        }

        SOCKADDR_IN clientaddr;
        int addrlen = sizeof(SOCKADDR_IN);
        getpeername(acceptedSock, (SOCKADDR*)&clientaddr, &addrlen);

        ClientSession* client = GSessionManager->CreateClientSession(acceptedSock);

        if (client->OnConnect(&clientaddr) == false)
        {
            client->Disconnect(DisconnectReason::DR_CONNECT_ERROR);
            GSessionManager->DeleteClientSession(client);
        }
    }
    return true;
}
예제 #7
0
unsigned int WINAPI ThreadProc(LPVOID _hComport)
{
	HANDLE hComport = (HANDLE)_hComport;
	ClientSession* clientSession;
	DWORD bytesTrans = 0;
	IOData* ioData = nullptr;

	while(1)
	{
		if(!GetQueuedCompletionStatus(hComport, &bytesTrans, (PULONG_PTR) &clientSession, (LPOVERLAPPED*) &ioData, INFINITE))
		{
			ErrorHandling("GetQueuedCompletionStatus() error!", GetLastError());
		}
		
		if(ioData->m_Mode == MODE_RECV)
		{
			if(bytesTrans == 0)
			{
				ClientManager::GetInstance()->RemoveClient(clientSession);
			}
			else
			{
				clientSession->PacketHandling(bytesTrans);
				clientSession->RecvFromClient();
			}
		}
		SafeDelete<IOData*>(ioData);
	}

	return 0;
}
예제 #8
0
	bool VNetwork::Accept()
	{
		SOCKET acceptedSock = accept(listenSocket_, NULL, NULL);
		if (acceptedSock == INVALID_SOCKET)
		{
			Logger<VNetwork>::Fatal("Accept : Invalid socket.");
			return false;
		}

		ClientSession* client = sessionManager_.GetSession(sessionID_);
		client->Initialize(acceptedSock);
		client->requestQueue_ = RIOBase::GetInstance()->GetRequestQueue(acceptedSock);

		RioIoContext* mainContext = new RioIoContext(client, IO_RECV, true);
		DWORD flags = 0;

		if (!RIOBase::GetInstance()->RIOReceive(client->requestQueue_, client->GetRecieveBuffer(), 1, flags, mainContext))
		{
			//TODO :  Logger 포멧 적용하기 GetLastError()
			Logger<VNetwork>::Fatal("RIOReceive error.");
			delete mainContext;
			return false;
		}

		sessionID_++;

		return true;
	}
예제 #9
0
bool SessionManager::AcceptSessions()
{
	FastSpinlockGuard guard(mLock);

	while (mCurrentIssueCount - mCurrentReturnCount < MAX_CONNECTION)
	{
		//TODO mFreeSessionList에서 ClientSession* 꺼내서 PostAccept() 해주기.. (위의 ReturnClientSession와 뭔가 반대로 하면 될 듯?)
		// AddRef()도 당연히 해줘야 하고...

	
		// 실패시 false
		//if (false == newClient->PostAccept())
		//	return false;
		////////////////////////////////////////////////////////////
		ClientSession * newClient = mFreeSessionList.back();
		mFreeSessionList.pop_back();
		++mCurrentIssueCount;
		newClient->AddRef();

		if (newClient->PostAccept() == false)
		{
			return false;
		}
		
		////////////////////////////////////////////////////////////
	}


	return true;
}
예제 #10
0
void ClientManager::CollectGarbageSessions()
{
	std::vector<ClientSession*> disconnectedSessions ;
	
	///FYI: C++ 11 람다를 이용한 스타일
	std::for_each(mClientList.begin(), mClientList.end(),
		[&](ClientList::const_reference it)
		{
			ClientSession* client = it.second ;

			if ( false == client->IsConnected() && 0 == client->GetRefCount() )
				disconnectedSessions.push_back(client) ;
		}
	) ;
	

	///FYI: C언어 스타일의 루프
	for (size_t i=0 ; i<disconnectedSessions.size() ; ++i)
	{
		ClientSession* client = disconnectedSessions[i] ;
		mClientList.erase(client->mSocket) ;
		delete client ;
	}

}
예제 #11
0
void ClientListener::OnSessionClose( Session * session )
{
    Logger::Log( "client % disconnected" , session->ip_address() );
    ClientSession * client = ( ClientSession* ) session;
    client->CloseFile();
    ClientPool::Instance()->Pop( ( ClientSession* ) session );
    SAFE_DELETE( session );
}
예제 #12
0
unsigned int WINAPI IocpManager::IoWorkerThread(LPVOID lpParam)
{
	LThreadType = THREAD_IO_WORKER;

	LIoThreadId = reinterpret_cast<int>(lpParam);
	HANDLE hComletionPort = GIocpManager->GetComletionPort();

	while (true)
	{
		DWORD dwTransferred = 0;
		OverlappedIOContext* context = nullptr;
		ClientSession* asCompletionKey = nullptr;

		int ret = 0; ///<여기에는 GetQueuedCompletionStatus(hComletionPort, ..., GQCS_TIMEOUT)를 수행한 결과값을 대입

		/// check time out first 
		if (ret == 0 && GetLastError()==WAIT_TIMEOUT)
			continue;

		if (ret == 0 || dwTransferred == 0)
		{
			/// connection closing
			asCompletionKey->Disconnect(DR_RECV_ZERO);
			GSessionManager->DeleteClientSession(asCompletionKey);
			continue;
		}

		// if (nullptr == context) 인 경우 처리
		//{
		//}

		bool completionOk = true;
		switch (context->mIoType)
		{
		case IO_SEND:
			completionOk = SendCompletion(asCompletionKey, context, dwTransferred);
			break;

		case IO_RECV:
			completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred);
			break;

		default:
			printf_s("Unknown I/O Type: %d\n", context->mIoType);
			break;
		}

		if ( !completionOk )
		{
			/// connection closing
			asCompletionKey->Disconnect(DR_COMPLETION_ERROR);
			GSessionManager->DeleteClientSession(asCompletionKey);
		}

	}

	return 0;
}
예제 #13
0
unsigned int WINAPI	IOCP_Manager::IoWorkerThread(LPVOID lpParam)
{
    LThreadType					= THREAD_TYPE::THREAD_IO_WORKER;

    LIoThreadID					= reinterpret_cast<int>(lpParam);
    HANDLE hCompletionPort		= GIOCP_Manager->GetCompletionPort();
    while (true)
    {
        DWORD					dwTransferred	= 0;
        OverlappedIOContext*	context			= nullptr;
        ClientSession*			asCompletionKey = nullptr;

        int ret = GetQueuedCompletionStatus(hCompletionPort, &dwTransferred, (ULONG_PTR*)&asCompletionKey, (LPOVERLAPPED*)&context, GQCS_TIMEOUT);
        if (ret == 0 && GetLastError() == WAIT_TIMEOUT)
        {
            continue;
        }

        if (ret == 0 || dwTransferred == 0)
        {
            asCompletionKey->Disconnect(DisconnectReason::DR_RECV_ZERO);
            GSessionManager->DeleteClientSession(asCompletionKey);
            continue;
        }

        if (context == nullptr)
        {
            printf_s("not dequeue completion packet\n");
            continue;
        }

        bool completionOk = true;
        switch (context->mIoType)
        {
        case IOType::IO_SEND:
            completionOk = SendCompletion(asCompletionKey, context, dwTransferred);
            break;

        case IOType::IO_RECV:
            completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred);
            break;

        default:
            printf_s("Unkonw I/O type: %d\n", context->mIoType);
            break;
        }

        if (!completionOk)
        {
            asCompletionKey->Disconnect(DisconnectReason::DR_COMPLETION_ERROR);
            GSessionManager->DeleteClientSession(asCompletionKey);
        }
    }

    return 0;
}
예제 #14
0
void ClientManager::FlushClientSend()
{
	for (auto& it : mClientList)
	{
		ClientSession* client = it.second;
		if (false == client->SendFlush())
		{
			client->Disconnect();
		}
	}
}
void GameManager::DoPeriodWork() 
{
	// 게임 로직이 주기적으로 실행되는 곳이므로 게임 내 상태 변화는 여기서 일어나고
	// 상태가 바뀐 부분(충돌이나 죽음, 게임 종료)에 한정해서 방송합니다
	// 주기적 polling이 많은 패킷을 유발하는 것은 방송할 필요가 없는 상태까지 똑같이 방송할 때 생기는 것 아닌가요??

	// 충돌 이벤트를 여기서 방송하는 이유는 충돌 판정이 되었을 때 바로 방송할 경우 
	// 특정 캐릭터가 여러 오브젝트와 동시에 충돌할 경우, 각각의 충돌 판정 수만큼 패킷을 보내므로 중복이라고 생각해서
	// 충돌 판정 된 캐릭터들 리스트를 생성하고 일괄적으로 한번씩만 보내기 위함이거든요.

	// 게임 로직 진행
	Update();

	// 충돌 결과 방송
	std::for_each( m_CollidedPlayers.begin(), m_CollidedPlayers.end(), []( const int& each )
	{
		// 방송 요청
		ClientSession* targetSession = GClientManager->GetSession( each );
		if ( targetSession )
			targetSession->BroadcastCollisionResult();
		else
			DDLOG_WARN( L"invalid index" );
		// printf_s( "collision : %d \n", each );
	}
	);
	m_CollidedPlayers.clear();

	// 죽음(산소 == 0) 방송
	std::for_each( m_DeadPlayers.begin(), m_DeadPlayers.end(), []( const int& each )
	{
		// 방송 요청
		ClientSession* targetSession = GClientManager->GetSession( each );

		if ( targetSession )
			targetSession->BroadcastDeadResult();
		else
			DDLOG_WARN( L"invalid index" );
	}
	);
	m_DeadPlayers.clear();

	// 게임 종료 조건 확인
	if ( m_WinnerTeam != TeamColor::NO_TEAM && !m_GameEndFlag )
	{
		DDLOG_INFO( L"game end" );
		m_GameEndFlag = true;

		// 방송 요청
		GameResultResult outPacket;
		outPacket.mWinnerTeam = static_cast<int>( m_WinnerTeam );

		GClientManager->BroadcastPacket( nullptr, &outPacket );
	}
}
void ForSClientMsgHandler::ServerToClient(BaseSession* pSessioin,const NetMsgHead* pHead,int32 nSize)
{

	ClientSession* pClientSession = ClientSessionMgr::Instance()->GetSession(pHead->nClientSessionID);
	if(pClientSession == NULL)
	{
		return;
	}
	pClientSession->SendMsg(const_cast<NetMsgHead*>(pHead),nSize);

}
예제 #17
0
ClientSession* SessionManager::CreateClientSession(SOCKET sock)
{
	ClientSession* client = new ClientSession(sock);
	client->AddRef();

	mLock.EnterLock();
	{
		mClientList.insert(ClientList::value_type(sock, client));
	}
	mLock.LeaveLock();

	return client;
}
예제 #18
0
void ClientManager::BroadcastPacket(ClientSession* from, PacketHeader* pkt)
{
	///FYI: C++ STL iterator 스타일의 루프
	for (ClientList::const_iterator it=mClientList.begin() ; it!=mClientList.end() ; ++it)
	{
		ClientSession* client = it->second ;
		
		if ( from == client )
			continue ;
		
		client->SendRequest(pkt) ;
	}
}
예제 #19
0
unsigned int WINAPI ClientHandlingThread( LPVOID lpParam )
{
	LThreadType = THREAD_CLIENT ;

	HANDLE hEvent = (HANDLE)lpParam ;

	/// Timer
	HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL) ;
	if (hTimer == NULL)
		return -1 ;

	LARGE_INTEGER liDueTime ;
	liDueTime.QuadPart = -10000000 ; ///< 1초 후부터 동작
	if ( !SetWaitableTimer(hTimer, &liDueTime, 1, TimerProc, NULL, TRUE) )
		return -1 ;
		

	while ( true )
	{
		/// accept or IO/Timer completion   대기
		DWORD result = WaitForSingleObjectEx(hEvent, INFINITE, TRUE) ;

		/// client connected
		if ( result == WAIT_OBJECT_0 )
		{
	
			/// 소켓 정보 구조체 할당과 초기화
			
			ClientSession* client = g_client_manager->CreateClient(g_AcceptedSocket) ;
			
			SOCKADDR_IN clientaddr ;
			int addrlen = sizeof(clientaddr) ;
			getpeername(g_AcceptedSocket, (SOCKADDR*)&clientaddr, &addrlen) ;

			// 클라 접속 처리
			if ( false == client->OnConnect(&clientaddr) )
			{
				client->Disconnect() ;
			}
		
			continue ; ///< 다시 대기로
		}

		// APC에 있던 completion이 아니라면 에러다
		if ( result != WAIT_IO_COMPLETION )
			return -1 ;
	}

	CloseHandle( hTimer ) ;
	return 0;
} 
예제 #20
0
unsigned int WINAPI ClientHandlingThread( LPVOID lpParam )
{
	LThreadType = THREAD_CLIENT;

	PendingAcceptList* pAcceptList = (PendingAcceptList*)lpParam;

	/// Timer
	HANDLE hTimer = CreateWaitableTimer( NULL, FALSE, NULL );
	if ( hTimer == NULL )
		return -1;

	LARGE_INTEGER liDueTime;
	liDueTime.QuadPart = -10000000; ///< 1초 후부터 동작
	if ( !SetWaitableTimer( hTimer, &liDueTime, 100, TimerProc, NULL, TRUE ) )
		return -1;

	while ( true )
	{
		SOCKET acceptSock = NULL;

		/// 새로 접속한 클라이언트 처리
		if ( pAcceptList->Consume( acceptSock, false ) )
		{
			/// 소켓 정보 구조체 할당과 초기화
			ClientSession* client = GClientManager->CreateClient( acceptSock );

			SOCKADDR_IN clientaddr;
			int addrlen = sizeof( clientaddr );
			getpeername( acceptSock, (SOCKADDR*)&clientaddr, &addrlen );

			// 클라 접속 처리
			if ( false == client->OnConnect( &clientaddr ) )
			{
				client->Disconnect();
			}

			continue; ///< 다시 대기로
		}

		/// 최종적으로 클라이언트들에 쌓인 send 요청 처리
		GClientManager->FlushClientSend();

		/// APC Queue에 쌓인 작업들 처리
		SleepEx( INFINITE, TRUE );
	}

	CloseHandle( hTimer );
	return 0;
}
예제 #21
0
void CALLBACK RecvCompletion(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
{
	ClientSession* fromClient = static_cast<OverlappedIO*>(lpOverlapped)->mObject;

	fromClient->DecRefCount();

	if (!fromClient->IsConnected())
		return;

	/// 에러 발생시 해당 세션 종료
	if (dwError || cbTransferred == 0)
	{
		fromClient->Disconnect();
		return;
	}

	/// 받은 데이터 처리
	fromClient->OnRead(cbTransferred);

	/// 다시 받기
	if (false == fromClient->PostRecv())
	{
		fromClient->Disconnect();
		return;
	}
}
///////////////////////////////////////////////////////////
// 비동기 입력 WSARecv()에 의해서, 입력이 완료 되면 콜백으로 RecvCompletion 실행
void CALLBACK RecvCompletion( DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags )
{

	// lpOverlapped 인자를 OverlappedIO 형태로 형변환 하면
	// 해당 구조체의 멤버 변수 mObject => ClientSession*
	// 바로 이 포인터가 비동기 입력 WSARecv로 보낸 ClientSession 객체의 주소값
	// PostRecv 멤소드에서 mOverlappedRecv.mObject = this ; 이 부분 참조
	ClientSession* fromClient = static_cast<OverlappedIO*>( lpOverlapped )->m_Object;

	// Overlapped IO 완료 했음. 카운트 감소
	fromClient->DecOverlappedRequest();

	if ( !fromClient->IsConnected() )
		return;

	/// 에러 발생시 해당 세션 종료
	if ( dwError || cbTransferred == 0 )
	{
		LogD( "[Disconnected from:]ClientSession::RecvCompletion dwError \n" );
		fromClient->Disconnect();
		return;
	}

	/// 받은 데이터 처리
	fromClient->OnRead( cbTransferred );

	/// 다시 받기
	if ( false == fromClient->PostRecv() )
	{
		LogD( "[Disconnected from:]ClientSession::RecvCompletion PostRecv \n" );
		fromClient->Disconnect();
		return;
	}
}
예제 #23
0
//
// Database test driver class
//
DbTester::DbTester(ClientSession &ss, const char *path,
	const AccessCredentials *cred, int timeout, bool sleepLock) 
: session(ss), dbId(ssuid, path, NULL)
{
	params.idleTimeout = timeout;
	params.lockOnSleep = sleepLock;
	dbRef = ss.createDb(dbId, cred, NULL, params);
	detail("Database %s created", path);
}
예제 #24
0
파일: ClientSession.cpp 프로젝트: SlowT/CSM
void CALLBACK SendCompletion( DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags )
{
	ClientSession* fromClient = static_cast<OverlappedIO*>(lpOverlapped)->mObject;

	fromClient->DecOverlappedRequest();

	if ( !fromClient->IsConnected() )
		return;

	/// 에러 발생시 해당 세션 종료
	if ( dwError || cbTransferred == 0 )
	{
		fromClient->Disconnect();
		return;
	}

	fromClient->OnWriteComplete(cbTransferred);
}
예제 #25
0
ClientSession* SessionManager::IssueClientSession()
{
	FastSpinlockGuard guard(mLock);

	uint64_t threadId = (mCurrentIssueCount++ % MAX_RIO_THREAD) + 1;
	CRASH_ASSERT(threadId > 0);

	CRASH_ASSERT((mCurrentIssueCount - mCurrentReturnCount) <= (MAX_RIO_THREAD*MAX_CLIENT_PER_RIO_THREAD));

	ClientSession* newClient = mFreeSessionList[threadId].back();
	mFreeSessionList[threadId].pop_back();

	newClient->AddRef();

	mOccupiedSessionList.push_back(newClient);

	return newClient;
}
예제 #26
0
bool SessionManager::PrepareSessionPool()
{
	CRASH_ASSERT(LIoThreadId == MAIN_THREAD_ID);

	for (int i = 1; i <= MAX_RIO_THREAD; ++i)
	{
		for (int j = 0; j < MAX_CLIENT_PER_RIO_THREAD; ++j)
		{
			ClientSession* client = new ClientSession(i);
			if (false == client->RioInitialize())
				return false;

			mFreeSessionList[i].push_back(client);
		}
	}

	return true;
}
void GameManager::BroadcastCharacterChange( int targetId, ChangeType type )
{
	ClientSession* targetSession = GClientManager->GetSession( targetId );
	assert( targetSession );

	switch ( type )
	{
	case ChangeType::KINETIC_STATE:
		targetSession->BroadcastKineticState( true, true );
		break;
	case ChangeType::CHARACTER_STATE:
		targetSession->BroadcastCharacterState( );
		break;
	case ChangeType::RESOURCE_GATHER:
		targetSession->BroadcastGatherResult( );
		break;
	default:
		break;
	}
}
예제 #28
0
bool ClientSessionManager::AcceptClientSessions()
{
	FastSpinlockGuard guard(mLock);

	while (mCurrentIssueCount - mCurrentReturnCount < MAX_CONNECTION)
	{
		ClientSession* newClient = mFreeSessionList.back();
		mFreeSessionList.pop_back();

		++mCurrentIssueCount;

		newClient->AddRef(); ///< refcount +1 for issuing 
		
		if (false == newClient->PostAccept())
			return false;
	}


	return true;
}
예제 #29
0
	CErrno NetThread::FetchClientsQueue()
	{
		SCreateInfo objInfo;
		while (m_queCreateClients.try_pop(objInfo))
		{
			INetHandlerPtr pNetHandler = CreateClientHandler(objInfo.strNodeName, objInfo.strUUID, objInfo.strAddress.c_str(), objInfo.usPort);
			if (!pNetHandler)
			{
				continue;
			}

			ClientSession * pSession = dynamic_cast<ClientSession*>(pNetHandler->GetSession());			
			if (pSession)
			{
				pSession->SetReconnect(objInfo.bReconnect);
			}
		}

		return CErrno::Success();
	}
예제 #30
0
void ProcServerHandler::DbRoleCreate(void* pSession,const void* pData)
{

#pragma pack(push,1)
	struct StCreateResult
	{
		int64 nNewCharID;
		int32 nAccountID;
	};
#pragma pack(pop)

	ClientSession* pClientSession = static_cast<ClientSession*>(pSession);
	const DbRecordSet* pRecordSet = static_cast<const DbRecordSet*>(pData);
	const StCreateResult* pCreateResult = static_cast<const StCreateResult*>(pRecordSet->GetRecordData(0));
	int64  nNewID = pCreateResult->nNewCharID;
	int32  nAccountID = pCreateResult->nAccountID;

	D2LRoleCreateResult sMsg;
	if(nNewID == 0)
	{
		sMsg.nResult = D2LRoleCreateResult::E_FAIL_SYNC;
	}else if(nNewID == 1)
	{
		sMsg.nResult = D2LRoleCreateResult::E_FAIL_ROLE_MAX;
	}
	else if (nNewID == 2)
	{
		sMsg.nResult = D2LRoleCreateResult::E_FAIL_NAME_EXIST;
	}
	else if (nNewID == 3)
	{
		sMsg.nResult = D2LRoleCreateResult::E_FAIL_INSERT_FAIL;
	}else
	{
		sMsg.nNewCharID = nNewID;
		sMsg.nResult = D2LRoleCreateResult::E_SUCCESS;
		QueryCharacterList(pClientSession,nAccountID,0);
	}
	pClientSession->SendMsgToLs(&sMsg,sMsg.GetPackLength());

}