Page 1 of 1

RCFProto how to retrieve session information

Posted: Fri Mar 20, 2015 4:30 pm
by denisc
hi everybody,

I wrote the code below. It works very well. I am just wondering if there is an elegant way to have session information accessible outside of the protobuf service implementation ? In the thread for my case.
I can do it with some static stuff but.... I don't like it !

Thank you for your help.
best regards
Denis

Code: Select all

// PositionInformationService implementation.
class PositionInformationImpl : public PositionInformationService
{
public:

    // PositionInformation() method implementation.
    void PositionInformation(
        RpcController *                             controller,
        const PositionInformationTransmit *         request,
        PositionInformationReceive *                response,
        Closure *                                   done)
    {
        startup_severity_channel_logger_mt& lg = protobufsyncserver_logger_c1::get();

        BOOST_LOG_SEV(lg, notification) << "message received from train !";

        RCF::RcfProtoController * rcfController = static_cast<RCF::RcfProtoController *>(controller);
        RCF::RcfProtoSession * pprotoSession = rcfController->getSession();
        RCF::RcfSession & rcfSession = rcfController->getSession()->getRcfSession();
        // Fill in the response.
        response->set_servername("server");

        // Send response back to the client.
        done->Run();

        bool b = rcfSession.getEnableCompression();
        cout << "compression enable ?: " << b << endl;
        const RCF::RemoteAddress & ipaddress = rcfSession.getClientAddress();
        BOOST_LOG_SEV(lg, notification) << "remote address: " << ipaddress.string() << std::endl;
        time_t timeraw = rcfSession.getConnectedAtTime();
        std::cout << "connected at time: " << ctime(&timeraw);
        RCF::SessionState & sessionState = rcfSession.getSessionState();
        b = sessionState.isConnected();
        cout << "Session active ?: " << b << endl;
        std::cout << "request user data: " << rcfSession.getRequestUserData() << std::endl;
        std::cout << "connection duration: " << pprotoSession->getConnectionDuration() << std::endl;
        std::cout << "remote call count: " << pprotoSession->getRemoteCallCount() << std::endl;
        std::cout << "total bytes received: " << pprotoSession->getTotalBytesReceived() << std::endl;
        std::cout << "total bytes sent: " << pprotoSession->getTotalBytesSent() << std::endl;
        std::cout << "transport protocol : " << pprotoSession->getTransportProtocol() << std::endl;
        std::cout << "transport type : " << pprotoSession->getTransportType() << std::endl;
        std::cout << "session cancelled ? " << pprotoSession->IsCanceled() << std::endl;

    }
};

void ProtobufSyncServer::ProtobufSyncServerThreadsCode(void)   //RCF and protobuf will start other threads hence the thread(s)
{
    startup_severity_channel_logger_mt& lg = protobufsyncserver_logger_c1::get();
    std::chrono::seconds duration(1);

    this->session_.sessionactive_=true;

    try
    {
        // Initialize RCFProto.
        RCF::init();
        RCF::enableLogging( RCF::LogToFile("/home/train/programs/real/rcfproto.log"), 4, "");
        BOOST_LOG_SEV(lg, notification) << "RCF init !";
        // Create server.
        RCF::RcfProtoServer server( RCF::TcpEndpoint("0.0.0.0", 50001) );
        BOOST_LOG_SEV(lg, notification) << "Protobuf server created !";
        // Bind Protobuf service.
        PositionInformationImpl positionInformationImpl;
        server.bindService(positionInformationImpl);
        BOOST_LOG_SEV(lg, notification) << "RCF proto server declared and service bind !";

        // Start the server.
        server.start();
        BOOST_LOG_SEV(lg, notification) << "RCF proto server started !";

        while(!g_signal_received)
        {
            std::this_thread::sleep_for(duration);
            BOOST_LOG_SEV(lg, notification) << "hello from protobufsyncserver thread";
        }
        if(g_signal_received) BOOST_LOG_SEV(lg, notification) << "Signal received, terminating ProtobufSyncServerThreads";

    }
    catch(const RCF::Exception & e)
    {
        BOOST_LOG_SEV(lg, critical) << "RCF::Exception: " << e.getErrorString();
        return;
    }
}

Re: RCFProto how to retrieve session information

Posted: Mon Mar 23, 2015 2:48 am
by jarl
There isn't currently a built in way to iterate over all existing client connections, but as your server is in C++, you can use regular RcfServer functionality to accomplish this. For each client connection, you should create an application-specific session object, as described here:

http://www.deltavsoft.com/doc/rcf_user_ ... r_sessions

In the constructor and destructor of the session object, you should register and unregister the object in a global or server-level map. Then, you can iterate over this map and dig out any information you need about each client.

You'll need thread synchronization locks around the map, to make sure sessions are not added or removed while you are iterating.