//------------------------------------------------------------------------------------- bool Proxy::sendToClient(bool expectData) { if(!getClientMailbox()) return false; Mercury::Channel* pChannel = getClientMailbox()->getChannel(); if(!pChannel) return false; if(expectData) { if(pChannel->bundles().size() == 0) { WARNING_MSG("Proxy::sendToClient: no data!\n"); return false; } } { // 如果数据大量阻塞发不出去将会报警 AUTO_SCOPED_PROFILE("sendToClient"); pChannel->send(); } return true; }
//------------------------------------------------------------------------------------- PyObject* Proxy::pyClientAddr() { if(isDestroyed()) { PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n", getScriptName(), getID()); PyErr_PrintEx(0); return 0; } PyObject* pyobj = PyTuple_New(2); if(getClientMailbox() == NULL || getClientMailbox()->getChannel() == NULL || getClientMailbox()->getChannel()->endpoint() == NULL) { PyTuple_SetItem(pyobj, 0, PyLong_FromLong(0)); PyTuple_SetItem(pyobj, 1, PyLong_FromLong(0)); } else { const Mercury::Address& addr = getClientMailbox()->getChannel()->endpoint()->addr(); PyTuple_SetItem(pyobj, 0, PyLong_FromUnsignedLong(addr.ip)); PyTuple_SetItem(pyobj, 1, PyLong_FromUnsignedLong(addr.port)); } return pyobj; }
//------------------------------------------------------------------------------------- void Proxy::initClientCellPropertys() { if(getClientMailbox() == NULL) return; Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->getID(); 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; } (*pBundle) << spaceuid << this->getSpaceID(); MemoryStream* s = MemoryStream::ObjPool().createObject(); addPositionAndDirectionToStream(*s); (*pBundle).append(s); MemoryStream::ObjPool().reclaimObject(s); // celldata获取客户端感兴趣的数据初始化客户端 如:ALL_CLIENTS s = MemoryStream::ObjPool().createObject(); addCellDataToStream(ED_FLAG_ALL_CLIENTS|ED_FLAG_CELL_PUBLIC_AND_OWN|ED_FLAG_OWN_CLIENT, s); (*pBundle).append(*s); MemoryStream::ObjPool().reclaimObject(s); getClientMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); }
//------------------------------------------------------------------------------------- bool Proxy::hasClient()const { if(getClientMailbox() == NULL || getClientMailbox()->getChannel() == NULL || getClientMailbox()->getChannel()->endpoint() == NULL) return false; return true; }
//------------------------------------------------------------------------------------- double Proxy::getTimeSinceHeardFromClient()const { if(getClientMailbox() == NULL || getClientMailbox()->getChannel() == NULL || getClientMailbox()->getChannel()->endpoint() == NULL) return DBL_MAX; return double(timestamp() - getClientMailbox()->getChannel()->lastReceivedTime()) / stampsPerSecondD(); }
//------------------------------------------------------------------------------------- double Proxy::getRoundTripTime()const { if(getClientMailbox() == NULL || getClientMailbox()->getChannel() == NULL || getClientMailbox()->getChannel()->endpoint() == NULL) return 0.0; return double(getClientMailbox()->getChannel()->endpoint()->getRTT()) / 1000000.0; }
//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", getScriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } Mercury::Channel* lpChannel = clientMailbox_->getChannel(); if(proxy) { EntityMailbox* mb = proxy->getClientMailbox(); if(mb != NULL) { ERROR_MSG(boost::format("Proxy::giveClientTo: %1%[%2%] give client to %3%[%4%], %5% have clientMailbox.\n") % getScriptName() % getID() % proxy->getScriptName() % proxy->getID() % proxy->getScriptName()); onGiveClientToFailure(); return; } if(getCellMailbox()) { // 通知cell丢失客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onResetWitness); (*pBundle) << this->getID(); getCellMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } entitiesEnabled_ = false; getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); proxy->onGiveClientTo(lpChannel); setClientMailbox(NULL); addr(Mercury::Address::NONE); if(proxy->getClientMailbox() != NULL) { // 通知client销毁当前entity Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onEntityDestroyed); (*pBundle) << this->getID(); proxy->getClientMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } } }
//------------------------------------------------------------------------------------- Proxy::Bundles* Proxy::pBundles() { if(!getClientMailbox()) return NULL; Mercury::Channel* pChannel = getClientMailbox()->getChannel(); if(!pChannel) return NULL; return &pChannel->bundles(); }
//------------------------------------------------------------------------------------- void Proxy::onClientDeath(void) { DEBUG_MSG("%s::onClientDeath: %d.\n", this->getScriptName(), this->getID()); if(getClientMailbox() != NULL) { Py_DECREF(getClientMailbox()); setClientMailbox(NULL); addr(Mercury::Address::NONE); } SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onClientDeath")); }
//------------------------------------------------------------------------------------- void Entity::onLoseWitness(Mercury::Channel* pChannel) { KBE_ASSERT(this->getClientMailbox() != NULL && this->hasWitness()); getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); setClientMailbox(NULL); pWitness_->detach(this); Witness::ObjPool().reclaimObject(pWitness_); pWitness_ = NULL; SCOPED_PROFILE(SCRIPTCALL_PROFILE); SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onLoseWitness")); }
//------------------------------------------------------------------------------------- void Proxy::giveClientTo(Proxy* proxy) { Mercury::Channel* lpChannel = clientMailbox_->getChannel(); if(lpChannel == NULL) { char err[255]; kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.\n", getScriptName()); PyErr_SetString(PyExc_TypeError, err); PyErr_PrintEx(0); onGiveClientToFailure(); return; } if(proxy) { EntityMailbox* mb = proxy->getClientMailbox(); if(mb != NULL) { ERROR_MSG("Proxy::giveClientTo: %s[%ld] give client to %s[%ld], %s have clientMailbox.", getScriptName(), getID(), proxy->getScriptName(), proxy->getID(), proxy->getScriptName()); onGiveClientToFailure(); return; } if(getCellMailbox()) { // 通知cell丢失客户端 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(CellappInterface::onLoseWitness); getCellMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } getClientMailbox()->addr(Mercury::Address::NONE); Py_DECREF(getClientMailbox()); proxy->onGiveClientTo(lpChannel); setClientMailbox(NULL); addr(Mercury::Address::NONE); } }
//------------------------------------------------------------------------------------- PyObject* Entity::pyGetClientMailbox() { EntityMailbox* mailbox = getClientMailbox(); if(mailbox == NULL) S_Return; Py_INCREF(mailbox); return mailbox; }
//------------------------------------------------------------------------------------- void Proxy::initClientBasePropertys() { if(getClientMailbox() == NULL) return; MemoryStream* s1 = MemoryStream::ObjPool().createObject(); addClientDataToStream(s1); if(s1->wpos() > 0) { Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->getID(); (*pBundle).append(*s1); getClientMailbox()->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } MemoryStream::ObjPool().reclaimObject(s1); }
//------------------------------------------------------------------------------------- void Proxy::onClientDeath(void) { if(getClientMailbox() == NULL) { ERROR_MSG(boost::format("%1%::onClientDeath: %2%, channel is null!\n") % this->getScriptName() % this->getID()); return; } SCOPED_PROFILE(SCRIPTCALL_PROFILE); DEBUG_MSG(boost::format("%1%::onClientDeath: %2%.\n") % this->getScriptName() % this->getID()); Py_DECREF(getClientMailbox()); setClientMailbox(NULL); addr(Mercury::Address::NONE); entitiesEnabled_ = false; SCRIPT_OBJECT_CALL_ARGS0(this, const_cast<char*>("onClientDeath")); }
//------------------------------------------------------------------------------------- PyObject* Base::pyGetClientMailbox() { if(isDestroyed()) { PyErr_Format(PyExc_Exception, "%s: %d is destroyed!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } EntityMailbox* mailbox = getClientMailbox(); if(mailbox == NULL) S_Return; Py_INCREF(mailbox); return mailbox; }
//------------------------------------------------------------------------------------- void Proxy::initClientCellPropertys() { if(getClientMailbox() == NULL) return; Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << this->getID(); 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(getScriptModule()->usePropertyDescrAlias()) { uint8 aliasID = ENTITY_BASE_PROPERTY_ALIASID_SPACEID; (*pBundle) << aliasID << this->getSpaceID(); } else { (*pBundle) << spaceuid << this->getSpaceID(); } 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); //getClientMailbox()->postMail((*pBundle)); //Mercury::Bundle::ObjPool().reclaimObject(pBundle); sendToClient(ClientInterface::onUpdatePropertys, pBundle); }