Archived

This forum has been archived. Please start a new discussion on GitHub.

Bidirectionnal Ice

Hi,

I'm trying to developp a bidirectionnal network application.
I ve wrote a simple server and a client based on the demo.
The client find easily the server, it requests a method server : newConnexion
This method instanciates via ice::Current and the identity of the client from argument, an client interface object.
And here, I have different behaviour.
    When I call the method printHello client method ( argument : a string, method which prints the string on the prompt), no problem. If I call the method printHello twice, the first is ok, and never the the second is execute.
    When I call the method getName client method ( no argument, but returns a string), the client receives the call, print a trace on the prompt, but never the server gets the string.

I ve read some post on the same topic, I desactivate the ACM : Ice.ACM.Client=0
I grow up the threadpool...

Do you have an idea?

ps: If you want, I zip my code, and attach it to the post.

Comments

  • mes
    mes California
    Hi,

    Providing sample code is usually the quickest way for us to help you. Please also tell us your operating system and compiler information, as well as the version of Ice you are using.

    Take care,
    - Mark
  • Server : Main()
                    ic= Ice::initialize(argc,argv);
    		PropertiesPtr properties = ic->getProperties();
    		Ice::ObjectAdapterPtr adapter=ic->createObjectAdapterWithEndpoints("my","tcp -p 10000");
    		ShimServer *myServer=new ShimServer();
    		myServer->setIc(ic);
    		Ice::ObjectPtr objet=myServer;
    		adapter->add(objet,Ice::stringToIdentity("MyServer"));
    		adapter->activate();
    		ic->waitForShutdown();
    
    ShimServer :
    Ice::Identity ShimServer::getUUID(const ::Ice::Current&){
    	return Ice::stringToIdentity(IceUtil::generateUUID());
    }
    
    void ShimServer::newConnexion(const ::Ice::Identity& ident,const Ice::Current &iceCurrent){
    	ShimLog::getAppliLog()->LogMessage("New player is coming " );
    	try{
    		string name;
    		IJoueurPrx    newComer=IJoueurPrx::uncheckedCast(iceCurrent.con->createProxy(ident));
    		if (newComer)
    			ShimLog::getAppliLog()->LogMessage("New player ok");
    		else
    			ShimLog::getAppliLog()->LogMessage("New player ko");
    		newComer->printHello("Ehlllo");
    		name=newComer->getName();
    		newComer->printHello("Ehlllo");
    		ShimLog::getAppliLog()->LogMessage("New player is coming " + name);
    	}catch(const Ice::Exception & e){
    		ShimLog::getTechLog()->LogMessage("An error occurs while trying to create callback : " + e.ice_name());
    	}catch(const string msg){
    		ShimLog::getTechLog()->LogMessage("An error occurs while trying to create callback : " + msg);
    	}
    	
    }
    

    Client : main()
                    ic=Ice::initialize(argc,argv);
    		PropertiesPtr properties = ic->getProperties();
    		Ice::ObjectPrx base=ic->stringToProxy("MyServer:tcp -p 10000");
    		IShimServerPrx server=IShimServerPrx::checkedCast(base);
    		if(!server){
    			throw("invalid proxy");
    		}else{
    			ShimLog::getTechLog()->LogMessage("Good Time");
    		}
    		              ShimLog::getTechLog()->LogMessage(Ice::identityToString(server->getUUID()));
    		ObjectAdapterPtr adapter=ic->createObjectAdapterWithEndpoints("ShimJoueur","tcp -p 10001");
    		ShimJoueur *joueur=new ShimJoueur();
    		
    		joueur->setIdentity(server->getUUID());
    		ShimLog::getTechLog()->LogMessage(Ice::identityToString(joueur->getIdentity()));
    		adapter->add(joueur,joueur->getIdentity());
    		adapter->activate();
    		server->ice_connection()->setAdapter(adapter);
    		server->newConnexion(joueur->getIdentity());
    		ic->waitForShutdown();
    

    ShimJoueur :
    string ShimJoueur::getName(const Ice::Current &) const{
            return name;
    }
    
    void ShimJoueur::printHello(const string &mywords,const Ice::Current &cur) const{
           printf("server messsage : %s",mywords.c_str());
    }
    

    config.properties:
    Ice.Trace.Network=3
    Ice.Trace.Protocol=1
    Ice.Warn.Connections=1
    Ice.ACM.Client=0
    Ice.ThreadPool.Client.SizeMax=5
    Ice.ThreadPool.Client.Size=4
    

    Here is the main code. What do you think about?

    Thanks for your help
  • benoit
    benoit Rennes, France
    Bonjour Pascal,

    Could you try to increase the size of your server thread pool with Ice.ThreadPool.Server.Size=2 in your server configuration file? I'm confident this should fix your problem.

    In the server, the connection to the client is managed by the server thread pool. By default this thread pool has 1 thread. Since this thread is busy dispatching the ShimServer::newConnexion() request when you invoke on your client, there's no more thread available to read the reply from the client and it hangs... You should be able to see this by increasing the tracing on your client and server with Ice.Trace.Protocol=1.

    Btw, I would recommend to not callback the client to get its name in the newConnexion method. It's much better to pass the name to the newConnexion method directly. This way you avoid holding up the server thread while waiting for the client to send the reply for getName(). Take a look at the "Avoiding deadlocks" articles from the Issue 4 and 5 of the newsletter for more information!

    Benoit.
  • hi,
    Thanks for answer.
    It works better, but I've always a problem with my getName method. never, the server have the result, wherever all methods are resolved.
    I take care of what you tell me about don't use it. But, I m trying this kind of stuff, to find the better architecture, between client and server.
  • benoit
    benoit Rennes, France
    Hi,

    I'm a bit confused, why is it working better if the getName() invocation still doesn't return? Or does it return now?

    Could you provide the tracing with Ice.Trace.Protocol=1 of your client and server? Or you could provide us a small self-compilable example that demonstrate the problem, we'll take a look at it!

    Benoit.
  • I m trying to upload Two files 1,1mo, and 1mo, but my browser doesn't upload... maybe an option to activate?
  • I uploaded them :
    server.zip
    client.zip

    Thanks for your precious time!
  • matthew
    matthew NL, Canada
    I tried your example. I changed main as follows and the example worked as expected:

    PropertiesPtr properties = Ice::createProperties();
    properties->setProperty("Ice.ThreadPool.Server.Size", "2");
    ic= Ice::initializeWithProperties(argc,argv, properties);

    As Benoit said, you MUST set the server thread pool size to 2 for this example to work as expected.
  • I'm sorry, I'm breaking my head on the floor! :(
    I did some much tests, that some of my code, is not what I want to do.

    I did more tests today, I recode some parts and it works fine. I was looking if the name was uploaded to the server, but I ve not affected the result to the good variable....

    Sorry to make you lose time. Answer from benoit was the good one!

    thanks a lot!