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;
    }
inline bool tryCreateRemoteObject(
    RCF::I_RcfClient &rcfClient,
    std::string objectName = "")
{
    try
    {
        rcfClient.getClientStub().createRemoteObject(objectName);
        return true;
    }
    catch (const RCF::Exception &e)
    {
        RCF_LOG_1()(e);
        return false;
    }
}
예제 #3
0
    bool TokenFactory::requestToken(Token &token)
    {
        WriteLock writeLock(mMutex);
        RCF_UNUSED_VARIABLE(writeLock);
        if (mAvailableTokens.empty())
        {
            RCF_LOG_1()(mAvailableTokens.size())(mTokenSpace.size()) 
                << "TokenFactory - no more tokens available.";

            return false;
        }
        else
        {
            Token myToken = mAvailableTokens.back();
            mAvailableTokens.pop_back();
            token = myToken;
            return true;
        }
    }
    void UdpServerTransport::open()
    {
        RCF_LOG_4()(mIpAddress.string()) << "UdpServerTransport - creating server socket.";

        int mPort = mIpAddress.getPort();

        // create and bind a socket for receiving UDP messages
        if (mFd == -1 && mPort >= 0)
        {
            int ret = 0;
            int err = 0;

            mIpAddress.resolve();
            mFd = mIpAddress.createSocket(SOCK_DGRAM, IPPROTO_UDP);

            // enable reception of broadcast messages
            int enable = 1;
            ret = setsockopt(mFd, SOL_SOCKET, SO_BROADCAST, (char *) &enable, sizeof(enable));
            err = Platform::OS::BsdSockets::GetLastError();
            if (ret)
            {
                RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_BROADCAST on listening udp socket.";
            }

            // Share the address binding, if appropriate.
            if (mEnableSharedAddressBinding)
            {
                enable = 1;

                // Set SO_REUSEADDR socket option.
                ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(enable));
                err = Platform::OS::BsdSockets::GetLastError();
                if (ret)
                {
                    RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_REUSEADDR on listening udp multicast socket.";
                }

                // On OS X and BSD variants, need to set SO_REUSEPORT as well.

#if (defined(__MACH__) && defined(__APPLE__)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) 

                ret = setsockopt(mFd, SOL_SOCKET, SO_REUSEPORT, (char *) &enable, sizeof(enable));
                err = Platform::OS::BsdSockets::GetLastError();
                if (ret)
                {
                    RCF_LOG_1()(ret)(err) << "setsockopt() - failed to set SO_REUSEPORT on listening udp multicast socket.";
                }
#endif

            }
            
            sockaddr * pServerAddr = NULL;
            Platform::OS::BsdSockets::socklen_t serverAddrSize = 0;
            mIpAddress.getSockAddr(pServerAddr, serverAddrSize);

            // bind the socket
            ret = ::bind(mFd, pServerAddr, serverAddrSize);
            if (ret < 0)
            {
                err = Platform::OS::BsdSockets::GetLastError();
                Exception e(_RcfError_Socket("bind()"), err, RcfSubsystem_Os);
                RCF_THROW(e)(mFd)(mIpAddress.string())(ret);
            }
            RCF_ASSERT_NEQ( mFd , -1 );

            if (!mMulticastIpAddress.empty())
            {
                // set socket option for receiving multicast messages

                mMulticastIpAddress.resolve();

                // TODO: implement for IPv6.
                RCF_ASSERT(
                        mIpAddress.getType() == IpAddress::V4 
                    &&  mMulticastIpAddress.getType() == IpAddress::V4);

                std::string ip = mMulticastIpAddress.getIp();
            
                ip_mreq imr;
                imr.imr_multiaddr.s_addr = inet_addr(ip.c_str());
                imr.imr_interface.s_addr = INADDR_ANY;
                int ret = setsockopt(mFd,IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*) &imr, sizeof(imr));
                int err = Platform::OS::BsdSockets::GetLastError();

                RCF_VERIFY(
                    ret ==  0,
                    Exception(
                        _RcfError_Socket("setsockopt() with IPPROTO_IP/IP_ADD_MEMBERSHIP"),
                        err,
                        RcfSubsystem_Os))
                        (mMulticastIpAddress.string())(mIpAddress.string());

                // TODO: enable source-filtered multicast messages
                //ip_mreq_source imr;
                //imr.imr_multiaddr.s_addr = inet_addr("232.5.6.7");
                //imr.imr_sourceaddr.s_addr = INADDR_ANY;//inet_addr("10.1.1.2");
                //imr.imr_interface.s_addr = INADDR_ANY;
                //int ret = setsockopt(mFd,IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (const char*) &imr, sizeof(imr));
                //int err = Platform::OS::BsdSockets::GetLastError();
            }

            // set the socket to nonblocking mode
            Platform::OS::BsdSockets::setblocking(mFd, false);

            // retrieve the port number, if it's generated by the system
            if (mPort == 0)
            {
                IpAddress ip(mFd, mIpAddress.getType());
                mPort = ip.getPort();
                mIpAddress.setPort(mPort);
            }

            RCF_LOG_2() << "UdpServerTransport - listening on port " << mPort << ".";
        }
    }