bool GameServer::GeneratePacketSourceCode_AS3(int packetCode, const _String sDumpDir, const TCHAR* pszPackage, const TCHAR* pszSerializeBasePackage){ BasePacket* packet = m_pPacketHandler->CreatePacketByCode(packetCode); if( !packet ) return false; _String sSaveDir = sDumpDir; Path::BuildFullPath(sSaveDir); StringToStringArray arrGenPackages; if( !packet->GenerateSourceCodeInAS3(arrGenPackages, pszPackage, pszSerializeBasePackage) ){ delete packet; return false; } if( sSaveDir.GetAt(sSaveDir.GetLength() - 1) != '\\' ) sSaveDir += _T("\\"); _String sPackage, sSourceCode, sFile; for(int i=0; i<arrGenPackages.GetCount(); i++){ sPackage = arrGenPackages.GetKey(i); sSourceCode = arrGenPackages.GetValueByIndex(i); sFile.Format(_T("%s%s.as"),sSaveDir.GetBuffer(), sPackage.GetBuffer()); Path::SaveAsFile(sSourceCode.GetBuffer(), sSourceCode.GetLength(), sFile); } return true; }
// libeasy copy packet BasePacket* BasePacketStreamer::clone_packet(BasePacket* src) { int32_t pcode = src->getPCode(); int64_t length = src->length(); BasePacket* dest = dynamic_cast<BasePacket*>(_factory->createPacket(pcode)); assert(NULL != dest); // Stream stream(length); dest->stream_.expand(length); int ret = src->serialize(dest->stream_); if (TFS_SUCCESS == ret) { ret = dest->deserialize(dest->stream_); } TBSYS_LOG_DW(ret, "clone packet, ret=%d, pcode=%d, length=%ld, src=%p, dest=%p", ret, pcode, length, src, dest); if (TFS_SUCCESS != ret) { tbsys::gDelete(dest); dest = NULL; } else { dest->setChannelId(src->getChannelId()); dest->set_request(src->get_request()); dest->set_direction(src->get_direction()); } return dest; }
void SFMultiLogicDispatcher::MultiLogicProc(void* Args) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = static_cast<SFIOCPQueue<BasePacket>*>(Args); #else SFLockQueue<BasePacket>* pQueue = static_cast<SFLockQueue<BasePacket>*>(Args); #endif LogicEntry::GetInstance()->Initialize(); while (true) { BasePacket* pPacket = pQueue->Pop(-1); if (pPacket == nullptr) continue; if (pPacket->GetPacketType() == SFPACKET_SERVERSHUTDOWN) break; else { LogicEntry::GetInstance()->ProcessPacket(pPacket); if (pPacket->GetPacketType() != SFPACKET_DB) { ReleasePacket(pPacket); } } } }
BasePacket* SFProtobufProtocol::GetPacket(int& ErrorCode) { //The Processing Loop. int uCommandID; BasePacket* pPacket = NULL; int iResult; unsigned int uExtractedBytes; ErrorCode = 0; //watch.GetElapsedTime(false); iResult = tryDeserializeIncomingPacket(m_Buffer , pPacket, uCommandID, uExtractedBytes); //iResult = pProtocol->tryDeframeIncomingPacket(pChannel->GetReceiveBuffer().GetBuffer(), pChannel->GetReceiveBuffer().GetDataSize(),uCommandID, pPacket, uExtractedBytes); //wcout << L"Packet deframed : " << watch.GetElapsedTime(false) << std::endl; if (iResult == SFProtocol::Success) { m_Buffer.Pop(uExtractedBytes); pPacket->SetPacketID(uCommandID); } else if (iResult == SFProtocol::eDecodingFailure) { m_Buffer.Pop(uExtractedBytes); ErrorCode = -1; return NULL; } return pPacket; }
bool GameServer::GeneratePacketSourceCode_CSharp(int packetCode, _String& strSource){ BasePacket* packet = m_pPacketHandler->CreatePacketByCode(packetCode); if( !packet ) return false; bool bRet = packet->GenerateSourceCodeInCSharp(strSource, true); delete packet; return bRet; }
bool SFCasualGameDispatcher::ShutDownLogicSystem() { m_bLogicEnd = true; BasePacket* pCommand = PacketPoolSingleton::instance()->Alloc(); pCommand->SetSerial(-1); pCommand->SetPacketType(SFPACKET_SERVERSHUTDOWN); LogicGatewaySingleton::instance()->PushPacket(pCommand); return true; }
bool SFEngine::OnDisconnect(int serial, _SessionDesc& desc) { BasePacket* pPacket = new BasePacket(); pPacket->SetSessionDesc(desc); pPacket->SetPacketType(SFPACKET_DISCONNECT); pPacket->SetSerial(serial); m_pLogicDispatcher->Dispatch(pPacket); return true; }
bool SFEngine::OnTimer(const void *arg) { UNREFERENCED_PARAMETER(arg); BasePacket* pPacket = new BasePacket(); pPacket->SetPacketType(SFPACKET_TIMER); pPacket->SetSerial(-1); m_pLogicDispatcher->Dispatch(pPacket); return true; }
bool SFEngine::OnTimer(const void *arg) { int timerId = (int)arg; BasePacket* pPacket = new BasePacket(); pPacket->SetPacketType(SFPACKET_TIMER); pPacket->SetSerial(timerId); m_pLogicDispatcher->Dispatch(pPacket); return true; }
uint64_t BasePacketStreamer::get_packet_id_handler(easy_connection_t *c, void *packet) { UNUSED(c); int32_t packet_id = 0; if (packet != NULL) { BasePacket *bp = (BasePacket*)packet; packet_id = bp->getChannelId(); } if (packet_id == 0) { while (packet_id == 0 || packet_id == -1) { packet_id = (int32_t)easy_atomic32_add_return(&global_chid, 1); } } return packet_id; }
bool GameServer::DispatchReceivedData(SocketContext* pSockConn, BYTE* pData, DWORD dwSize, bool bIsFirstData){ ASSERT(m_pPacketHandler && pData && dwSize > 0); if( !pData || !dwSize ) return false; ClientConnection* pConn = (ClientConnection*)pSockConn->GetParam(); GrowableMemory mem(0, 0, false); mem.SetReadonlyBuffer(pData, dwSize); if( !pConn ) return false; BasePacket basePacket; int nOffset = 0; int nBufferSize = dwSize; int nSerializedBytes = 0; while( TRUE ){ if( basePacket.Deserialize(&mem) ){ // Success // Handshake must be the only one command accepted while session is not created. if( (basePacket.m_nCode != PacketCodes::_HandShake && basePacket.m_nCode != PacketCodes::_AcquireTableAccess) && pConn->GetSession(false) == NULL ) return false; BasePacket* packet = m_pPacketHandler->CreatePacketByCode(basePacket.m_nCode); ASSERT( packet ); #ifndef _DEBUG if( packet == NULL ) return false; #endif // Deserialize received data into known packet. if( !mem.SetCurrentOffset(nOffset) ) return false; if( !packet->Deserialize(&mem) ) return false; // Handle received packet. OnPacketReceived(pConn, packet); delete packet; nOffset = mem.GetCurrentOffset(); if( nOffset == nBufferSize ) break; } else break; } return true; }
bool SFNETDispatcher::ShutDownLogicSystem() { m_bLogicEnd = true; for (int i = 0; i < m_nLogicThreadCnt; i++) { BasePacket* pCommand = PacketPoolSingleton::instance()->Alloc(); pCommand->SetSerial(-1); pCommand->SetPacketType(SFPACKET_SERVERSHUTDOWN); LogicGatewaySingleton::instance()->PushPacket(pCommand); } ACE_Thread_Manager::instance()->wait_grp(m_logicThreadGroupId); LogicEntrySingleton::instance()->DestroyLogic(); return true; }
void SFMulitiCasualGameDispatcher::CasualGameLogicProc(void* Args) { CasualGameParam* pParam = static_cast<CasualGameParam*>(Args); SFIOCPQueue<BasePacket>* pQueue = pParam->pQueue; ILogicEntry* pEntry = pParam->pLogicEntry; while (m_bLogicEnd == false) { BasePacket* pPacket = pQueue->Pop(INFINITE); if (pPacket) { pEntry->ProcessPacket(pPacket); if (pPacket->GetPacketType() != SFPACKET_DB) { ReleasePacket(pPacket); } } } }
BOOL SFTCPNetwork::Update() { while (1) { BasePacket* pPacket = LogicGatewaySingleton::instance()->PopPacket(0); if (pPacket != NULL) { switch (pPacket->GetPacketType()) { case SFPACKET_DATA: m_pTCPCallBack->HandleNetworkMessage(pPacket); m_TCPClient->ReleasePacket(pPacket); break; case SFPACKET_RPC: lfds611_queue_guaranteed_enqueue(m_pQueue, pPacket); break; case SFPACKET_CONNECT: m_pTCPCallBack->HandleConnect(pPacket->GetOwnerSerial()); delete pPacket; break; case SFPACKET_DISCONNECT: m_pTCPCallBack->HandleDisconnect(pPacket->GetOwnerSerial()); delete pPacket; break; } } else { break; } } return TRUE; }
BOOL SFDirectoryWatcherTask::ProcessShouterTask() { m_Shouter.Initialize(); m_Shouter.Read(_T("Shouter.xml")); _ShouterInfo* pInfo = m_Shouter.GetShouterInfo(); if(pInfo->SentenceList.size() == 0) return FALSE; for(int i = 0; i < pInfo->RepeatCount; i++) { std::list<std::wstring>::iterator iter = pInfo->SentenceList.begin(); if(i != 0) Sleep(pInfo->MessageInterval); DWORD Count = 0; for(;iter != pInfo->SentenceList.end(); iter++) { if(Count != 0) Sleep(pInfo->SentenceInterval); BasePacket* pCommand = new BasePacket(); pCommand->SetPacketType(SFPACKET_SHOUTER); pCommand->SetSerial(-1); LogicGatewaySingleton::instance()->PushPacket(pCommand); #ifdef _DEBUG _tprintf( _T("Shout : %s\n"), iter->c_str()); #endif Count++; } } return TRUE; }
bool SFMultiLogicDispatcher::ShutDownLogicSystem() { BasePacket* pCommand = SFPacketPool::GetInstance()->Alloc(); pCommand->SetSerial(-1); pCommand->SetPacketType(SFPACKET_SERVERSHUTDOWN); SFLogicGateway::GetInstance()->PushPacket(pCommand); if (m_packetDistrubutor->joinable()) m_packetDistrubutor->join(); for (auto& thread : m_mapThread) { tthread::thread* pThread = thread.second; if (pThread->joinable()) { pThread->join(); delete pThread; } } m_mapThread.clear(); for (auto& queue : m_mapQueue) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = queue.second; #else SFLockQueue<BasePacket>* pQueue = queue.second; #endif delete pQueue; } m_mapQueue.clear(); LogicEntry::GetInstance()->Destroy(); return true; }
void SFCasualGameDispatcher::LogicThreadProc(void* Args) { UNREFERENCED_PARAMETER(Args); SFEngine* pEngine = SFEngine::GetInstance(); while (m_bLogicEnd == false) { //로직게이트웨이 큐에서 패킷을 꺼낸다. BasePacket* pPacket = LogicGatewaySingleton::instance()->PopPacket(); //로직엔트리 객체의 ProcessPacket 메소드를 호출해서 패킷 처리를 수행한다. LogicEntrySingleton::instance()->ProcessPacket(pPacket); //사용한 패킷을 수거한다. 패킷의 타입에 따라 릴리즈 형태가 다름 switch (pPacket->GetPacketType()) { case SFPACKET_DATA: pEngine->ReleasePacket(pPacket); break; case SFPACKET_CONNECT: case SFPACKET_DISCONNECT: case SFPACKET_TIMER: case SFPACKET_SHOUTER: delete pPacket; break; case SFPACKET_DB: SFDatabase::RecallDBMsg((SFMessage*)pPacket); break; case SFPACKET_SERVERSHUTDOWN: return; default: SFASSERT(0); } } }
BasePacket* SFAvroProtocol::GetPacket(int& errorCode) { errorCode = PACKETIO_ERROR_NONE; SFPacketHeader header; if (false == m_pPacketIOBuffer->GetHeader(header, errorCode)) return NULL; BasePacket* pPacket = CreateIncomingPacketFromPacketId(header.packetID); if (pPacket == NULL) return NULL; SFAvroPacketImpl* pAvroPacket = (SFAvroPacketImpl*)pPacket; memcpy(pAvroPacket->GetHeader(), &header, sizeof(SFPacketHeader)); char dataBuffer[8096] = { 0, }; if (false == m_pPacketIOBuffer->GetPacket(header, dataBuffer, m_packetSize, errorCode)) { DisposePacket(pPacket); return NULL; } if (false == pPacket->Decode(dataBuffer, header.dataSize)) { errorCode = PACKETIO_ERROR_DATA; DisposePacket(pPacket); return NULL; } pPacket->SetPacketID(header.packetID); return pPacket; }
BOOL SGBattle::BroadCast(BasePacket& packet) { SFRoom* pRoom = GetOwner()->GetOwner(); auto& roomMember = pRoom->GetRoomMemberMap(); for (auto& iter : roomMember) { SFPlayer* pPlayer = iter.second; packet.SetSerial(pPlayer->GetSerial()); SFEngine::GetInstance()->SendRequest(&packet); } return TRUE; }
bool TEMPLATE_SERVER_CLASS::handlePacketQueue( tbnet::Packet * apacket, void *args) { TBSYS_LOG(DEBUG,"%s", "TEMPLATE_SERVER_CLASS::handlePacketQueue"); BasePacket *packet = (BasePacket *) apacket; tbnet::Connection* conn=packet->get_connection(); int64_t now_time=tbsys::CTimeUtil::getTime(); if (now_time - packet->get_recv_time() > PACKET_IN_PACKET_QUEUE_THREAD_MAX_TIME) { //PacketQueueThread中排队3min的请求丢弃 queueThreadTimeoutThrowPackets_++; TBSYS_LOG(DEBUG,"queueThreadTimeoutThrowPackets_=%d", queueThreadTimeoutThrowPackets_); return true; } if (conn==NULL || conn->isConnectState()==false) { //失效连接上的请求丢弃 //避免失效连接上的业务处理消耗大量的时间 clientDisconnThrowPackets_++; TBSYS_LOG(DEBUG,"clientDisconnThrowPackets_=%d", clientDisconnThrowPackets_); return true; } int pcode = apacket->getPCode(); switch (pcode) { case REQUEST_PACKET: { TBSYS_LOG(DEBUG,"%s","REQUEST_PACKET"); RequestPacket *req = (RequestPacket *)packet; //检查注册状态 ResponsePacket* resp=new ResponsePacket(); if (NULL==resp) { return true; } resp->setChannelId(req->getChannelId()); resp->src_type_=req->dest_type_; resp->src_id_=req->dest_id_; resp->dest_type_=req->src_type_; resp->dest_id_=req->src_id_; resp->msg_id_=req->msg_id_+1; resp->error_code_=0; if (PUBLIC_REGISTER_REQ==req->msg_id_) { if (false == conn_manager_from_client_.IsSupportServerType( req->src_type_)) { resp->error_code_=3; TBSYS_LOG(DEBUG,"%s","server_type not supported"); } if (0!= conn_manager_from_client_.Register( req->src_id_, conn)) { resp->error_code_=1; TBSYS_LOG(DEBUG,"%s","register fail"); } if (false==conn->postPacket(resp)) { delete resp; } return true; } if (false==conn_manager_from_client_.IsRegister( req->src_id_)) { resp->error_code_=2; if (false==conn->postPacket(resp)) { delete resp; } TBSYS_LOG(DEBUG,"%s","not register"); return true; } //普通业务处理 resp->set_recv_time(now_time); Handler handler=HANDLER_ROUTER.GetHandler( req->msg_id_); if (NULL==handler) { resp->error_code_=4; } else { handler(req,NULL,resp); } conn_manager_from_client_.PostPacket( resp->dest_id_, resp); return true; } break; case RESPONSE_PACKET: { TBSYS_LOG(DEBUG,"%s","RESPONSE_PACKET"); } break; } return true; }
STDMETHODIMP BasicPacketFlow::OnPacket(UINT16 uStreamNumber, BasePacket** ppPacket) { if (m_bIsDone) return HXR_UNEXPECTED; PacketStream* pStream = &m_pStreams[uStreamNumber]; HX_ASSERT(pStream->m_bStreamRegistered); BasePacket* pPacket; for (; (pPacket = *ppPacket); ppPacket++) { // Do not check for IsStreamDone() because this is part of the // resend mechanism if (pPacket->IsResendRequested() && pPacket->m_uPriority != 10) continue; if (!pPacket->IsResendRequested()) pPacket->SetResendRequested(); UINT32 ulPos = m_ulResendIDPosition + 1; if (ulPos == MAX_RESENDS_PER_SECOND) ulPos = 0; while (m_pResendIDs[ulPos] && ulPos != m_ulResendIDPosition) { ulPos++; if (ulPos == MAX_RESENDS_PER_SECOND) ulPos = 0; } if (m_pResendIDs[m_ulResendIDPosition = ulPos]) continue; PacketFlowResendCallback* pResendCB = new (m_pProc->pc->mem_cache) PacketFlowResendCallback(); pResendCB->AddRef(); pResendCB->m_pTransport = pStream->m_pTransport; pResendCB->m_pPacket = pPacket; pResendCB->m_pPacket->AddRef(); pResendCB->m_pZeroMe = m_pResendIDs + m_ulResendIDPosition; UINT32 ulMinWaitTime; if ((m_pRateManager) && (m_pRateManager->GetActualDeliveryRate() > 60000)) ulMinWaitTime = 500; else ulMinWaitTime = 10; UINT32 ulTime = rand() % 300 + ulMinWaitTime; // printf("%p %p %p %p %p\n", this, m_pProc, m_pProc->pc, m_pProc->pc->engine, // m_pProc->pc->engine->schedule); // fflush(stdout); m_pResendIDs[m_ulResendIDPosition] = m_pProc->pc->engine->schedule.enter( m_pProc->pc->engine->now + Timeval(0, ulTime * 1000), pResendCB); pResendCB->Release(); } return HXR_OK; }
bool BasePacketStreamer::encode(tbnet::Packet* packet, tbnet::DataBuffer* output) { bool bret = NULL != packet && NULL != output; if (bret) { tbnet::PacketHeader* header = packet->getPacketHeader(); int32_t old_len = output->getDataLen(); BasePacket* bpacket = dynamic_cast<BasePacket*>(packet); int32_t iret = TFS_SUCCESS; int32_t header_length = 0; int64_t pos = 0; //v1 if (TFS_PACKET_VERSION_V1 == bpacket->get_version()) { TfsPacketNewHeaderV1 pheader; pheader.crc_ = bpacket->get_crc(); pheader.flag_ = TFS_PACKET_FLAG_V1; pheader.id_ = bpacket->get_id(); pheader.length_ = bpacket->get_data_length(); pheader.type_ = header->_pcode; pheader.version_ = bpacket->get_version(); header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); }//v2 tbnet else if (TFS_PACKET_VERSION_V2 == bpacket->get_version()) { TfsPacketNewHeaderV1 pheader; pheader.crc_ = bpacket->get_crc(); pheader.flag_ = TFS_PACKET_FLAG_V1; pheader.id_ = bpacket->getChannelId(); pheader.length_ = bpacket->get_data_length(); pheader.type_ = header->_pcode; pheader.version_ = bpacket->get_version(); header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); } else//v0 { TfsPacketNewHeaderV1 pheader; memset(&pheader, 0, sizeof(pheader)); pheader.flag_ = TFS_PACKET_FLAG_V0; char* header_data = reinterpret_cast<char*>(&pheader); int32_t length = TFS_PACKET_HEADER_V0_SIZE - 2; for (int32_t i = 0; i < length; i++) { pheader.version_ = static_cast<uint16_t>(*(header_data + i)); } header_length = pheader.length(); output->ensureFree(header_length + pheader.length_); iret = pheader.serialize(output->getFree(), output->getFreeLen(), pos); } bret = TFS_SUCCESS == iret; if (bret) { //TBSYS_LOG(DEBUG, "pcode: %d, header length: %d, body length : %" PRI64_PREFIX "d", bpacket->getPCode(), header_length, bpacket->get_data_length()); //Func::hex_dump(output->getData(), output->getDataLen()); output->pourData(header_length); bret = bpacket->encode(output); //Func::hex_dump(output->getData(), output->getDataLen()); } else { TBSYS_LOG(ERROR, "encode erorr, pcode: %d", header->_pcode); output->stripData(output->getDataLen() - old_len); } } return bret; }
int BasePacketStreamer::encode_handler(easy_request_t *r, void *packet) { BasePacket* bp = (BasePacket*)packet; int32_t pcode = bp->getPCode(); int64_t length = bp->length(); TBSYS_LOG(DEBUG, "encode packet, pcode=%d, length=%ld, chid=%d", pcode, length, bp->getChannelId()); if (EASY_TYPE_CLIENT == r->ms->c->type) { uint32_t chid = ((easy_session_t*)r->ms)->packet_id; bp->setChannelId(chid); } else { if (((easy_message_t*)r->ms)->status == EASY_MESG_DESTROY) { return EASY_ERROR; } if (r->retcode == EASY_ABORT) { r->ms->c->pool->ref--; easy_atomic_dec(&r->ms->pool->ref); r->retcode = EASY_OK; } } easy_list_t list; easy_list_init(&list); Stream output(r->ms->pool, &list); output.reserve(TFS_PACKET_HEADER_V1_SIZE + bp->length()); output.set_int32(TFS_PACKET_FLAG_V1); char* len_pos = output.get_free(); // length() may not equal real data length output.set_int32(bp->length()); output.set_int16(bp->getPCode()); output.set_int16(TFS_PACKET_VERSION_V2); output.set_int64(bp->getChannelId()); output.set_int32(0); // crc, place holder if (TFS_SUCCESS != bp->serialize(output)) { return EASY_ERROR; } // use real length to replace header length if (bp->length() != output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE) { // help to detect serialize problem TBSYS_LOG(DEBUG, "length()=%ld not equals to serialize()=%ld", bp->length(), output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE); int64_t pos = 0; Serialization::set_int32(len_pos, INT_SIZE, pos, output.get_data_length() - TFS_PACKET_HEADER_V1_SIZE); } easy_request_addbuf_list(r, &list); return EASY_OK; }
void SceneObjectImplementation::broadcastMessagesPrivate(Vector<BasePacket*>* messages, SceneObject* selfObject) { ZoneServer* zoneServer = getZoneServer(); if (zoneServer != NULL && zoneServer->isServerLoading()) return; if (parent.get() != NULL) { ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get()); if (grandParent != NULL) { grandParent->broadcastMessagesPrivate(messages, selfObject); return; } else { while (!messages->isEmpty()) { delete messages->remove(0); } return; } } if (zone == NULL) { while (!messages->isEmpty()) { delete messages->remove(0); } return; } //getZone()->rlock(); //Locker zoneLocker(zone); bool readlock = !zone->isLockedByCurrentThread(); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; int maxInRangeObjectCount = 0; // zone->rlock(readlock); try { if (closeobjects == NULL) { info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagesPrivate", true); zone->getInRangeObjects(getPositionX(), getPositionY(), 192, &closeSceneObjects, true); maxInRangeObjectCount = closeSceneObjects.size(); } else { maxInRangeObjectCount = closeobjects->size(); closeSceneObjects.removeAll(maxInRangeObjectCount, 10); //closeSceneObjects.addAll(*closeobjects); closeobjects->safeCopyTo(closeSceneObjects); maxInRangeObjectCount = closeSceneObjects.size(); } } catch (Exception& e) { } //getZone()->runlock(); //zoneLocker.release(); // zone->runlock(readlock); for (int i = 0; i < maxInRangeObjectCount; ++i) { SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get()); if (selfObject == scno) continue; ManagedReference<ZoneClientSession*> client = scno->getClient(); if (scno->isVehicleObject() || client != NULL || scno->isMount()) { for (int j = 0; j < messages->size(); ++j) { BasePacket* msg = messages->get(j); scno->sendMessage(msg->clone()); } } } while (!messages->isEmpty()) { delete messages->remove(0); } }
void SFMultiLogicDispatcher::PacketDistributorProc(void* Args) { SFMultiLogicDispatcher* pDispatcher = static_cast<SFMultiLogicDispatcher*>(Args); while (true) { BasePacket* pPacket = SFLogicGateway::GetInstance()->PopPacket(); if (pPacket->GetPacketType() == SFPACKET_CONNECT) { pDispatcher->RegisterClient(pPacket); } if (pPacket->GetPacketType() == SFPACKET_TIMER) { for (auto& iter : pDispatcher->m_mapQueue) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = iter.second; #else SFLockQueue<BasePacket>* pQueue = iter.second; #endif pQueue->Push(pPacket); //일단 한스레드에만 패킷을 넘기고 전체 로직 스레드에게 타이머 패킷을 보낼 수 있도록 나중에 수정한다 break; } } else if (pPacket->GetPacketType() == SFPACKET_SERVERSHUTDOWN) { for (auto& queue : pDispatcher->m_mapQueue) { BasePacket* pCommand = SFPacketPool::GetInstance()->Alloc(); pCommand->SetSerial(-1); pCommand->SetPacketType(SFPACKET_SERVERSHUTDOWN); #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = queue.second; #else SFLockQueue<BasePacket>* pQueue = queue.second; #endif pQueue->Push(pCommand); } break; } else { ClientInfo* pInfo = pDispatcher->FindClient(pPacket->GetSerial()); if (pInfo != nullptr) { const auto& iter = pDispatcher->m_mapQueue.find(pInfo->channel); if (iter != pDispatcher->m_mapQueue.end()) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = iter->second; #else SFLockQueue<BasePacket>* pQueue = iter->second; #endif pQueue->Push(pPacket); } else { LOG(WARNING) << "Invalid Channel Num : " << pInfo->channel; ReleasePacket(pPacket); } } else { LOG(WARNING) << "ClientInfo NULL : " << pPacket->GetSerial(); } } if (pPacket->GetPacketType() == SFPACKET_DISCONNECT) { pDispatcher->UnregisterClient(pPacket); } } }
/** handle single packet */ tbnet::IPacketHandler::HPRetCode KvRootServer::handlePacket(tbnet::Connection *connection, tbnet::Packet *packet) { tbnet::IPacketHandler::HPRetCode hret = tbnet::IPacketHandler::FREE_CHANNEL; bool bret = NULL != connection && NULL != packet; if (bret) { TBSYS_LOG(DEBUG, "receive pcode : %d", packet->getPCode()); if (!packet->isRegularPacket()) { bret = false; TBSYS_LOG(WARN, "control packet, pcode: %d", dynamic_cast<tbnet::ControlPacket*>(packet)->getCommand()); } if (bret) { BasePacket* bpacket = dynamic_cast<BasePacket*>(packet); bpacket->set_connection(connection); bpacket->setExpireTime(MAX_RESPONSE_TIME); bpacket->set_direction(static_cast<DirectionStatus>(bpacket->get_direction()|DIRECTION_RECEIVE)); if (bpacket->is_enable_dump()) { bpacket->dump(); } int32_t pcode = bpacket->getPCode(); int32_t iret = common::TFS_SUCCESS; if (common::TFS_SUCCESS == iret) { hret = tbnet::IPacketHandler::KEEP_CHANNEL; switch (pcode) { case REQ_KV_RT_MS_KEEPALIVE_MESSAGE: ms_rs_heartbeat_workers_.push(bpacket, 0/* no limit */, false/* no block */); break; default: if (!main_workers_.push(bpacket, work_queue_size_)) { bpacket->reply_error_packet(TBSYS_LOG_LEVEL(ERROR),STATUS_MESSAGE_ERROR, "%s, task message beyond max queue size, discard", get_ip_addr()); bpacket->free(); } break; } } else { bpacket->free(); TBSYS_LOG(WARN, "the msg: %d will be ignored", pcode); } } } return hret; }
void* BasePacketStreamer::decode_handler(easy_message_t *m) { // check if header complete if (m->input->last - m->input->pos < TFS_PACKET_HEADER_V1_SIZE) { TBSYS_LOG(DEBUG, "packet header not complete"); return NULL; } assert(m->pool->tlock <= 1 && m->pool->flags <= 1); // why? // decode packet header, get length and pcode Stream input(m->input); uint32_t flag = 0; int32_t len = 0; int16_t pcode = 0; int16_t version = 0; uint64_t id = 0; uint32_t crc = 0; input.get_int32(reinterpret_cast<int32_t*>(&flag)); input.get_int32(&len); input.get_int16(&pcode); input.get_int16(&version); input.get_int64(reinterpret_cast<int64_t*>(&id)); input.get_int32(reinterpret_cast<int32_t*>(&crc)); if (flag != TFS_PACKET_FLAG_V1 || len < 0 || len > (1<<26) /* 64M */) { TBSYS_LOG(ERROR, "decoding failed: flag=%x, len=%d, pcode=%d", flag, len, pcode); m->status = EASY_ERROR; return NULL; } // only received part of packet data if (m->input->last - m->input->pos < len) { //TBSYS_LOG(DEBUG, "data in buffer not enough: data_len=%d, buf_len=%d, pcode=%d", // len, static_cast<int32_t>(m->input->last - m->input->pos), pcode); m->next_read_len = len - (m->input->last - m->input->pos); m->input->pos -= TFS_PACKET_HEADER_V1_SIZE; return NULL; } TBSYS_LOG(DEBUG, "decode packet, pcode=%d, length=%d", pcode, len); BasePacket* bp = dynamic_cast<BasePacket*>(_factory->createPacket(pcode)); assert(NULL != bp); tbnet::PacketHeader header; header._chid = id; header._pcode = pcode; header._dataLen = len; bp->setPacketHeader(&header); // copy raw data to BasePacket's stream // because some Message hold the pointer bp->stream_.reserve(len); bp->stream_.set_bytes(m->input->pos, len); m->input->pos += len; assert(m->input->pos <= m->input->last); if(TFS_SUCCESS != bp->deserialize(bp->stream_)) { TBSYS_LOG(ERROR, "decoding packet failed, pcode=%d", pcode); tbsys::gDelete(bp); input.clear_last_read_mark(); m->status = EASY_ERROR; return NULL; } // help to detect serialize/deserialize not match problem if (bp->stream_.get_data_length() != 0) { TBSYS_LOG(DEBUG, "some data are useless, pcode=%d, unused_length=%ld", pcode, bp->stream_.get_data_length()); } assert(m->pool->tlock <= 1 && m->pool->flags <= 1); return bp; }
int Khaan :: UpdateOutwardPacketList() { if( m_hasPacketsToSend == false || m_isDisconnected ) return 0; //cout << "Khaan :: UpdateOutwardPacketList:: lock 1" << endl; m_outputChainListMutex.lock(); deque< BasePacket* > localQueue = m_packetsOut; m_packetsOut.clear(); m_outputChainListMutex.unlock(); m_hasPacketsToSend = false; //cout << "Khaan :: UpdateOutwardPacketList:: unlock 1" << endl; if( localQueue.size() == 0 ) return 0; //LogMessage( LOG_PRIO_INFO, "Khaan 11" ); int length; int offset = 0; PacketFactory factory; int totalBytesLeftToWrite = m_maxBytesToSend; U16 sizeOfLastWrite; int sizeOfHeader = sizeof( sizeOfLastWrite ); int sizeSent = 0; while( localQueue.size() ) { offset = 0; length = sizeOfHeader;// reserve space BasePacket* packet = localQueue.front(); packet->SerializeOut( m_outboundBuffer, length, m_versionNumberMinor ); totalBytesLeftToWrite -= length; if( totalBytesLeftToWrite < 0 ) break; sizeSent += length + sizeOfHeader; sizeOfLastWrite = length - sizeOfHeader; Serialize::Out( m_outboundBuffer, offset, sizeOfLastWrite, m_versionNumberMinor );// write in the size SendData( m_outboundBuffer, length ); DumpBuffer( m_outboundBuffer, offset, length ); localQueue.pop_front(); TrackOutwardPacketType( packet ); factory.CleanupPacket( packet ); } if( localQueue.size() ) // remainder { //cout << "Khaan :: UpdateOutwardPacketList:: lock 2" << endl; m_outputChainListMutex.lock(); deque< BasePacket* >::reverse_iterator it = localQueue.rbegin();// reverse order while( it != localQueue.rend() ) { BasePacket* packet = *it++; m_packetsOut.push_front( packet ); } m_hasPacketsToSend = true; m_outputChainListMutex.unlock(); //cout << "Khaan :: UpdateOutwardPacketList:: unlock 2" << endl; } return sizeSent; }
BasePacket* parse(PTP::ByteStream& stream) { uint32_t length = 0, code = 0; BasePacket* res; if(!stream.peek(length)) return NULL; if(stream.length()<length) return NULL; LOG_VERBOSE("Receiving packet: length=%u", length); LOG_DUMP_V(stream.peek(), length); stream.read(length); stream.read(code); switch(code) { case PacketCode::InitCommandRequest: res = new InitCommandRequest; break; case PacketCode::InitCommandAck: res = new InitCommandAck; break; case PacketCode::InitEventRequest: res = new InitEventRequest; break; case PacketCode::InitEventAck: res = new InitEventAck; break; case PacketCode::InitFail: res = new InitFail; break; case PacketCode::OperationRequest: res = new OperationRequest; break; case PacketCode::OperationResponse: res = new OperationResponse; break; case PacketCode::Event: res = new Event; break; case PacketCode::StartData: res = new StartData; break; case PacketCode::Data: res = new Data(length); break; case PacketCode::Cancel: res = new Cancel; break; case PacketCode::EndData: res = new EndData(length); break; case PacketCode::ProbeRequest: res = new ProbeRequest; break; case PacketCode::ProbeResponse: res = new ProbeResponse; break; default: throw RUNTIME_ERROR("Invalid PTP/IP Packet code."); } res->parse(stream); return res; }