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();
    }