//------------------------------------------------------------------------------------- BundleBroadcast::BundleBroadcast(NetworkInterface & networkInterface, uint16 bindPort, uint32 recvWindowSize): Bundle(NULL, Network::PROTOCOL_UDP), epListen_(), networkInterface_(networkInterface), recvWindowSize_(recvWindowSize), good_(false), itry_(5) { epListen_.socket(SOCK_DGRAM); epBroadcast_.socket(SOCK_DGRAM); if (!epListen_.good() || !epBroadcast_.good()) { ERROR_MSG(fmt::format("BundleBroadcast::BundleBroadcast: init socket is error, {}\n", kbe_strerror())); networkInterface_.dispatcher().breakProcessing(); } else { int count = 0; while(true) { if (epListen_.bind(htons(bindPort), htonl(INADDR_ANY)) != 0) { good_ = false; KBEngine::sleep(10); count++; if(count > 30) { WARNING_MSG(fmt::format("BundleBroadcast::BundleBroadcast: Couldn't bind listener socket to port {}, {}\n", bindPort, kbe_strerror())); break; } } else { epListen_.addr(htons(bindPort), htonl(INADDR_ANY)); good_ = true; // DEBUG_MSG(fmt::format("BundleBroadcast::BundleBroadcast: epListen {}\n", epListen_.c_str())); break; } } } pCurrPacket()->data_resize(recvWindowSize_); }
//------------------------------------------------------------------------------------- bool EPoller::doRegister(int fd, bool isRead, bool isRegister) { struct epoll_event ev; memset(&ev, 0, sizeof(ev)); // stop valgrind warning int op; ev.data.fd = fd; // Handle the case where the file is already registered for the opposite // action. if (this->isRegistered(fd, !isRead)) { op = EPOLL_CTL_MOD; ev.events = isRegister ? EPOLLIN|EPOLLOUT : isRead ? EPOLLOUT : EPOLLIN; } else { // TODO: Could be good to use EPOLLET (leave like select for now). ev.events = isRead ? EPOLLIN : EPOLLOUT; op = isRegister ? EPOLL_CTL_ADD : EPOLL_CTL_DEL; } if (epoll_ctl(epfd_, op, fd, &ev) < 0) { const char* MESSAGE = "EPoller::doRegister: Failed to %s %s file " "descriptor %d (%s)\n"; if (errno == EBADF) { WARNING_MSG(boost::format(MESSAGE) % (isRegister ? "add" : "remove") % (isRead ? "read" : "write") % fd % kbe_strerror()); } else { ERROR_MSG(boost::format(MESSAGE) % (isRegister ? "add" : "remove") % (isRead ? "read" : "write") % fd % kbe_strerror()); } return false; } return true; }
//------------------------------------------------------------------------------------- void Components::removeComponentByChannel(Network::Channel * pChannel, bool isShutingdown) { int ifind = 0; while(ALL_COMPONENT_TYPES[ifind] != UNKNOWN_COMPONENT_TYPE) { COMPONENT_TYPE componentType = ALL_COMPONENT_TYPES[ifind++]; COMPONENTS& components = getComponents(componentType); COMPONENTS::iterator iter = components.begin(); for(; iter != components.end();) { if((*iter).pChannel == pChannel) { //SAFE_RELEASE((*iter).pIntAddr); //SAFE_RELEASE((*iter).pExtAddr); // (*iter).pChannel->decRef(); if (!isShutingdown && g_componentType != LOGGER_TYPE) { ERROR_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n", COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror())); #if KBE_PLATFORM == PLATFORM_WIN32 printf("[ERROR]: %s.\n", (fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n", COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror())).c_str()); #endif } else { INFO_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Normal exit!\n", COMPONENT_NAME_EX(componentType), (*iter).cid)); } ComponentInfos* componentInfos = &(*iter); if(_pHandler) _pHandler->onRemoveComponent(componentInfos); iter = components.erase(iter); return; } else iter++; } } // KBE_ASSERT(false && "channel is not found!\n"); }
//------------------------------------------------------------------------------------- int ListenerReceiver::handleInputNotification(int fd) { int tickcount = 0; while(tickcount ++ < 256) { EndPoint* pNewEndPoint = endpoint_.accept(); if(pNewEndPoint == NULL){ if(tickcount == 1) { WARNING_MSG(fmt::format("PacketReceiver::handleInputNotification: accept endpoint({}) {}!\n", fd, kbe_strerror())); this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK); } break; } else { Channel* pchannel = new Channel(networkInterface_, pNewEndPoint, traits_); if(!networkInterface_.registerChannel(pchannel)) { ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification:registerChannel({}) is failed!\n", pchannel->c_str())); } } } return 0; }
//------------------------------------------------------------------------------------- Mercury::Channel* ClientObjectBase::initBaseappChannel() { Mercury::EndPoint* pEndpoint = new Mercury::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObjectBase::initBaseappChannel: couldn't create a socket\n"); delete pEndpoint; return false; } u_int32_t address; pEndpoint->convertAddress(ip_.c_str(), address); if(pEndpoint->connect(htons(port_), address) == -1) { ERROR_MSG(boost::format("ClientObjectBase::initBaseappChannel: connect server is error(%1%)!\n") % kbe_strerror()); delete pEndpoint; return NULL; } Mercury::Address addr(ip_.c_str(), port_); pEndpoint->addr(addr); pServerChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); connectedGateway_ = true; return pServerChannel_; }
//------------------------------------------------------------------------------------- Mercury::Channel* ClientObjectBase::initLoginappChannel(std::string accountName, std::string passwd, std::string ip, KBEngine::uint32 port) { Mercury::EndPoint* pEndpoint = new Mercury::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObjectBase::initLoginappChannel: couldn't create a socket\n"); delete pEndpoint; return NULL; } u_int32_t address; pEndpoint->convertAddress(ip.c_str(), address); if(pEndpoint->connect(htons(port), address) == -1) { ERROR_MSG(boost::format("ClientObjectBase::initLoginappChannel: connect server is error(%1%)!\n") % kbe_strerror()); delete pEndpoint; return NULL; } Mercury::Address addr(ip.c_str(), port); pEndpoint->addr(addr); pServerChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); password_ = passwd; name_ = accountName; return pServerChannel_; }
//------------------------------------------------------------------------------------- Reason NetworkInterface::getSendErrorReason(const EndPoint * endpoint, int retSendSize, int packetTotalSize) { int err; Reason reason; #ifdef unix err = errno; switch (err) { case ECONNREFUSED: reason = REASON_NO_SUCH_PORT; break; case EAGAIN: reason = REASON_RESOURCE_UNAVAILABLE; break; case ENOBUFS: reason = REASON_TRANSMIT_QUEUE_FULL; break; default: reason = REASON_GENERAL_NETWORK; break; } #else err = WSAGetLastError(); if (err == WSAEWOULDBLOCK || err == WSAEINTR) { reason = REASON_RESOURCE_UNAVAILABLE; } else { reason = REASON_GENERAL_NETWORK; } #endif if (retSendSize == -1) { if (reason != REASON_NO_SUCH_PORT) { ERROR_MSG( "NetworkInterface::getSendErrorReason( %s ): " "Could not send packet: %s\n", endpoint->addr().c_str(), kbe_strerror( err ) ); } } else { WARNING_MSG( "NetworkInterface::getSendErrorReason( %s ): " "Packet length %d does not match sent length %d (err = %s)\n", endpoint->addr().c_str(), packetTotalSize, retSendSize, kbe_strerror( err ) ); } return reason; }
//------------------------------------------------------------------------------------- BundleBroadcast::BundleBroadcast(NetworkInterface & networkInterface, uint16 bindPort, uint32 recvWindowSize): Bundle(NULL, Mercury::PROTOCOL_UDP), epListen_(), networkInterface_(networkInterface), recvWindowSize_(recvWindowSize), good_(false), itry_(5) { epListen_.socket(SOCK_DGRAM); epBroadcast_.socket(SOCK_DGRAM); if (!epListen_.good() || !epBroadcast_.good()) { ERROR_MSG("BundleBroadcast::BundleBroadcast: init socket is error, %s\n", kbe_strerror()); networkInterface_.mainDispatcher().breakProcessing(); } else { int count = 0; while(true) { if (epListen_.bind(htons(bindPort), htonl(INADDR_ANY)) != 0) { good_ = false; WARNING_MSG("BundleBroadcast::BundleBroadcast: Couldn't bind listener socket to port %d, %s\n", bindPort, kbe_strerror()); KBEngine::sleep(100); count++; if(count > 3) { break; } } else { epListen_.addr(htons(bindPort), htonl(INADDR_ANY)); good_ = true; DEBUG_MSG("BundleBroadcast::BundleBroadcast: epListen %s\n", epListen_.c_str()); break; } } } }
//------------------------------------------------------------------------------------- int SelectPoller::processPendingEvents(double maxWait) { fd_set readFDs; fd_set writeFDs; struct timeval nextTimeout; FD_ZERO(&readFDs); FD_ZERO(&writeFDs); readFDs = fdReadSet_; writeFDs = fdWriteSet_; nextTimeout.tv_sec = (int)maxWait; nextTimeout.tv_usec = (int)((maxWait - (double)nextTimeout.tv_sec) * 1000000.0); #if ENABLE_WATCHERS g_idleProfile.start(); #else uint64 startTime = timestamp(); #endif KBEConcurrency::onStartMainThreadIdling(); int countReady = 0; #if KBE_PLATFORM == PLATFORM_WIN32 if (fdLargest_ == -1) { Sleep(int(maxWait * 1000.0)); } else #endif { countReady = select(fdLargest_+1, &readFDs, fdWriteCount_ ? &writeFDs : NULL, NULL, &nextTimeout); } KBEConcurrency::onEndMainThreadIdling(); #if ENABLE_WATCHERS g_idleProfile.stop(); spareTime_ += g_idleProfile.lastTime_; #else spareTime_ += timestamp() - startTime; #endif if (countReady > 0) { this->handleNotifications(countReady, readFDs, writeFDs); } else if (countReady == -1) { WARNING_MSG(fmt::format("EventDispatcher::processContinuously: " "error in select(): {}\n", kbe_strerror())); } return countReady; }
//------------------------------------------------------------------------------------- bool Machine::findBroadcastInterface() { std::map<u_int32_t, std::string> interfaces; Mercury::BundleBroadcast bhandler(networkInterface_, KBE_PORT_BROADCAST_DISCOVERY); if (!bhandler.epListen().getInterfaces(interfaces)) { ERROR_MSG("Machine::findBroadcastInterface: Failed to discover network interfaces\n"); return false; } uint8 data = 1; bhandler << data; if (!bhandler.broadcast(KBE_PORT_BROADCAST_DISCOVERY)) { ERROR_MSG(boost::format("Machine::findBroadcastInterface:Failed to send broadcast discovery message. error:%1%\n") % kbe_strerror()); return false; } sockaddr_in sin; if(bhandler.receive(NULL, &sin)) { INFO_MSG(boost::format("Machine::findBroadcastInterface:Machine::findBroadcastInterface: Broadcast discovery receipt from %1%.\n") % inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) ); std::map< u_int32_t, std::string >::iterator iter; iter = interfaces.find( (u_int32_t &)sin.sin_addr.s_addr ); if (iter != interfaces.end()) { INFO_MSG(boost::format("Machine::findBroadcastInterface: Confirmed %1% (%2%) as default broadcast route interface.\n") % inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) % iter->second.c_str()); broadcastAddr_ = sin.sin_addr.s_addr; return true; } } std::string sinterface = "\t["; std::map< u_int32_t, std::string >::iterator iter = interfaces.begin(); for(; iter != interfaces.end(); iter++) { sinterface += inet_ntoa((struct in_addr&)iter->first); sinterface += ", "; } sinterface += "]"; ERROR_MSG(boost::format("Machine::findBroadcastInterface: Broadcast discovery [%1%] " "not a valid interface. available interfaces:%2%\n") % inet_ntoa((struct in_addr&)sin.sin_addr.s_addr) % sinterface.c_str()); return false; }
//------------------------------------------------------------------------------------- bool ClientObject::initCreate() { Network::EndPoint* pEndpoint = new Network::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n"); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots(); u_int32_t address; pEndpoint->convertAddress(infos.login_ip, address); if(pEndpoint->connect(htons(infos.login_port), address) == -1) { ERROR_MSG(fmt::format("ClientObject::initNetwork({1}): connect server({2}:{3}) is error({0})!\n", kbe_strerror(), name_, infos.login_ip, infos.login_port)); delete pEndpoint; // error_ = C_ERROR_INIT_NETWORK_FAILED; state_ = C_STATE_INIT; return false; } Network::Address addr(infos.login_ip, infos.login_port); pEndpoint->addr(addr); pServerChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); pServerChannel_->pMsgHandlers(&ClientInterface::messageHandlers); Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this); Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(LoginappInterface::hello); (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pushBundle(pBundle); this->pEndpoint_ = pEndpoint; return true; }
//------------------------------------------------------------------------------------- EPoller::EPoller(int expectedSize) : epfd_(epoll_create(expectedSize)) { if (epfd_ == -1) { ERROR_MSG(boost::format("EPoller::EPoller: epoll_create failed: %1%\n") % kbe_strerror()); } };
//------------------------------------------------------------------------------------- bool ClientObject::initLoginGateWay() { Bots::getSingleton().pEventPoller()->deregisterForRead(*pServerChannel_->endpoint()); Network::EndPoint* pEndpoint = new Network::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n"); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } u_int32_t address; pEndpoint->convertAddress(ip_.c_str(), address); if(pEndpoint->connect(htons(port_), address) == -1) { ERROR_MSG(fmt::format("ClientObject::initLogin({}): connect server is error({})!\n", kbe_strerror(), name_)); delete pEndpoint; // error_ = C_ERROR_INIT_NETWORK_FAILED; state_ = C_STATE_LOGIN_GATEWAY_CREATE; return false; } Network::Address addr(ip_.c_str(), port_); pEndpoint->addr(addr); pServerChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this); connectedGateway_ = true; Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pushBundle(pBundle); return true; }
//------------------------------------------------------------------------------------- EpollPoller::EpollPoller(int expectedSize) : epfd_(epoll_create(expectedSize)) { if (epfd_ == -1) { ERROR_MSG(fmt::format("EpollPoller::EpollPoller: epoll_create failed: {}\n", kbe_strerror())); } };
//------------------------------------------------------------------------------------- HTTPCBHandler::HTTPCBHandler(): pEndPoint_(NULL), clients_() { pEndPoint_ = new Network::EndPoint(); pEndPoint_->socket(SOCK_STREAM); if (!pEndPoint_->good()) { ERROR_MSG("HTTPCBHandler::process: couldn't create a socket\n"); return; } if (pEndPoint_->bind(htons(g_kbeSrvConfig.getLoginApp().http_cbport), Loginapp::getSingleton().networkInterface().extaddr().ip) == -1) { ERROR_MSG(fmt::format("HTTPCBHandler::bind({}): {}:{}\n", kbe_strerror(), inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip), g_kbeSrvConfig.getLoginApp().http_cbport)); pEndPoint_->close(); return; } if(pEndPoint_->listen() == -1) { ERROR_MSG(fmt::format("HTTPCBHandler::listeningSocket({}): {}:{}\n", kbe_strerror(), inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip), g_kbeSrvConfig.getLoginApp().http_cbport)); pEndPoint_->close(); return; } pEndPoint_->setnonblocking(true); Loginapp::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor(*pEndPoint_, this); INFO_MSG(fmt::format("HTTPCBHandler::bind: {}:{}\n", inet_ntoa((struct in_addr&)Loginapp::getSingleton().networkInterface().extaddr().ip), g_kbeSrvConfig.getLoginApp().http_cbport)); }
//------------------------------------------------------------------------------------- int TelnetServer::handleInputNotification(int fd) { KBE_ASSERT(listener_ == fd); int tickcount = 0; while(tickcount ++ < 1024) { Mercury::EndPoint* pNewEndPoint = listener_.accept(); if(pNewEndPoint == NULL){ if(tickcount == 1) { WARNING_MSG(fmt::format("TelnetServer::handleInputNotification: accept endpoint({}) {}!\n", fd, kbe_strerror())); } break; } else { TelnetHandler* pTelnetHandler = new TelnetHandler(pNewEndPoint, this, pNetworkInterface_, passwd_.size() > 0 ? TelnetHandler::TELNET_STATE_PASSWD : (TelnetHandler::TELNET_STATE)this->deflayer()); if(!pDispatcher_->registerFileDescriptor((*pNewEndPoint), pTelnetHandler)) { ERROR_MSG(fmt::format("TelnetServer::start:: registerFileDescriptor(pTelnetHandler) is failed! addr={}\n", pNewEndPoint->c_str())); delete pTelnetHandler; continue; } INFO_MSG(fmt::format("TelnetServer::handleInputNotification: new handler({})!\n", pNewEndPoint->c_str())); handlers_[(*pNewEndPoint)].reset(pTelnetHandler); std::string s; if(passwd_.size() > 0) { s = "password:"; } else { s = pTelnetHandler->getWelcome(); } pNewEndPoint->send(s.c_str(), s.size()); } } return 0; }
//------------------------------------------------------------------------------------- int ListenerReceiver::handleInputNotification(int fd) { int tickcount = 0; while(tickcount ++ < 256) { EndPoint* pNewEndPoint = endpoint_.accept(); if(pNewEndPoint == NULL){ if(tickcount == 1) { WARNING_MSG(fmt::format("PacketReceiver::handleInputNotification: accept endpoint({}) {}!\n", fd, kbe_strerror())); this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK); } break; } else { Channel* pChannel = Network::Channel::createPoolObject(); bool ret = pChannel->initialize(networkInterface_, pNewEndPoint, traits_); if(!ret) { ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification: initialize({}) is failed!\n", pChannel->c_str())); pChannel->destroy(); Network::Channel::reclaimPoolObject(pChannel); return 0; } if(!networkInterface_.registerChannel(pChannel)) { ERROR_MSG(fmt::format("ListenerReceiver::handleInputNotification: registerChannel({}) is failed!\n", pChannel->c_str())); pChannel->destroy(); Network::Channel::reclaimPoolObject(pChannel); } } } return 0; }
//------------------------------------------------------------------------------------- bool BundleBroadcast::broadcast(uint16 port) { if (!epBroadcast_.good()) return false; if(port == 0) port = KBE_MACHINE_BRAODCAST_SEND_PORT; epBroadcast_.addr(port, Mercury::BROADCAST); if(epBroadcast_.setbroadcast(true) != 0) { ERROR_MSG("BundleBroadcast::broadcast: Couldn't broadcast socket, port %d, %s\n", port, kbe_strerror()); networkInterface_.mainDispatcher().breakProcessing(); return false; } this->sendto(epBroadcast_, htons(port), Mercury::BROADCAST); return true; }
//------------------------------------------------------------------------------------- bool ClientObject::initLoginGateWay() { Bots::getSingleton().pEventPoller()->deregisterForRead(*pChannel_->endpoint()); Mercury::EndPoint* pEndpoint = new Mercury::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n"); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } u_int32_t address; pEndpoint->convertAddress(ip_.c_str(), address); if(pEndpoint->connect(htons(port_), address) == -1) { ERROR_MSG(boost::format("ClientObject::initLogin: connect server is error(%1%)!\n") % kbe_strerror()); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } Mercury::Address addr(ip_.c_str(), port_); pEndpoint->addr(addr); pChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this); connectedGateway_ = true; return true; }
//------------------------------------------------------------------------------------- bool ClientObject::initCreate() { Mercury::EndPoint* pEndpoint = new Mercury::EndPoint(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n"); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots(); u_int32_t address; pEndpoint->convertAddress(infos.login_ip, address); if(pEndpoint->connect(htons(infos.login_port), address) == -1) { ERROR_MSG(boost::format("ClientObject::initNetwork: connect server is error(%1%)!\n") % kbe_strerror()); delete pEndpoint; error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } Mercury::Address addr(infos.login_ip, infos.login_port); pEndpoint->addr(addr); pChannel_->endpoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); pChannel_->pMsgHandlers(&ClientInterface::messageHandlers); Bots::getSingleton().pEventPoller()->registerForRead((*pEndpoint), this); return true; }
//------------------------------------------------------------------------------------- bool TPThread::onWaitCondSignal(void) { #if KBE_PLATFORM == PLATFORM_WIN32 if(threadWaitSecond_ <= 0) { state_ = THREAD_STATE_SLEEP; WaitForSingleObject(cond_, INFINITE); ResetEvent(cond_); } else { state_ = THREAD_STATE_SLEEP; DWORD ret = WaitForSingleObject(cond_, threadWaitSecond_ * 1000); ResetEvent(cond_); // 如果是因为超时了, 说明这个线程很久没有被用到, 我们应该注销这个线程。 // 通知ThreadPool注销自己 if (ret == WAIT_TIMEOUT) { threadPool_->removeHangThread(this); return false; } else if(ret != WAIT_OBJECT_0) { ERROR_MSG(fmt::format("TPThread::onWaitCondSignal: WaitForSingleObject is error, ret={0}\n", ret)); } } #else if(threadWaitSecond_ <= 0) { lock(); state_ = THREAD_STATE_SLEEP; pthread_cond_wait(&cond_, &mutex_); unlock(); } else { struct timeval now; struct timespec timeout; gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + threadWaitSecond_; timeout.tv_nsec = now.tv_usec * 1000; lock(); state_ = THREAD_STATE_SLEEP; int ret = pthread_cond_timedwait(&cond_, &mutex_, &timeout); unlock(); // 如果是因为超时了, 说明这个线程很久没有被用到, 我们应该注销这个线程。 if (ret == ETIMEDOUT) { // 通知ThreadPool注销自己 threadPool_->removeHangThread(this); return false; } else if(ret != 0) { ERROR_MSG(fmt::format("TPThread::onWaitCondSignal: pthread_cond_timedwait is error, {0}\n", kbe_strerror())); } } #endif return true; }
//------------------------------------------------------------------------------------- bool ThreadPool::addTask(TPTask* tptask) { THREAD_MUTEX_LOCK(threadStateList_mutex_); if(currentFreeThreadCount_ > 0) { std::list<TPThread*>::iterator itr = freeThreadList_.begin(); TPThread* tptd = (TPThread*)(*itr); freeThreadList_.erase(itr); busyThreadList_.push_back(tptd); --currentFreeThreadCount_; //INFO_MSG("ThreadPool::currFree:%d, currThreadCount:%d, busy:[%d]\n", // currentFreeThreadCount_, currentThreadCount_, busyThreadList_count_); tptd->task(tptask); // 给线程设置新任务 #if KBE_PLATFORM == PLATFORM_WIN32 if(tptd->sendCondSignal()== 0) { #else if(tptd->sendCondSignal()!= 0) { #endif ERROR_MSG("ThreadPool::addTask: pthread_cond_signal is error!\n"); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return false; } THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return true; } bufferTask(tptask); if(isThreadCountMax()) { THREAD_MUTEX_UNLOCK(threadStateList_mutex_); //WARNING_MSG(fmt::format("ThreadPool::addTask: can't createthread, the poolsize is full({}).\n, // maxThreadCount_)); return false; } for(uint32 i=0; i<extraNewAddThreadCount_; i++) { TPThread* tptd = createThread(300); // 设定5分钟未使用则退出的线程 if(!tptd) { #if KBE_PLATFORM == PLATFORM_WIN32 ERROR_MSG("ThreadPool::addTask: the ThreadPool create thread is error! ... \n"); #else ERROR_MSG(fmt::format("ThreadPool::addTask: the ThreadPool create thread is error:{0}\n", kbe_strerror())); #endif } allThreadList_.push_back(tptd); // 所有的线程列表 freeThreadList_.push_back(tptd); // 闲置的线程列表 ++currentThreadCount_; ++currentFreeThreadCount_; } INFO_MSG(fmt::format("ThreadPool::addTask: new Thread, currThreadCount: {0}\n", currentThreadCount_)); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return true; } //------------------------------------------------------------------------------------- bool ThreadPool::hasThread(TPThread* pTPThread) { bool ret = true; THREAD_MUTEX_LOCK(threadStateList_mutex_); std::list<TPThread*>::iterator itr1 = find(allThreadList_.begin(), allThreadList_.end(), pTPThread); if(itr1 == allThreadList_.end()) ret = false; THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return ret; }
//------------------------------------------------------------------------------------- int Components::connectComponent(COMPONENT_TYPE componentType, int32 uid, COMPONENT_ID componentID, bool printlog) { Components::ComponentInfos* pComponentInfos = findComponent(componentType, uid, componentID); if (pComponentInfos == NULL) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: not found componentType={}, uid={}, componentID={}!\n", COMPONENT_NAME_EX(componentType), uid, componentID)); } return -1; } Network::EndPoint * pEndpoint = Network::EndPoint::createPoolObject(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { if (printlog) { ERROR_MSG("Components::connectComponent: couldn't create a socket\n"); } Network::EndPoint::reclaimPoolObject(pEndpoint); return -1; } pEndpoint->addr(*pComponentInfos->pIntAddr); int ret = pEndpoint->connect(pComponentInfos->pIntAddr->port, pComponentInfos->pIntAddr->ip); if(ret == 0) { Network::Channel* pChannel = Network::Channel::createPoolObject(); bool ret = pChannel->initialize(*_pNetworkInterface, pEndpoint, Network::Channel::INTERNAL); if(!ret) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: initialize({}) is failed!\n", pChannel->c_str())); } pChannel->destroy(); Network::Channel::reclaimPoolObject(pChannel); return -1; } pComponentInfos->pChannel = pChannel; pComponentInfos->pChannel->componentID(componentID); if(!_pNetworkInterface->registerChannel(pComponentInfos->pChannel)) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: registerChannel({}) is failed!\n", pComponentInfos->pChannel->c_str())); } pComponentInfos->pChannel->destroy(); Network::Channel::reclaimPoolObject(pComponentInfos->pChannel); // 此时不可强制释放内存,destroy中已经对其减引用 // SAFE_RELEASE(pComponentInfos->pChannel); pComponentInfos->pChannel = NULL; return -1; } else { Network::Bundle* pBundle = Network::Bundle::createPoolObject(); if(componentType == BASEAPPMGR_TYPE) { (*pBundle).newMessage(BaseappmgrInterface::onRegisterNewApp); BaseappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == CELLAPPMGR_TYPE) { (*pBundle).newMessage(CellappmgrInterface::onRegisterNewApp); CellappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == CELLAPP_TYPE) { (*pBundle).newMessage(CellappInterface::onRegisterNewApp); CellappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == BASEAPP_TYPE) { (*pBundle).newMessage(BaseappInterface::onRegisterNewApp); BaseappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == DBMGR_TYPE) { (*pBundle).newMessage(DbmgrInterface::onRegisterNewApp); DbmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == LOGGER_TYPE) { (*pBundle).newMessage(LoggerInterface::onRegisterNewApp); LoggerInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else { KBE_ASSERT(false && "invalid componentType.\n"); } pComponentInfos->pChannel->send(pBundle); } } else { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: connect({}) is failed! {}.\n", pComponentInfos->pIntAddr->c_str(), kbe_strerror())); } Network::EndPoint::reclaimPoolObject(pEndpoint); return -1; } return ret; }
//------------------------------------------------------------------------------------- bool ClientObject::initLoginGateWay() { Bots::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*pTCPPacketReceiverEx_->pEndPoint()); pServerChannel_->stopSend(); pServerChannel_->pPacketSender(NULL); SAFE_RELEASE(pTCPPacketSenderEx_); SAFE_RELEASE(pTCPPacketReceiverEx_); Network::EndPoint* pEndpoint = Network::EndPoint::ObjPool().createObject(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initLogin: couldn't create a socket\n"); Network::EndPoint::ObjPool().reclaimObject(pEndpoint); error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } u_int32_t address; Network::Address::string2ip(ip_.c_str(), address); if(pEndpoint->connect(htons(port_), address) == -1) { ERROR_MSG(fmt::format("ClientObject::initLogin({}): connect server is error({})!\n", kbe_strerror(), name_)); Network::EndPoint::ObjPool().reclaimObject(pEndpoint); // error_ = C_ERROR_INIT_NETWORK_FAILED; state_ = C_STATE_LOGIN_GATEWAY_CREATE; return false; } Network::Address addr(ip_.c_str(), port_); pEndpoint->addr(addr); pServerChannel_->pEndPoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); pTCPPacketSenderEx_ = new Network::TCPPacketSenderEx(*pEndpoint, this->networkInterface_, this); pTCPPacketReceiverEx_ = new Network::TCPPacketReceiverEx(*pEndpoint, this->networkInterface_, this); Bots::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor((*pEndpoint), pTCPPacketReceiverEx_); //²»ÔÚÕâÀï×¢²á //Bots::getSingleton().networkInterface().dispatcher().registerWriteFileDescriptor((*pEndpoint), pTCPPacketSenderEx_); pServerChannel_->pPacketSender(pTCPPacketSenderEx_); connectedGateway_ = true; Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pEndpoint->send(pBundle); Network::Bundle::ObjPool().reclaimObject(pBundle); return true; }
//------------------------------------------------------------------------------------- bool ClientObject::initCreate() { Network::EndPoint* pEndpoint = Network::EndPoint::ObjPool().createObject(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("ClientObject::initNetwork: couldn't create a socket\n"); Network::EndPoint::ObjPool().reclaimObject(pEndpoint); error_ = C_ERROR_INIT_NETWORK_FAILED; return false; } ENGINE_COMPONENT_INFO& infos = g_kbeSrvConfig.getBots(); u_int32_t address; Network::Address::string2ip(infos.login_ip, address); if(pEndpoint->connect(htons(infos.login_port), address) == -1) { ERROR_MSG(fmt::format("ClientObject::initNetwork({1}): connect server({2}:{3}) is error({0})!\n", kbe_strerror(), name_, infos.login_ip, infos.login_port)); Network::EndPoint::ObjPool().reclaimObject(pEndpoint); // error_ = C_ERROR_INIT_NETWORK_FAILED; state_ = C_STATE_INIT; return false; } Network::Address addr(infos.login_ip, infos.login_port); pEndpoint->addr(addr); pServerChannel_->pEndPoint(pEndpoint); pEndpoint->setnonblocking(true); pEndpoint->setnodelay(true); pServerChannel_->pMsgHandlers(&ClientInterface::messageHandlers); pTCPPacketSenderEx_ = new Network::TCPPacketSenderEx(*pEndpoint, this->networkInterface_, this); pTCPPacketReceiverEx_ = new Network::TCPPacketReceiverEx(*pEndpoint, this->networkInterface_, this); Bots::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor((*pEndpoint), pTCPPacketReceiverEx_); //²»ÔÚÕâÀï×¢²á //Bots::getSingleton().networkInterface().dispatcher().registerWriteFileDescriptor((*pEndpoint), pTCPPacketSenderEx_); pServerChannel_->pPacketSender(pTCPPacketSenderEx_); Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(LoginappInterface::hello); (*pBundle) << KBEVersion::versionString() << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); } else { std::string key = ""; (*pBundle).appendBlob(key); } pEndpoint->send(pBundle); Network::Bundle::ObjPool().reclaimObject(pBundle); return true; }
//------------------------------------------------------------------------------------- bool ThreadPool::_addTask(TPTask* tptask) { std::list<TPThread*>::iterator itr = freeThreadList_.begin(); TPThread* tptd = (TPThread*)(*itr); freeThreadList_.erase(itr); busyThreadList_.push_back(tptd); --currentFreeThreadCount_; //INFO_MSG("ThreadPool::currFree:%d, currThreadCount:%d, busy:[%d]\n", // currentFreeThreadCount_, currentThreadCount_, busyThreadList_count_); tptd->task(tptask); #if KBE_PLATFORM == PLATFORM_WIN32 if (tptd->sendCondSignal() == 0) { #else if (tptd->sendCondSignal() != 0) { #endif ERROR_MSG("ThreadPool::addTask: pthread_cond_signal error!\n"); return false; } return true; } //------------------------------------------------------------------------------------- bool ThreadPool::addTask(TPTask* tptask) { THREAD_MUTEX_LOCK(threadStateList_mutex_); if(currentFreeThreadCount_ > 0) { bool ret = _addTask(tptask); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return ret; } bufferTask(tptask); if(isThreadCountMax()) { THREAD_MUTEX_UNLOCK(threadStateList_mutex_); //WARNING_MSG(fmt::format("ThreadPool::addTask: can't createthread, the poolsize is full({}).\n, // maxThreadCount_)); return false; } for(uint32 i=0; i<extraNewAddThreadCount_; ++i) { bool threadStartsImmediately = i > 0; // 设定5分钟未使用则退出的线程 TPThread* tptd = createThread(ThreadPool::timeout, threadStartsImmediately); if(!tptd) { #if KBE_PLATFORM == PLATFORM_WIN32 ERROR_MSG("ThreadPool::addTask: the ThreadPool create thread error! ... \n"); #else ERROR_MSG(fmt::format("ThreadPool::addTask: the ThreadPool create thread error:{0}\n", kbe_strerror())); #endif } // 所有的线程列表 allThreadList_.push_back(tptd); if (threadStartsImmediately) { // 闲置的线程列表 freeThreadList_.push_back(tptd); ++currentFreeThreadCount_; } else { TPTask * pTask = tptd->tryGetTask(); if (pTask) { busyThreadList_.push_back(tptd); tptd->task(pTask); } else { freeThreadList_.push_back(tptd); ++currentFreeThreadCount_; } tptd->createThread(); } ++currentThreadCount_; } INFO_MSG(fmt::format("ThreadPool::addTask: new Thread, currThreadCount: {0}\n", currentThreadCount_)); THREAD_MUTEX_UNLOCK(threadStateList_mutex_); return true; }
//------------------------------------------------------------------------------------- bool UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket) { if (len == 0) { WARNING_MSG( "PacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK (1)- %s\n", strerror( errno ) ); this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK ); return true; } #ifdef _WIN32 DWORD wsaErr = WSAGetLastError(); #endif //def _WIN32 if ( #ifdef _WIN32 wsaErr == WSAEWOULDBLOCK && !expectingPacket #else errno == EAGAIN && !expectingPacket #endif ) { return false; } #ifdef unix if (errno == EAGAIN || errno == ECONNREFUSED || errno == EHOSTUNREACH) { #if defined(PLAYSTATION3) this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT); return true; #else Mercury::Address offender; if (pEndpoint_->getClosedPort(offender)) { // If we got a NO_SUCH_PORT error and there is an internal // channel to this address, mark it as remote failed. The logic // for dropping external channels that get NO_SUCH_PORT // exceptions is built into BaseApp::onClientNoSuchPort(). if (errno == ECONNREFUSED) { // н╢й╣ож } this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT, offender); return true; } else { WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "getClosedPort() failed\n"); } #endif } #else if (wsaErr == WSAECONNRESET) { return true; } #endif // unix #ifdef _WIN32 WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - %d\n", wsaErr); #else WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - %s\n", kbe_strerror()); #endif this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK); return true; }
PacketReceiver::RecvState UDPPacketReceiver::checkSocketErrors(int len, bool expectingPacket) { if (len == 0) { /*SL_ELOG(fmt::format("PacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK (1)- {}\n", strerror( errno )));*/ /*this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK );*/ return RECV_STATE_CONTINUE; } #ifdef _WIN32 DWORD wsaErr = WSAGetLastError(); #endif //def _WIN32 if ( #ifdef _WIN32 wsaErr == WSAEWOULDBLOCK && !expectingPacket #else errno == EAGAIN && !expectingPacket #endif ) { return RECV_STATE_BREAK; } #ifdef unix if (errno == EAGAIN || errno == ECONNREFUSED || errno == EHOSTUNREACH) { Network::Address offender; if (pEndpoint_->getClosedPort(offender)) { // If we got a NO_SUCH_PORT error and there is an internal // channel to this address, mark it as remote failed. The logic // for dropping external channels that get NO_SUCH_PORT // exceptions is built into BaseApp::onClientNoSuchPort(). if (errno == ECONNREFUSED) { // 未实现 } this->dispatcher().errorReporter().reportException( REASON_NO_SUCH_PORT, offender); return RECV_STATE_CONTINUE; } else { WARNING_MSG("UDPPacketReceiver::processPendingEvents: " "getClosedPort() failed\n"); } } #else if (wsaErr == WSAECONNRESET) { return RECV_STATE_CONTINUE; } #endif // unix #ifdef _WIN32 /*WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - {}\n", wsaErr));*/ #else WARNING_MSG(fmt::format("UDPPacketReceiver::processPendingEvents: " "Throwing REASON_GENERAL_NETWORK - {}\n", kbe_strerror())); #endif /*this->dispatcher().errorReporter().reportException( REASON_GENERAL_NETWORK);*/ return RECV_STATE_CONTINUE; }
//------------------------------------------------------------------------------------- int HTTPCBHandler::handleInputNotification(int fd) { if(fd == *pEndPoint_) { u_int16_t port; u_int32_t addr; Network::EndPoint* newclient = pEndPoint_->accept(&port, &addr); if(newclient == NULL) { ERROR_MSG(fmt::format("HTTPCBHandler::handleInputNotification: accept is error:{}.\n", kbe_strerror())); return 0; } INFO_MSG(fmt::format("HTTPCBHandler:handleInputNotification: newclient = {}\n", newclient->c_str())); newclient->setnonblocking(true); CLIENT& client = clients_[*newclient]; client.endpoint = KBEShared_ptr< Network::EndPoint >(newclient); client.state = 0; Loginapp::getSingleton().networkInterface().dispatcher().registerReadFileDescriptor(*newclient, this); } else { std::map< int, CLIENT >::iterator iter = clients_.find(fd); if(iter == clients_.end()) { ERROR_MSG(fmt::format("HTTPCBHandler:handleInputNotification: fd({}) not found!\n", fd)); return 0; } CLIENT& client = iter->second; Network::EndPoint* newclient = iter->second.endpoint.get(); char buffer[1024]; int len = newclient->recv(&buffer, 1024); if(len <= 0) { ERROR_MSG(fmt::format("HTTPCBHandler:handleInputNotification: recv error, newclient = {}, recv={}.\n", newclient->c_str(), len)); if(len == 0) { Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient); clients_.erase(iter); } return 0; } if(client.state == 1) { Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient); clients_.erase(iter); } int type = 0; std::string s = buffer; std::string keys = "<policy-file-request/>"; std::string::size_type fi0 = s.find(keys); if(fi0 != std::string::npos) { if(client.state != 1) { std::string response = "<?xml version='1.0'?><cross-domain-policy><allow-access-from domain=""*"" to-ports=""*"" /></cross-domain-policy>"; iter->second.endpoint->send(response.c_str(), response.size()); Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient); clients_.erase(iter); } return 0; } keys = "accountactivate_"; std::string::size_type fi1 = s.find(keys); if(fi1 == std::string::npos) { keys = "resetpassword_"; fi1 = s.find(keys); if(fi1 == std::string::npos) { keys = "bindmail_"; fi1 = s.find(keys); if(fi1 != std::string::npos) { type = 3; } } else { type = 2; } } else { type = 1; } std::string::size_type fi2 = s.find("?"); std::string::size_type fi3 = s.find(" HTTP/"); if(fi2 == std::string::npos || fi2 > fi3) fi2 = fi3; if(fi2 <= fi1) { return 0; } std::string code; if(fi1 != std::string::npos && fi2 != std::string::npos) { int ilen = keys.size(); code.assign(s.c_str() + fi1 + ilen, fi2 - (fi1 + ilen)); } client.state = 1; code = KBEngine::strutil::kbe_trim(code); if(code.size() > 0) { INFO_MSG(fmt::format("HTTPCBHandler:handleInputNotification: code = {}\n", code.c_str())); client.code = code; Components::COMPONENTS& cts = Components::getSingleton().getComponents(DBMGR_TYPE); Components::ComponentInfos* dbmgrinfos = NULL; if(cts.size() > 0) dbmgrinfos = &(*cts.begin()); if(dbmgrinfos == NULL || dbmgrinfos->pChannel == NULL || dbmgrinfos->cid == 0) { return 0; } std::string hellomessage; if(type == 1) { // Ïòdbmgr¼¤»îÕ˺ŠNetwork::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(DbmgrInterface::accountActivate); (*pBundle) << code; dbmgrinfos->pChannel->send(pBundle); hellomessage = g_kbeSrvConfig.emailAtivationInfo_.backlink_hello_message; } else if(type == 2) { std::string::size_type fi1 = s.find("password="******"&", fi1); std::string password; if(fi1 != std::string::npos && fi2 != std::string::npos) { client.state = 2; if(fi1 < fi2) { int ilen = strlen("password="******"username="******"&", fi1); std::string username; if(fi1 != std::string::npos && fi2 != std::string::npos) { if(fi1 < fi2) { int ilen = strlen("username="******"username="******" HTTP/"); if(fi1 != std::string::npos && fi2 != std::string::npos) { if(fi1 < fi2) { int ilen = strlen("username="******"${backlink}", fmt::format("http://{}:{}/{}{}", Loginapp::getSingleton().networkInterface().extaddr().ipAsString(), g_kbeSrvConfig.getLoginApp().http_cbport, keys, code)); KBEngine::strutil::kbe_replace(hellomessage, "${code}", code); std::string response = fmt::format("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: {}\r\n\r\n{}", hellomessage.size(), hellomessage); newclient->send(response.c_str(), response.size()); } client.state = 2; } else { if(client.state != 2) { Loginapp::getSingleton().networkInterface().dispatcher().deregisterReadFileDescriptor(*newclient); clients_.erase(iter); } } } return 0; }
//------------------------------------------------------------------------------------- int Components::connectComponent(COMPONENT_TYPE componentType, int32 uid, COMPONENT_ID componentID) { Components::ComponentInfos* pComponentInfos = findComponent(componentType, uid, componentID); KBE_ASSERT(pComponentInfos != NULL); Mercury::EndPoint * pEndpoint = new Mercury::EndPoint; pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { ERROR_MSG("Components::connectComponent: couldn't create a socket\n"); delete pEndpoint; return -1; } pEndpoint->addr(*pComponentInfos->pIntAddr); int ret = pEndpoint->connect(pComponentInfos->pIntAddr->port, pComponentInfos->pIntAddr->ip); if(ret == 0) { pComponentInfos->pChannel = new Mercury::Channel(*_pNetworkInterface, pEndpoint, Mercury::Channel::INTERNAL); if(!_pNetworkInterface->registerChannel(pComponentInfos->pChannel)) { ERROR_MSG("Components::connectComponent: registerChannel(%s) is failed!\n", pComponentInfos->pChannel->c_str()); delete pComponentInfos->pChannel; pComponentInfos->pChannel = NULL; return -1; } else { Mercury::Bundle bundle(pComponentInfos->pChannel); if(componentType == BASEAPPMGR_TYPE) { bundle.newMessage(BaseappmgrInterface::onRegisterNewApp); BaseappmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == CELLAPPMGR_TYPE) { bundle.newMessage(CellappmgrInterface::onRegisterNewApp); CellappmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == CELLAPP_TYPE) { bundle.newMessage(CellappInterface::onRegisterNewApp); CellappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == BASEAPP_TYPE) { bundle.newMessage(BaseappInterface::onRegisterNewApp); BaseappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == DBMGR_TYPE) { bundle.newMessage(DbmgrInterface::onRegisterNewApp); DbmgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == MESSAGELOG_TYPE) { bundle.newMessage(MessagelogInterface::onRegisterNewApp); MessagelogInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else if(componentType == RESOURCEMGR_TYPE) { bundle.newMessage(ResourcemgrInterface::onRegisterNewApp); ResourcemgrInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), Componentbridge::getSingleton().componentType(), Componentbridge::getSingleton().componentID(), _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port); } else { KBE_ASSERT(false && "invalid componentType.\n"); } bundle.send(*_pNetworkInterface, pComponentInfos->pChannel); } } else { ERROR_MSG("Components::connectComponent: connect(%s) is failed! %s.\n", pComponentInfos->pIntAddr->c_str(), kbe_strerror()); return -1; } return ret; }