bool SessionTimeoutService::cycle( int timeoutMs, const volatile bool &stopFlag) { RCF_UNUSED_VARIABLE(timeoutMs); if ( !mLastRunTimer.elapsed(mReapingIntervalMs) && !stopFlag && !mStopFlag) { Platform::OS::Sleep(1); return false; } mLastRunTimer.restart(); mSessionsTemp.resize(0); mpRcfServer->enumerateSessions(std::back_inserter(mSessionsTemp)); for (std::size_t i=0; i<mSessionsTemp.size(); ++i) { RcfSessionPtr rcfSessionPtr = mSessionsTemp[i].lock(); if (rcfSessionPtr) { RCF::Timer touchTimer( rcfSessionPtr->getTouchTimestamp() ); if (touchTimer.elapsed(mSessionTimeoutMs)) { rcfSessionPtr->disconnect(); } } } return stopFlag || mStopFlag; }
unsigned int Subscription::getPingTimestamp() { RcfSessionPtr rcfSessionPtr; { RecursiveLock lock(mMutex); rcfSessionPtr = mRcfSessionWeakPtr.lock(); } if (rcfSessionPtr) { return rcfSessionPtr->getPingTimestamp(); } return 0; }
void MulticastClientTransport::dropIdleTransports() { bringInNewTransports(); Lock lock(mClientTransportsMutex); bool needToRemove = false; ClientTransportList::iterator iter; for (iter = mClientTransports.begin(); iter != mClientTransports.end(); ++iter) { RCF::ClientTransport & transport = ***iter; RcfSessionWeakPtr rcfSessionWeakPtr = transport.getRcfSession(); if ( rcfSessionWeakPtr == RcfSessionWeakPtr() ) { // HTTP/HTTPS connections do not hold on to the RcfSession and can't receive pings. continue; } RcfSessionPtr rcfSessionPtr = rcfSessionWeakPtr.lock(); if (!rcfSessionPtr) { RCF_LOG_2() << "Dropping subscription. Subscriber has closed connection."; iter->reset(); needToRemove = true; } else { boost::uint32_t pingIntervalMs = rcfSessionPtr->getPingIntervalMs(); if (pingIntervalMs) { RCF::Timer pingTimer( rcfSessionPtr->getPingTimestamp() ); if (pingTimer.elapsed(5000 + 2*pingIntervalMs)) { std::string subscriberUrl = rcfSessionPtr->getClientAddress().string(); RCF_LOG_2()(subscriberUrl)(pingIntervalMs) << "Dropping subscription. Subscriber has not sent pings within the expected ping interval."; iter->reset(); needToRemove = true; } } } } if (needToRemove) { eraseRemove(mClientTransports, ClientTransportAutoPtrPtr()); } }
void SubscriptionService::harvestExpiredSubscriptions() { // Kill off subscriptions that haven't received any recent pings. Subscriptions subsToDrop; { Lock lock(mSubscriptionsMutex); Subscriptions::iterator iter; for (iter = mSubscriptions.begin(); iter != mSubscriptions.end(); ++iter) { SubscriptionPtr subPtr = iter->lock(); if (subPtr) { Subscription & sub = * subPtr; RecursiveLock lock(sub.mMutex); RcfSessionPtr sessionPtr = sub.mRcfSessionWeakPtr.lock(); if (!sessionPtr) { RCF_LOG_2()(sub.mPublisherUrl)(sub.mTopic) << "Dropping subscription. Publisher has closed connection."; subsToDrop.insert(*iter); } else if (sub.mPingsEnabled) { boost::uint32_t pingIntervalMs = sub.mPingIntervalMs; if (pingIntervalMs) { RCF::Timer pingTimer(sessionPtr->getPingTimestamp()); if (pingTimer.elapsed(5000 + 2*pingIntervalMs)) { RCF_LOG_2()(sub.mPublisherUrl)(sub.mTopic)(sub.mPingIntervalMs) << "Dropping subscription. Publisher has not sent pings."; subsToDrop.insert(*iter); } } } } } for (iter = subsToDrop.begin(); iter != subsToDrop.end(); ++iter) { mSubscriptions.erase(*iter); } } subsToDrop.clear(); }
SerializationProtocolOut *getCurrentSerializationProtocolOut() { ClientStubPtr clientStubPtr = RCF::getCurrentClientStubPtr(); RcfSessionPtr rcfSessionPtr = RCF::getCurrentRcfSessionPtr(); if (clientStubPtr) { return &clientStubPtr->getSpOut(); } else if (rcfSessionPtr) { return &rcfSessionPtr->getSpOut(); } else { return NULL; } }
SessionPtr AsioServerTransport::createServerSession( ClientTransportAutoPtr clientTransportAutoPtr, StubEntryPtr stubEntryPtr) { RCF2_TRACE(""); AsioSessionStatePtr sessionStatePtr(createSessionState()); SessionPtr sessionPtr(sessionStatePtr->getSessionPtr()); sessionStatePtr->implTransferNativeFrom(*clientTransportAutoPtr); if (stubEntryPtr) { RcfSessionPtr rcfSessionPtr = boost::static_pointer_cast<RcfSession>( sessionStatePtr->mSessionPtr ); rcfSessionPtr->setDefaultStubEntryPtr(stubEntryPtr); } sessionStatePtr->mState = AsioSessionState::WritingData; sessionStatePtr->onReadWrite(0, boost::system::error_code()); return sessionPtr; }
void MulticastClientTransport::pingAllTransports() { bringInNewTransports(); Lock lock(mClientTransportsMutex); if (!mMulticastTemp.get()) { mMulticastTemp.reset( new MulticastClientTransport() ); } MulticastClientTransport & multicastTemp = static_cast<MulticastClientTransport &>(*mMulticastTemp); multicastTemp.mClientTransports.resize(0); ClientTransportList::iterator iter; for (iter = mClientTransports.begin(); iter != mClientTransports.end(); ++iter) { I_ClientTransport & transport = ***iter; RcfSessionPtr rcfSessionPtr = transport.getRcfSession().lock(); if (rcfSessionPtr) { boost::uint32_t pingIntervalMs = rcfSessionPtr->getPingIntervalMs(); if (pingIntervalMs) { multicastTemp.mClientTransports.push_back(*iter); } } } RcfClient<I_Null> nullClient( mMulticastTemp ); nullClient.getClientStub().ping(RCF::Oneway); mMulticastTemp.reset( nullClient.getClientStub().releaseTransport().release() ); multicastTemp.mClientTransports.resize(0); }
void RcfServer::onWriteCompleted(SessionPtr sessionPtr) { RcfSessionPtr rcfSessionPtr = sessionPtr; rcfSessionPtr->onWriteCompleted(); }
SubscriptionPtr SubscriptionService::onRequestSubscriptionCompleted( boost::int32_t ret, const std::string & publisherName, RcfClient<I_RequestSubscription> & client, RcfClientPtr rcfClientPtr, OnSubscriptionDisconnect onDisconnect, boost::uint32_t pubToSubPingIntervalMs, bool pingsEnabled) { bool ok = (ret == RcfError_Ok); if (ok) { ClientTransportAutoPtr clientTransportAutoPtr( client.getClientStub().releaseTransport()); I_ServerTransport * pTransport = NULL; I_ServerTransportEx * pTransportEx = NULL; if (clientTransportAutoPtr->isInProcess()) { pTransport = dynamic_cast<I_ServerTransport *>( clientTransportAutoPtr.get()); } else { pTransport = & mpServer->findTransportCompatibleWith( *clientTransportAutoPtr); } pTransportEx = dynamic_cast<I_ServerTransportEx *>(pTransport); I_ServerTransportEx & serverTransportEx = * pTransportEx; SessionPtr sessionPtr = serverTransportEx.createServerSession( clientTransportAutoPtr, StubEntryPtr(new StubEntry(rcfClientPtr)), true); RCF_ASSERT( sessionPtr ); RcfSessionPtr rcfSessionPtr = sessionPtr; rcfSessionPtr->setUserData(client.getClientStub().getUserData()); rcfSessionPtr->setPingTimestamp(); std::string publisherUrl; EndpointPtr epPtr = client.getClientStub().getEndpoint(); if (epPtr) { publisherUrl = epPtr->asString(); } if ( !clientTransportAutoPtr->isInProcess() && !clientTransportAutoPtr->isAssociatedWithIoService()) { AsioServerTransport & asioTransport = dynamic_cast<AsioServerTransport &>( mpServer->getServerTransport()); clientTransportAutoPtr->associateWithIoService(asioTransport.getIoService()); } SubscriptionPtr subscriptionPtr( new Subscription( *this, clientTransportAutoPtr, rcfSessionPtr, pubToSubPingIntervalMs, publisherUrl, publisherName, onDisconnect)); rcfSessionPtr->setOnDestroyCallback( boost::bind( &Subscription::onDisconnect, SubscriptionWeakPtr(subscriptionPtr), _1)); subscriptionPtr->setWeakThisPtr(subscriptionPtr); subscriptionPtr->mPingsEnabled = pingsEnabled; Lock lock(mSubscriptionsMutex); mSubscriptions.insert(subscriptionPtr); return subscriptionPtr; } return SubscriptionPtr(); }
SubscriptionPtr SubscriptionService::onRequestSubscriptionCompleted( boost::int32_t ret, const std::string & publisherName, ClientStub & clientStub, RcfClientPtr rcfClientPtr, OnSubscriptionDisconnect onDisconnect, boost::uint32_t pubToSubPingIntervalMs, bool pingsEnabled) { if (ret != RcfError_Ok) { RCF_THROW( Exception( Error(ret) ) ); } ClientTransportAutoPtr clientTransportAutoPtr( clientStub.releaseTransport() ); ServerTransport * pTransport = NULL; ServerTransportEx * pTransportEx = NULL; pTransport = & mpServer->findTransportCompatibleWith( *clientTransportAutoPtr); pTransportEx = dynamic_cast<ServerTransportEx *>(pTransport); ServerTransportEx & serverTransportEx = * pTransportEx; SessionPtr sessionPtr = serverTransportEx.createServerSession( clientTransportAutoPtr, StubEntryPtr(new StubEntry(rcfClientPtr)), true); RCF_ASSERT( sessionPtr ); RcfSessionPtr rcfSessionPtr = sessionPtr; rcfSessionPtr->setUserData(clientStub.getUserData()); rcfSessionPtr->setPingTimestamp(); std::string publisherUrl; EndpointPtr epPtr = clientStub.getEndpoint(); if (epPtr) { publisherUrl = epPtr->asString(); } //if (!clientTransportAutoPtr->isAssociatedWithIoService()) //{ // AsioServerTransport & asioTransport = dynamic_cast<AsioServerTransport &>( // mpServer->getServerTransport()); // clientTransportAutoPtr->associateWithIoService(asioTransport.getIoService()); //} SubscriptionPtr subscriptionPtr( new Subscription( *this, clientTransportAutoPtr, rcfSessionPtr, pubToSubPingIntervalMs, publisherUrl, publisherName, onDisconnect)); rcfSessionPtr->setOnDestroyCallback( boost::bind( &Subscription::onDisconnect, SubscriptionWeakPtr(subscriptionPtr), _1)); subscriptionPtr->setWeakThisPtr(subscriptionPtr); subscriptionPtr->mPingsEnabled = pingsEnabled; Lock lock(mSubscriptionsMutex); mSubscriptions.insert(subscriptionPtr); return subscriptionPtr; }