示例#1
0
    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);
    }
示例#8
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;                
    }