//------------------------------------------------------------------------------------- double Proxy::getRoundTripTime()const { if(clientMailbox() == NULL || clientMailbox()->getChannel() == NULL || clientMailbox()->getChannel()->endpoint() == NULL) return 0.0; return double(clientMailbox()->getChannel()->endpoint()->getRTT()) / 1000000.0; }
//------------------------------------------------------------------------------------- bool Proxy::hasClient() const { if(clientMailbox() == NULL || clientMailbox()->getChannel() == NULL || clientMailbox()->getChannel()->pEndPoint() == NULL) return false; return true; }
//------------------------------------------------------------------------------------- double Proxy::getTimeSinceHeardFromClient() const { if(clientMailbox() == NULL || clientMailbox()->getChannel() == NULL || clientMailbox()->getChannel()->pEndPoint() == NULL) return DBL_MAX; return double(timestamp() - clientMailbox()->getChannel()->lastReceivedTime()) / stampsPerSecondD(); }
//------------------------------------------------------------------------------------- Proxy::Bundles* Proxy::pBundles() { if(!clientMailbox()) return NULL; Mercury::Channel* pChannel = clientMailbox()->getChannel(); if(!pChannel) return NULL; return &pChannel->bundles(); }
//------------------------------------------------------------------------------------- Network::Channel* Proxy::pChannel() { if(!clientMailbox()) return NULL; Network::Channel* pChannel = clientMailbox()->getChannel(); if(!pChannel) return NULL; return pChannel; }
//------------------------------------------------------------------------------------- bool Proxy::pushBundle(Network::Bundle* pBundle) { if(!clientMailbox()) return false; Network::Channel* pChannel = clientMailbox()->getChannel(); if(!pChannel) return false; pChannel->send(pBundle); return true; }
//------------------------------------------------------------------------------------- void Proxy::onGiveClientTo(Network::Channel* lpChannel) { clientMailbox(new EntityMailbox(this->pScriptModule_, &lpChannel->addr(), 0, id_, MAILBOX_TYPE_CLIENT)); addr(lpChannel->addr()); Baseapp::getSingleton().createClientProxies(this); // 如果有cell, 需要通知其获得witness, 因为这个客户端刚刚绑定到这个proxy // 此时这个entity即使有cell正常情况必须是没有witness的。 onGetWitness(); }
//------------------------------------------------------------------------------------- bool Proxy::pushBundle(Network::Bundle* pBundle) { if(!clientMailbox()) return false; Network::Channel* pChannel = clientMailbox()->getChannel(); if(!pChannel) return false; pBundle->pChannel(pChannel); pBundle->finiMessage(true); pChannel->pushBundle(pBundle); { // 如果数据大量阻塞发不出去将会报警 //AUTO_SCOPED_PROFILE("pushBundleAndSendToClient"); //pChannel->send(pBundle); } return true; }
//------------------------------------------------------------------------------------- void Proxy::onClientDeath(void) { if(clientMailbox() == NULL) { ERROR_MSG(fmt::format("{}::onClientDeath: {}, channel is null!\n", this->scriptName(), this->id())); return; } SCOPED_PROFILE(SCRIPTCALL_PROFILE); DEBUG_MSG(fmt::format("{}::onClientDeath: {}.\n", this->scriptName(), this->id())); Py_DECREF(clientMailbox()); clientMailbox(NULL); addr(Network::Address::NONE); entitiesEnabled_ = false; SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onClientDeath")); }
//------------------------------------------------------------------------------------- void Proxy::initClientBasePropertys() { if(clientMailbox() == NULL) return; MemoryStream* s1 = MemoryStream::ObjPool().createObject(); addClientDataToStream(s1); if(s1->wpos() > 0) { Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->id(); (*pBundle).append(*s1); sendToClient(ClientInterface::onUpdatePropertys, pBundle); //clientMailbox()->postMail((*pBundle)); } MemoryStream::ObjPool().reclaimObject(s1); }
//------------------------------------------------------------------------------------- void Proxy::onGiveClientTo(Mercury::Channel* lpChannel) { clientMailbox(new EntityMailbox(this->scriptModule_, &lpChannel->addr(), 0, id_, MAILBOX_TYPE_CLIENT)); addr(lpChannel->addr()); Baseapp::getSingleton().createClientProxies(this); /* 如果有cell则已经绑定了witness, 在此我们不需要再次绑定。 if(cellMailbox()) { // 通知cell获得客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onGetWitness); (*pBundle) << this->id(); sendToCellapp(pBundle); } */ }
//------------------------------------------------------------------------------------- void Proxy::initClientCellPropertys() { if(clientMailbox() == NULL) return; Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->id(); ENTITY_PROPERTY_UID spaceuid = ENTITY_BASE_PROPERTY_UTYPE_SPACEID; Mercury::FixedMessages::MSGInfo* msgInfo = Mercury::FixedMessages::getSingleton().isFixed("Property::spaceID"); if(msgInfo != NULL) { spaceuid = msgInfo->msgid; } if(scriptModule()->usePropertyDescrAlias()) { uint8 aliasID = ENTITY_BASE_PROPERTY_ALIASID_SPACEID; (*pBundle) << aliasID << this->spaceID(); } else { (*pBundle) << spaceuid << this->spaceID(); } MemoryStream* s = MemoryStream::ObjPool().createObject(); // celldata获取客户端感兴趣的数据初始化客户端 如:ALL_CLIENTS addCellDataToStream(ED_FLAG_ALL_CLIENTS|ED_FLAG_CELL_PUBLIC_AND_OWN|ED_FLAG_OWN_CLIENT, s, true); (*pBundle).append(*s); MemoryStream::ObjPool().reclaimObject(s); //clientMailbox()->postMail((*pBundle)); //Mercury::Bundle::ObjPool().reclaimObject(pBundle); sendToClient(ClientInterface::onUpdatePropertys, pBundle); }
//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { if(isDestroyed()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: %d is destroyed.", scriptName(), id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", scriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } Network::Channel* lpChannel = clientMailbox_->getChannel(); if(proxy) { if(proxy->isDestroyed()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is destroyed.", scriptName(), proxy->id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(proxy->id() == this->id()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is self.", scriptName(), proxy->id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } EntityMailbox* mb = proxy->clientMailbox(); if(mb != NULL) { ERROR_MSG(fmt::format("Proxy::giveClientTo: {}[{}] give client to {}[{}], {} has clientMailbox.\n", scriptName(), id(), proxy->scriptName(), proxy->id(), proxy->scriptName())); onGiveClientToFailure(); return; } if(cellMailbox()) { // 当前这个entity如果有cell,说明已经绑定了witness, 那么既然我们将控制权 // 交换给了另一个entity, 这个entity需要解绑定witness。 // 通知cell丢失witness Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onLoseWitness); (*pBundle) << this->id(); sendToCellapp(pBundle); } // 既然客户端失去对其的控制, 那么通知client销毁这个entity Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onEntityDestroyed); (*pBundle) << this->id(); sendToClient(ClientInterface::onEntityDestroyed, pBundle); // 将控制权交换 entitiesEnabled_ = false; clientMailbox()->addr(Network::Address::NONE); Py_DECREF(clientMailbox()); proxy->setClientType(this->getClientType()); proxy->setClientDatas(this->getClientDatas()); this->setClientType(UNKNOWN_CLIENT_COMPONENT_TYPE); this->setClientDatas(""); clientMailbox(NULL); proxy->onGiveClientTo(lpChannel); addr(Network::Address::NONE); } }
//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { if(isDestroyed()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: %d is destroyed.", scriptName(), id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", scriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } Mercury::Channel* lpChannel = clientMailbox_->getChannel(); if(proxy) { if(proxy->isDestroyed()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is destroyed.", scriptName(), proxy->id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(proxy->id() == this->id()) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is self.", scriptName(), proxy->id()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } EntityMailbox* mb = proxy->clientMailbox(); if(mb != NULL) { ERROR_MSG(boost::format("Proxy::giveClientTo: %1%[%2%] give client to %3%[%4%], %5% has clientMailbox.\n") % scriptName() % id() % proxy->scriptName() % proxy->id() % proxy->scriptName()); onGiveClientToFailure(); return; } if(cellMailbox()) { // 通知cell丢失客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onResetWitness); (*pBundle) << this->id(); sendToCellapp(pBundle); } entitiesEnabled_ = false; clientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(clientMailbox()); proxy->onGiveClientTo(lpChannel); clientMailbox(NULL); addr(Mercury::Address::NONE); if(proxy->clientMailbox() != NULL) { // 通知client销毁当前entity Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onEntityDestroyed); (*pBundle) << this->id(); proxy->sendToClient(ClientInterface::onEntityDestroyed, pBundle); //Mercury::Bundle::ObjPool().reclaimObject(pBundle); } } }