//------------------------------------------------------------------------------------- bool ClientObject::processSocket(bool expectingPacket) { Mercury::TCPPacket* pReceiveWindow = Mercury::TCPPacket::ObjPool().createObject(); int len = pReceiveWindow->recvFromEndPoint(*pChannel_->endpoint()); if (len < 0) { Mercury::TCPPacket::ObjPool().reclaimObject(pReceiveWindow); PacketReceiver::RecvState rstate = this->checkSocketErrors(len, expectingPacket); if(rstate == Mercury::PacketReceiver::RECV_STATE_INTERRUPT) { Bots::getSingleton().pEventPoller()->deregisterForRead(*pChannel_->endpoint()); pChannel_->destroy(); Bots::getSingleton().delClient(this); return false; } return rstate == Mercury::PacketReceiver::RECV_STATE_CONTINUE; } else if(len == 0) // 客户端正常退出 { Mercury::TCPPacket::ObjPool().reclaimObject(pReceiveWindow); Bots::getSingleton().pEventPoller()->deregisterForRead(*pChannel_->endpoint()); pChannel_->destroy(); Bots::getSingleton().delClient(this); return false; } pChannel_->addReceiveWindow(pReceiveWindow); Mercury::Reason ret = this->processPacket(pChannel_, pReceiveWindow); if(ret != Mercury::REASON_SUCCESS) { ERROR_MSG(boost::format("ClientObject::processSocket: " "Throwing %1%\n") % Mercury::reasonToString(ret)); } return true; }
//------------------------------------------------------------------------------------- bool Components::checkComponentUsable(const Components::ComponentInfos* info) { Mercury::EndPoint epListen; epListen.socket(SOCK_STREAM); if (!epListen.good()) { ERROR_MSG("Components::checkComponentUsable: couldn't create a socket\n"); return true; } int trycount = 0; while(true) { if(epListen.connect(info->pIntAddr->port, info->pIntAddr->ip) == -1) { KBEngine::sleep(30); trycount++; if(trycount > 3) { ERROR_MSG("Components::checkComponentUsable: couldn't connect to:%s\n", info->pIntAddr->c_str()); return false; } } break; } Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); COMMON_MERCURY_MESSAGE(info->componentType, (*pBundle), lookApp); epListen.send(pBundle->pCurrPacket()->data(), pBundle->pCurrPacket()->wpos()); Mercury::Bundle::ObjPool().reclaimObject(pBundle); epListen.setnodelay(true); epListen.setnonblocking(true); fd_set fds; struct timeval tv = { 0, 100000 }; // 100ms FD_ZERO( &fds ); FD_SET((int)epListen, &fds); int selgot = select(epListen+1, &fds, NULL, NULL, &tv); if(selgot == 0) { return true; // 超时可能对方繁忙 } else if(selgot == -1) { return true; } else { COMPONENT_TYPE ctype; COMPONENT_ID cid; Mercury::TCPPacket packet; packet.resize(255); int recvsize = sizeof(ctype) + sizeof(cid); int len = epListen.recv(packet.data(), recvsize); packet.wpos(len); if(recvsize != len) { ERROR_MSG("Components::checkComponentUsable: packet invalid.\n"); return true; } packet >> ctype >> cid; if(ctype != info->componentType || cid != info->cid) { ERROR_MSG("Components::checkComponentUsable: invalid component.\n"); return false; } } return true; }
//------------------------------------------------------------------------------------- void Machine::stopserver(Mercury::Channel* pChannel, KBEngine::MemoryStream& s) { int32 uid = 0; COMPONENT_TYPE componentType; uint32 recvip; uint16 recvport; Mercury::Bundle bundle; bool success = true; s >> uid; s >> componentType; s >> recvip; s >> recvport; Mercury::EndPoint ep; ep.socket(SOCK_DGRAM); if (!ep.good()) { ERROR_MSG("Machine::stopserver: Failed to create socket.\n"); return; } Components::COMPONENTS& components = Componentbridge::getComponents().getComponents(componentType); Components::COMPONENTS::iterator iter = components.begin(); Components::ComponentInfos* cinfos = NULL; for(; iter != components.end(); ) { if((*iter).uid != uid) continue; if(componentType != (*iter).componentType) { continue; } bool usable = Componentbridge::getComponents().checkComponentUsable(&(*iter)); if(!usable) { success = true; break; } cinfos = &(*iter); Mercury::Bundle closebundle; COMMON_MERCURY_MESSAGE(componentType, closebundle, reqCloseServer); Mercury::EndPoint ep1; ep1.socket(SOCK_STREAM); if (!ep1.good()) { ERROR_MSG("Machine::stopserver: Failed to create socket.\n"); success = false; break; } if(ep1.connect((*iter).pIntAddr.get()->port, (*iter).pIntAddr.get()->ip) == -1) { ERROR_MSG("Machine::stopserver: connect server is error(%s)!\n", kbe_strerror()); success = false; break; } closebundle.send(ep1); Mercury::TCPPacket recvpacket; recvpacket.resize(255); int len = ep1.recv(recvpacket.data(), 1); if(len != 1) { success = false; break; } recvpacket >> success; break; } bundle << success; bundle.sendto(ep, recvport, recvip); }
//------------------------------------------------------------------------------------- bool CreateAccountTask::process() { if(!enable) { return false; } // 如果没有设置第三方服务地址则我们默认为成功 if(strlen(serviceAddr()) == 0) { success = true; getDatas = postDatas; return false; } Mercury::EndPoint endpoint; endpoint.socket(SOCK_STREAM); if (!endpoint.good()) { ERROR_MSG("BillingTask::process: couldn't create a socket\n"); return false; } if(postDatas.size() == 0) { ERROR_MSG(boost::format("BillingTask::process: %1% postData is NULL.\n") % commitName); return false; } u_int32_t addr; KBEngine::Mercury::EndPoint::convertAddress(serviceAddr(), addr); if(endpoint.connect(htons(servicePort()), addr) == -1) { ERROR_MSG(boost::format("BillingTask::process: connect billingserver(%1%:%2%) is error(%3%)!\n") % serviceAddr() % servicePort() % kbe_strerror()); endpoint.close(); return false; } endpoint.setnonblocking(true); endpoint.setnodelay(true); Mercury::Bundle::SmartPoolObjectPtr bundle = Mercury::Bundle::createSmartPoolObj(); (*(*bundle)).append(postDatas.data(), postDatas.size()); (*(*bundle)).send(endpoint); Mercury::TCPPacket packet; packet.resize(1024); fd_set frds; struct timeval tv = { 0, 5000000 }; // 5000ms FD_ZERO( &frds ); FD_SET((int)endpoint, &frds); int selgot = select(endpoint+1, &frds, NULL, NULL, &tv); if(selgot <= 0) { ERROR_MSG(boost::format("BillingTask::process: %1% send(%2%).\n") % commitName % postDatas); ERROR_MSG(boost::format("BillingTask::process: %1% recv is error(%2%).\n") % commitName % KBEngine::kbe_strerror()); endpoint.close(); return false; } int len = endpoint.recv(packet.data(), 1024); if(len <= 0) { ERROR_MSG(boost::format("BillingTask::process: %1% recv is size<= 0.\n===>postdatas=%2%\n") % commitName % postDatas); endpoint.close(); return false; } packet.wpos(len); getDatas.assign((const char *)(packet.data() + packet.rpos()), packet.opsize()); try { std::string::size_type fi = getDatas.find("\r\n\r\n"); if(fi != std::string::npos) { fi += 4; MemoryStream s; s.append(getDatas.data() + fi, getDatas.size() - fi); while(s.opsize() > 0) { int32 type, len; s >> type >> len; EndianConvertReverse<int32>(type); EndianConvertReverse<int32>(len); int32 error = 0; switch(type) { case 1: s >> error; EndianConvertReverse<int32>(error); if(error != 0) { success = false; endpoint.close(); std::string err; if(s.opsize() >= (sizeof(int32) * 2)) { s >> type >> len; if(len > 0 && len < 1024) { char* buf = new char[len + 1]; memcpy(buf, s.data() + s.rpos(), len); buf[len] = 0; err = buf; delete[] buf; } } DEBUG_MSG(boost::format("BillingTask::process: (%1%)op is failed! err=%2%\n<==send(%3%)\n==>recv(%4%).\n") % commitName % err % postDatas % getDatas); return false; } else { success = true; } break; case 2: { s.read_skip(len); } break; case 3: { char* buf = new char[len + 1]; memcpy(buf, s.data() + s.rpos(), len); buf[len] = 0; accountName = buf; delete[] buf; s.read_skip(len); } break; default: break; };
//------------------------------------------------------------------------------------- bool Components::checkComponentUsable(const Components::ComponentInfos* info) { // 不对其他machine做处理 if(info->componentType == MACHINE_TYPE) { return true; } bool islocal = _pNetworkInterface->intaddr().ip == info->pIntAddr->ip || _pNetworkInterface->extaddr().ip == info->pIntAddr->ip; // 如果是本机应用则判断是否还在运行中 if(islocal && info->pid > 0) { SystemInfo::PROCESS_INFOS sysinfos = SystemInfo::getSingleton().getProcessInfo(info->pid); if(sysinfos.error) { WARNING_MSG(boost::format("Components::checkComponentUsable: not found pid(%1%)\n") % info->pid); //return false; } else { Components::ComponentInfos* winfo = findComponent(info->cid); if(winfo) { winfo->cpu = sysinfos.cpu; winfo->usedmem = (uint32)sysinfos.memused; winfo->mem = float((winfo->usedmem * 1.0 / SystemInfo::getSingleton().totalmem()) * 100.0); } } } Mercury::EndPoint epListen; epListen.socket(SOCK_STREAM); if (!epListen.good()) { ERROR_MSG("Components::checkComponentUsable: couldn't create a socket\n"); return true; } epListen.setnonblocking(true); while(true) { fd_set frds, fwds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &frds ); FD_ZERO( &fwds ); FD_SET((int)epListen, &frds); FD_SET((int)epListen, &fwds); if(epListen.connect(info->pIntAddr->port, info->pIntAddr->ip) == -1) { int selgot = select(epListen+1, &frds, &fwds, NULL, &tv); if(selgot > 0) { break; } ERROR_MSG(boost::format("Components::checkComponentUsable: couldn't connect to:%1%\n") % info->pIntAddr->c_str()); return false; } } epListen.setnodelay(true); Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); // 由于COMMON_MERCURY_MESSAGE不包含client, 如果是bots, 我们需要单独处理 if(info->componentType != BOTS_TYPE) { COMMON_MERCURY_MESSAGE(info->componentType, (*pBundle), lookApp); } else { (*pBundle).newMessage(BotsInterface::lookApp); } epListen.send(pBundle->pCurrPacket()->data(), pBundle->pCurrPacket()->wpos()); Mercury::Bundle::ObjPool().reclaimObject(pBundle); fd_set fds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &fds ); FD_SET((int)epListen, &fds); int selgot = select(epListen+1, &fds, NULL, NULL, &tv); if(selgot == 0) { return true; // 超时可能对方繁忙 } else if(selgot == -1) { return true; } else { COMPONENT_TYPE ctype; COMPONENT_ID cid; int8 istate = 0; ArraySize entitySize = 0, cellSize = 0; int32 clientsSize = 0, proxicesSize = 0; uint32 telnet_port = 0; Mercury::TCPPacket packet; packet.resize(255); int recvsize = sizeof(ctype) + sizeof(cid) + sizeof(istate); if(info->componentType == CELLAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(cellSize) + sizeof(telnet_port); } if(info->componentType == BASEAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(clientsSize) + sizeof(proxicesSize) + sizeof(telnet_port); } int len = epListen.recv(packet.data(), recvsize); packet.wpos(len); if(recvsize != len) { ERROR_MSG(boost::format("Components::checkComponentUsable: packet invalid(recvsize(%1%) != ctype_cid_len(%2%).\n") % len % recvsize); if(len == 0) return false; return true; } packet >> ctype >> cid >> istate; if(ctype == CELLAPP_TYPE) { packet >> entitySize >> cellSize >> telnet_port; } if(ctype == BASEAPP_TYPE) { packet >> entitySize >> clientsSize >> proxicesSize >> telnet_port; }