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()); } }
int MulticastClientTransport::send( I_ClientTransportCallback &clientStub, const std::vector<ByteBuffer> &data, unsigned int timeoutMs) { // TODO: in some cases, may need to make a full copy of data for // each individual sub-transport, as they might transform the data. bringInNewTransports(); Lock lock(mClientTransportsMutex); // TODO: hardcoded timeoutMs = 1000; bool needToRemove = false; ClientTransportList::iterator iter; for ( iter = mClientTransports.begin(); iter != mClientTransports.end(); ++iter) { try { if ((**iter)->isInProcess()) { ClientStub & stub = static_cast<ClientStub &>(clientStub); (**iter)->doInProcessCall(stub); } else { // We used to check *iter->isConnected() here, and if so not // try the send at all. Appear to have been synchronization // issues when doing that though. // Sending synchronously, so no use for the callback DummyCallback dummyCallback; (**iter)->send(dummyCallback, data, timeoutMs); } } catch(const Exception &e) { RCF_LOG_1()(e) << "Error publishing to subscriber."; needToRemove = true; iter->reset(); } } if (needToRemove) { mClientTransports.remove( ClientTransportAutoPtrPtr() ); } clientStub.onSendCompleted(); return 1; }