Home Help Center

Bidirectionnal Ice

shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
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

  • mesmes CaliforniaAdministrators, ZeroC Staff Mark SpruiellOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    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
  • shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
    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
  • benoitbenoit Rennes, FranceAdministrators, ZeroC Staff Benoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    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.
  • shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
    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.
  • benoitbenoit Rennes, FranceAdministrators, ZeroC Staff Benoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    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.
  • shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
    I m trying to upload Two files 1,1mo, and 1mo, but my browser doesn't upload... maybe an option to activate?
  • shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
    I uploaded them :
    server.zip
    client.zip

    Thanks for your precious time!
  • matthewmatthew NL, CanadaMember Matthew NewhookOrganization: ZeroC, Inc.Project: Internet Communications Engine ✭✭✭
    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.
  • shimrodshimrod Member pascal ogilOrganization: personnalProject: personal project ( mmorpg ) ✭✭
    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!
Sign In or Register to comment.