Archived

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

Multiple client recognition

Hi everyone,

This question may seemt trivial but how can I create an ICE server that will be able to distinguish between multiple ICE clients? I'm currently using ICEStorm to send messages to 3 clients that have subscribed to a specific topic but I also want the server to be able to choose a specific client to send a message to. Is there any way of doing this? Thanks in advance.


Regards,

John

Comments

  • matthew
    matthew NL, Canada
    johnstv3 wrote:
    Hi everyone,

    This question may seemt trivial but how can I create an ICE server that will be able to distinguish between multiple ICE clients? I'm currently using ICEStorm to send messages to 3 clients that have subscribed to a specific topic but I also want the server to be able to choose a specific client to send a message to. Is there any way of doing this? Thanks in advance.


    Regards,

    John

    All methods that are safe revolve around the client explicitly identifying itself to the server in some way.

    Some specific methods could be a) use an SSL certificate for each client (heavy weight, but secure) or b) Have the client use sessions. You can do this through with the Glacier2 session management API (see demo/Glacier2/chat for an example) or a more lightweight session management API if you don't need the Glacier2 infrastructure (the upcoming 2.1.1 release will have a demo that shows how to do this).

    Another solution which I'll mention, but would not recommend, is to place the client side identifier in the messages themselves either directly in a parameter or more indirectly through the use of Ice::Context. This solution is much more error prone and doesn't allow other things that the session approach does such as automatic cleanup of server side resources after a client terminates (either through a crash, or an explicit disconnect).

    Regards, Matthew
  • Thank you Matthew for your quick reply. Your "not recommended" solution was one of the first I considered of doing but I'm glad you've advised not to. Glacier2's session management seems the best option for now but can it be easily refactored to the upcoming 2.1.1 session API should I decide to go with it? And is there any ETA for the 2.1.1 release?


    Regards,

    John
  • matthew
    matthew NL, Canada
    johnstv3 wrote:
    Thank you Matthew for your quick reply. Your "not recommended" solution was one of the first I considered of doing but I'm glad you've advised not to. Glacier2's session management seems the best option for now but can it be easily refactored to the upcoming 2.1.1 session API should I decide to go with it? And is there any ETA for the 2.1.1 release?


    Regards,

    John

    Sorry, my post was misleading. The "lightweight session API" in 2.1.1 is not a new part of Ice. Its a demo to show how to do this in your own code without having to use Glacier2.

    No promises, but Ice 2.1.1 should be out before the end of the week.

    Regards, Matthew
  • marc
    marc Florida
    The Ice 2.1.1 release will be available in a few days. Glacier2 session management will not change in 2.1.1, i.e., the API will stay the same. Ice 2.1.1 will include a new demo that will show one possible way for implementing sessions (without Glacier2). This is not a new library, but you can cut&paste and modify the demo code for your own application.
  • I will take this onboard. Thank you both for your swift responses and advise. Much appreciated.


    Regards,

    John
  • Hi everyone,

    The thing that now puzzles me is how to get IceStorm working with Glacier2. I built a simple client/server session application using Glacier2 which works fine. But I'm having trouble to get IceStorm up and running that will send "broadcast" messages though Glacier2 to their respective subscribers. How would I do this? I want all client/server-side communication to go through Glacier2 and that includes Icestorm "broadcasts". Any help is appreciated. Thanks.


    Regards,

    John
  • benoit
    benoit Rennes, France
    Can you detail what kind of troubles you're experiencing?

    It should be straigthforward to do this. One solution is to have your client provide the proxy of the subscriber object to the session and have the session subscribe it to the IceStorm topic. The client doesn't directly talk to the IceStorm service for the subscription. Another solution is to directly subscribe to the IceStorm topic from the client but this requires all the clients to have access to the IceStorm service.

    Once the subscriber object is subscribed, it should start receiving updates from the topic. The updates will automatically be routed through Glacier2 if you've properly created the subscriber object in your client (see how the CallbackReceiver object is created and registered with the client object adapter in the Glacier2/callack demo for an example).

    Benoit.
  • Hi Benoit,

    I've created and subscribed to a topic (in C#) as normal on the client :


    // Get a proxy to the router
    Ice.RouterPrx defaultRouter = communicator().getDefaultRouter();
    if(defaultRouter == null)
    {
    Console.Error.WriteLine("no default router set");
    return 1;
    }

    Glacier2.RouterPrx router = Glacier2.RouterPrxHelper.checkedCast(defaultRouter);
    if(router == null)
    {
    Console.Error.WriteLine("configured router is not a Glacier2 router");
    return 1;
    }


    // Get a proxy to the topic manager
    Ice.ObjectPrx obj = communicator().stringToProxy("IceStorm/TopicManager:tcp -p 10000 -h 127.0.0.1");
    IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj);

    // Create an object adapter
    Ice.ObjectAdapter adapter = communicator().createObjectAdapter("Callback.Client");

    // Add the servant to the adapter
    Demo.UpdateClient servant = new UpdateClientI();
    Ice.ObjectPrx proxy = adapter.addWithUUID(servant);

    IceStorm.TopicPrx topic = null;

    // Get the topic and subscribe the servant to it
    try
    {
    topic = topicManager.retrieve("ClientUpdate");
    IceStorm.QoS qos = new IceStorm.QoS();
    qos.Add("reliability", "batch");
    topic.subscribe(qos, proxy);

    Console.WriteLine("subscribed to topic " + topic.getName() + "\n");
    }
    catch (IceStorm.NoSuchTopic ex)
    {
    Console.WriteLine(ex.ToString());
    // Error! No topic found!
    }

    adapter.activate();
    communicator().waitForShutdown();



    I'm using the same config file as that given with the Glacier2 example. Glacier2 starts correctly as does the IceStorm service and with tracing enabled the call is roured corrected through each. Here's a sample Glacier2 trace:


    [ glacier2router: Glacier2: adding proxy to routing table:
    IceStorm/TopicManager -t:tcp -h 127.0.0.1 -p 10000 ]
    [ glacier2router: Glacier2: routing (buffered)
    proxy = IceStorm/TopicManager -t:tcp -h 127.0.0.1 -p 10000
    operation = ice_isA
    context = ]
    [ glacier2router: Network: tcp connection established
    local address = 127.0.0.1:3041
    remote address = 127.0.0.1:10000 ]
    [ glacier2router: Glacier2: routing (buffered)
    proxy = IceStorm/TopicManager -t:tcp -h 127.0.0.1 -p 10000
    operation = retrieve
    context = ]
    [ glacier2router: Glacier2: adding proxy to routing table:
    ClientUpdate -t:tcp -h 127.0.0.1 -p 10000 ]
    [ glacier2router: Glacier2: routing (buffered)
    proxy = ClientUpdate -t:tcp -h 127.0.0.1 -p 10000
    operation = subscribe
    context = ]
    [ glacier2router: Glacier2: routing (buffered)
    proxy = ClientUpdate -t:tcp -h 127.0.0.1 -p 10000
    operation = getName
    context = ]



    And here's a sample Icestorm trace:


    [ icebox-IceStorm: Network: accepted tcp connection
    local address = 127.0.0.1:10000
    remote address = 127.0.0.1:3041 ]
    [ icebox-IceStorm: Topic: Subscribe: 2a3db8da-6a2b-47af-ad1b-5d3f69c66610 ]
    [ icebox-IceStorm: Network: accepted tcp connection
    local address = 127.0.0.1:10000
    remote address = 127.0.0.1:3042 ]
    [ icebox-IceStorm: Network: accepted tcp connection
    local address = 127.0.0.1:3033
    remote address = 127.0.0.1:3045 ]



    The problem occurs when I tell the server to publish a message to the subscriber. The fact is that it's not published. The subscriber isn't receiving it. No errors are given either?



    Regards,

    John
  • benoit
    benoit Rennes, France
    Your subscriber object doesn't have the correct identity. The identity category should be the category of "router.getServerProxy().ice_getIdentity().category" instead (see section 39.4.5 of the Ice manual):
    Demo.UpdateClient servant = new UpdateClientI();
    Ice.Identity id = new Ice.Identity();
    id.category = router.getServerProxy().ice_getIdentity().category;
    id.name = Ice.Util.generatedUUID();
    Ice.ObjectPrx proxy = adapter.add(servant, id);
    

    You can increase the tracing in IceStorm for subscribers by setting the property IceStorm.Trace.Subscriber to 1 for example.

    Hope this helps!

    Benoit.
  • Thats fantastic Benoit! Those extra lines of code did the job. Thank you again for your help and your time.


    Regards,

    John