Session Object does not exist after RCF::createCallbackConne

RCF support and general discussion.
Post Reply
MyongKyun
Posts: 7
Joined: Tue Apr 30, 2013 1:09 am

Session Object does not exist after RCF::createCallbackConne

Post by MyongKyun »

Hi

When I use callback connections, session objects doses not exist after RCF::createCallbackConnection.

Test code is like blow.

client->setname(test); <-- 1st call : create session obj at server side
RCF::createCallbackConnection(*client, callbackServer); <-- 2nd call : session obj exist.
client->print(); <-- 3rd call : Caught exception : session object does not exist.


client side)

RCF::RcfInitDeinit rcfInit;
RcfClient<I_CLIENT> *client;
RCF::RcfServer callbackServer(RCF::TcpEndpoint(0));
Client_reverseImpl client_serverimpl;
callbackServer.bind<I_CLIENT_REVERSE>(client_serverimpl);
callbackServer.start();

client = new RcfClient<I_CLIENT>(RCF::TcpEndpoint(serverip, serverport));

std::string test = "abcdef";
client->setname(test);

RCF::createCallbackConnection(*client, callbackServer);

client->print();



Server SIDE)

RCF::RcfInitDeinit rcfInit;

// Start a TCP server on port 50001, and expose MyServiceImpl.
Server_Impl myServiceImpl;
RCF::RcfServer server( RCF::TcpEndpoint("0.0.0.0", 50001) );
RCF::ThreadPoolPtr tpool(new RCF::ThreadPool(10));
server.setThreadPool(tpool);
server.bind<I_CLIENT>(myServiceImpl);
RCF::getObjectPool().setBufferCountLimit(0);
server.setOnCallbackConnectionCreated(onCallbackConnectionCreated);
server.start();


void onCallbackConnectionCreated(
RCF::RcfSessionPtr sessionPtr,
RCF::ClientTransportAutoPtr clientTransportPtr)
{
// Store the callback client transport in a global variable for later use.
RCF::Lock lock(gCallbackTransportMutex);
std::cout << "client is connected" << std::endl;

std::string &clientname = sessionPtr->getSessionObject<std::string>();
std::cout << "Session Client Name is : " << clientname << std::endl;
}


class Server_Impl
{
public:
void setname(std::string &data)
{
RCF::RcfSession & session = RCF::getCurrentRcfSession();
std::string & sessionClientName = session.getSessionObject<std::string>(true);
sessionClientName = data;
}

void print()
{
RCF::RcfSession & session = RCF::getCurrentRcfSession();
std::string & sessionClientName = session.getSessionObject<std::string>();
std::cout << "PRINT Session Client Name is : " << sessionClientName << std::endl;
}
};



INTERFACE)

RCF_BEGIN(I_CLIENT, "I_CLIENT")
RCF_METHOD_V1(void, setname, std::string &)
RCF_METHOD_V0(void, print);
RCF_END(I_CLIENT)

RCF_BEGIN(I_CLIENT_REVERSE, "I_CLIENT_REVERSE")
RCF_METHOD_R1(std::string, reverse, std::string)
RCF_END(I_CLIENT_REVERSE)

jarl
Posts: 238
Joined: Mon Oct 03, 2011 4:53 am
Contact:

Re: Session Object does not exist after RCF::createCallbackC

Post by jarl »

Thanks for the detailed description.

What's happening is that when RCF::createCallbackConnection() is called, the network connection is removed from the RcfClient<> object, and taken over by the RcfServer.

When you make a subsequent call on the same RcfClient<> object, a new network connection is created. Because the second call is using a different network connection than the first, the session objects from the first connection are no longer available.

In other words, once you've called RCF::createCallbackConnection(), the RcfClient<> becomes a brand new client, and you'll need to recreate any session objects you need.
Kind Regards

Jarl Lindrud
Delta V Software
http://www.deltavsoft.com

cinsk
Posts: 5
Joined: Mon Mar 18, 2013 6:24 am

Re: Session Object does not exist after RCF::createCallbackC

Post by cinsk »

What's happening is that when RCF::createCallbackConnection() is called, the network connection is removed from the RcfClient<> object, and taken over by the RcfServer.

When you make a subsequent call on the same RcfClient<> object, a new network connection is created. Because the second call is using a different network connection than the first, the session objects from the first connection are no longer available.

In other words, once you've called RCF::createCallbackConnection(), the RcfClient<> becomes a brand new client, and you'll need to recreate any session objects you need.
Basically, what we need is,

1. Server will interact with remote call back to client.
2. We need the same session object for the whole client connection, and the session object will be used to store the RCF::ClientTransportAutoPtr transportAutoPtr, from the onCallbackConnectionCreated().

What we first thought was, to create a server-side session, in the onCallbackConnectionCreated(), and use the session from subsequent calls.

When we tested, if we create a server-side session in onCallbackConnectionCreated(), that session is not visible from subsequent calls.
What we want is, client will call createCallbackConnection(), then server will create new session from onCallbackConnectionCreated(), and server will
use that session for the client's subsequent calls. Is this possible?

In our design, destroying/creating new session during the client's connection is very difficult. So, we want a solution that, to use the same session object
from the onCallbackConnectionCreated() ... subsequent calls. Can you provide a hint or solution to this?

jarl
Posts: 238
Joined: Mon Oct 03, 2011 4:53 am
Contact:

Re: Session Object does not exist after RCF::createCallbackC

Post by jarl »

If I understand correctly, you want to be able to make calls from the server to the client, and from the client to the server. The easiest way to do that is for the client to create two RcfClient<> objects, and call createCallbackConnection() on one of them. That way both the server and the client will end up with a RcfClient<> object, with which to make remote calls.

The two RcfClient<> objects will have separate network connections, and separate session objects.

On a network level, there would be two TCP connections, one for each RcfClient<>.

Would that work for you?

If you find yourself needing to access the same session object from multiple client connections, you probably need to use a server object instead. Server objects are held by the RcfServer, and accessed with a string key. So you can do something like this:

Code: Select all

class MyObject {};
typedef boost::shared_ptr<MyObject> MyObjectPtr;


// From within server implemenation of a remote call:
RcfServer & server = RCF::getCurrentRcfSession().getRcfServer();

std::string objKey = "<something fairly unique here>";
boost::uint32_t objTimeoutMs = 5*60*1000;
MyObjectPtr objPtr = server.getServerObject<MyObject>(objKey, objTimeoutMs);
Kind Regards

Jarl Lindrud
Delta V Software
http://www.deltavsoft.com

Post Reply