Archived

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

proxy acquisition problem

Hi,

In an older version of ice, I wrote some code snippets, I wanted to reuse today, but I got some problems.

I want to get a proxy to an object of the server, added to the adapter with an id generated by Ice.Util.generateUUID. The server is a java program, and the client a C++ program.

In my client, I wrote
ITestPrx proxyToTest;
string proxy=Ice::identityToString(Id) + ":" + adressToServer;
Ice::ObjectPrx base=ic->stringToProxy(proxy);
proxyToTest=ITestPrx::checkedCast(base);

Badly, it doesn't work. In my stderr.txt of my client, when I activate Ice trace:
05/04/07 23:12:41.374 warning: Proxy contains unknown endpoints: `a8' `0' `1' `27501a26' `11258effa61' `-8000'
And effectively, the server client generate this id:
c0:a8:0:1:27501a26:11258effa61:-8000

Strange, cause in previous version of ice, the different parts of the id was separated by - and not by :.

So what? Do I have to acquire proxy from a different way?

Can you help me please?

thank you

Comments

  • matthew
    matthew NL, Canada
    UUID identities generated by java servers have always contained ':' as the separator. The problem with your code is that you are not correctly enclosing the stringified identity in quotes. You can fix this problem as follows:
    string proxy="'" + Ice::identityToString(Id) + "':" + adressToServer;

    This code looks a little suspicious though. Typically you'd have a well known identity (something simple like "Master") which you contact in your server and then use that to retrieve other objects. Not some object identified by a UUID as a point of first contact.
  • The way I do, I create an UUId for each object I want to reach, and I create a proxy for each one. Then, With the precedently code, I got a proxy to them.
    class A { //master object
        vector<B *> listOfFollowingObject;
        
        vector<B *> getListOfFollowingObject();
    };
    
    class B{
       string name;
       string info;....
    
       string getName();
       string getInfo();
    };
    
    


    What you say, it is to do that, for only the master object, cause I have the need of one proxy at least, and them, I hava to do something like proxy->getFollowingObjects(), which returns a vector of reference to the object B? directly? Without using intermediate proxy?

    In this case, I don't have the needs to generate UUID, and I call my master simply Master ( Yes Master!! Zogzog).

    Is it like this?
  • matthew
    matthew NL, Canada
    Yes, this is better for a whole bunch of reasons. The best reason is that its easier then to replicate and distribute the master object and objects created by the master across multiple nodes if and when you need more scalability. If you do things as you've outlined initially then you need to know the address of all of the nodes and upon which node the object lives to construct the stringified proxy. However, if you have a single replicated master object (or a sequence of possible masters) upon which you call to get the sub-objects you don't need to know the address and such of the object.

    For example, this is quite typical:
    interface User
    {
      // user methods
      void destroy();
    };
    
    interface UserFactory
    {
      User* createUser(string name, // other details);
    };
    
    interface UserLookup
    {
       User* getUserByName(string name);
    };
    

    In this case UserFactory is replicated. User is per-factory. UserLookup is a singleton object which ensures that no-username is duplicated, and provides a central repository for all of the users.

    Code using the users don't need to know which factory they use, nor where they reside.

    I described this scenario in detail in my initial set of newsletter articles on the chat system in Connections.
  • right. But I have a runtime error now.

    Here the ice definition of my connexionManager. It returns the Joueur object defines on another ice file, which just return an string on getName().
    #ifndef _ICONNEXIONMANAGER_
    #define _ICONNEXIONMANAGER_
    
    #include <Ice/Identity.ice>
    #include <IJoueur.ice>
    
    module MedievalStory{
    
      interface IConnexionManager{
    
        int newConnexion(string name, string pwd);
        void disconnect(string name);
        IJoueur getJoueur(string username);
      };
    };
    
    #endif
    

    I extend a class with IJoueur.

    In my connexionManager, I implement the methods, and below the getJoueur Method:
    public IJoueur getJoueur(String username, Current __current) {
             //seeking in a hashtable name->Joueur object
    		Joueur temp=(Joueur) listOfJoueur.get(username);
    		if (temp!=null){
                            system.out.println("object found!");
    			return temp;
    		}
    		return null;
    	}
    
    An object is found, and is return, I got my message in console.

    In my client code:
    IJoueurPtr myJoueur=Server::Instance()->getProxy()->getJoueur("username");
    printLog("ptr received");
    

    but I have never this log message. I got a runtime error.

    end of the client ice trace:
    [ 05/05/07 22:29:15.730 Protocol: sending request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 68
    request id = 3
    identity = MyMedievalStoryServer
    facet =
    operation = getJoueur
    mode = 0 (normal)
    context = ]
    [ 05/05/07 22:29:15.730 Network: sent 68 of 68 bytes via tcp
    local address = 192.168.0.1:1195
    remote address = 192.168.0.1:55000 ]
    [ 05/05/07 22:29:15.730 Network: received 14 of 14 bytes via tcp
    local address = 192.168.0.1:1195
    remote address = 192.168.0.1:55000 ]
    [ 05/05/07 22:29:15.730 Network: received 41 of 41 bytes via tcp
    local address = 192.168.0.1:1195
    remote address = 192.168.0.1:55000 ]
    [ 05/05/07 22:29:15.730 Protocol: received reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 55
    request id = 3
    reply status = 0 (ok) ]

    here the ice trace from server:
    [ 05/05/07 22:29:15:730 Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 68
    request id = 3
    identity = MyMedievalStoryServer
    facet =
    operation = getJoueur
    mode = 0 (normal)
    context = ]
    [ 05/05/07 22:29:15:730 Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 55
    request id = 3
    reply status = 0 (ok) ]
    [ 05/05/07 22:29:15:730 Network: sent 55 of 55 bytes via tcp
    local address = 192.168.0.1:55000
    remote address = 192.168.0.1:1195 ]
    05/05/07 22:29:20:126 warning: connection exception:
    local address = 192.168.0.1:55000
    remote address = 192.168.0.1:1195
    Ice.SocketException
    error = 0
    at IceInternal.TcpTransceiver.read(TcpTransceiver.java:314)
    at Ice.ConnectionI.read(ConnectionI.java:1307)
    at IceInternal.ThreadPool.read(ThreadPool.java:929)
    at IceInternal.ThreadPool.run(ThreadPool.java:723)
    at IceInternal.ThreadPool.access$100(ThreadPool.java:12)
    at IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:1242)
    Caused by: java.io.IOException: Une connexion existante a dû être fermée par l'hôte distant
    at sun.nio.ch.SocketDispatcher.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(Unknown Source)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
    at sun.nio.ch.IOUtil.read(Unknown Source)
    at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
    at IceInternal.TcpTransceiver.read(TcpTransceiver.java:243)
    ... 5 more

    [ 05/05/07 22:29:20:126 Network: shutting down tcp connection for writing
    local address = 192.168.0.1:55000
    remote address = 192.168.0.1:1195 ]
    [ 05/05/07 22:29:20:126 Network: closing tcp connection
    local address = 192.168.0.1:55000
    remote address = 192.168.0.1:1195 ]

    The exception will come because the client end the connexion, pretty violently. I got this error before my runtime error.

    I do something wrong, I think... but what it is?
  • matthew
    matthew NL, Canada
    What is the IJoueur object? Is it abstract or concrete (you can see the Ice manual for what this means in the context of passing an object over the wire). Do you really mean to pass an object, btw, and not a proxy to the object?

    Looking at your slice I would also recommend that you make the connection an object. More like:
    module MedievalStory{
      interface IConnexion {
        IJoueur getJoueur(string username);
        void destroy();
      };
      interface IConnexionManager{
        IConnexion* newConnexion(string name, string pwd);
      };
    };
    
  • IJoueur is an interface declared in an ice file.
    Joueur is a class which extends the IJoueur interface.

    I saw in your recommandation for declare my Ice Interface, than you return an interface (IConnexion).
    In fact, in my java code, I will create a Connexion class which will extend this interface, and a class ConnexionManager which will extends the IConnexionManager. The class ConnexionManager will return a Connexion object.
    Is it that?

    Oki, I try this...
  • Oki, when I return a IConnexion * in my ice, the translation in java, is IConnexionPrx.
    How from my object Connexion extending IConnexion, I can send an IConnexionPrx?
    I read the documentation, but I saw how to acquire proxy from the client ( whith id:adress), but not how to do to have a IconnexionPrx on the server?
    class ConnexionManager extends IConnexionManager{
     ....
    ....
    
    public IConnexionPrx getConnexion(String username, Currrent __current){
        Connexion myConnexion=new Connexion();
        IConnexionPrx myPrx=...???;
        return ????;
    }
    }
    
    

    thank you
  • IConnexionPrx proxy = IJoueurPrxHelper.uncheckedCast(adapter.addWithUUID(myConnexion));
    

    ok I will continue in this way...

    thanks a lo
  • matthew
    matthew NL, Canada
    As you see there is a significant difference between returning an object and a proxy to the object. Returning an object is analogous to in C++:
    class foo
    {
       // ...
    };
    
    foo
    getFoo()
    {
       foo f;
       // ...
       return f;
    }
    

    Returning a proxy is analogous to to:
    foo*
    getFoo()
    {
       foo* f = new foo();
       // ...
       return f;
    }
    

    If you return abstract objects (that is objects with methods) then you must install an object factory in your client to instantiate local implementations of this object. You can see the Ice manual for more information on this.