What locator options exist for javascript mapping...

smandysmandy Member Andy SmithOrganization: Self EmployedProject: Learning Ice
Hi All,

I'm trying to get my head around the scope of functionality possible using the javascript language mapping. ( Specifically with respect to location services).

Option1 - The ideal case would be that IceLocatorDiscovery and IceLocatorDiscovery would be supported but I guess at the moment that is unrealistic given websocket imitations and lack of multicast in javascript?

Option2 - is it possible to pass a properties file to the javascript initialize method that specifies something like ...
Ice.Default.Locator=IceGrid/Locator:ws -h mygridhost -p 4321

I guess the grid would need to be suitable configured to open up a websocket transport as well ....would this work. ( In locator config on mygridhost)?

IceGrid.Registry.Client.Endpoints=ws -h localhost -p 4321


I guess there would need to be multiple endpoints to support tcp as well, but I hope the question is clear....

Option3 - Use the locator API manually. Use the slice definition for the locator api to perform lookup on various services. Again question still remains does the icegrid need to have both tcp and ws endpoints enabled to enable this?

I guess for all of these options there will be tweaking required to add websocket endpoints to existing services. Is it possible to make a service 'bilingual', i.e. have it support websocket for javascript clients and, say, TCP for C++/java/python clients. If so how does a client specify a particular endpoint type? Or does the locator just work it out based on context - i.e. only return WS endpoints to a WS client, TCP endpoints to a TCP client et??

Sorry for barrage of questions - just trying to figure out what's realistic to attempt and what isn't! Also thinking all this through a bit I'm really starting to see the wisdom behind the adapter/endpoint abstraction. It sounds like getting all this working can be achieved solely at the endpoint level without having to touch how client/server code uses adapters. Nice!

Cheers,

A.
















Comments

  • smandysmandy Member Andy SmithOrganization: Self EmployedProject: Learning Ice
    I've made a bit of progress on this ( and discovered one or two followup questions :-) ).

    I can get either a node client or browser client to use the Icegrid locator provided I use the correct proxt. Didn't realise node still uses TCP as the default transport, whereas running in a browser is (by necessity), using the websocket transport. Is there a reason node is using TCP and not WS? Seems a bit asymmetrical?

    Anyway here's how I'm creating communicator on the browser side...
         var iid = new Ice.InitializationData();
         iid.properties = Ice.createProperties();
         iid.properties.setProperty("Ice.Default.Locator", "IceGrid/Locator:ws -h localhost -p 4063");
         var communicator = Ice.initialize([], iid);
    

    I made a few attempts trying to set iid.properties["Ice.Default.Locator"], which I guess does nothing useful :-)

    Corresponding tweak to the icegrid config to get it to open up a websocket transport ...
    Ice.Default.Locator=IceGrid/Locator:tcp -p 4061:ws -p 4061
    

    This seemed to work well until I tried making calls on existing services I'd already set up on IceGrid. Then I realised that I needed to add a Websocket transport to their corresponding adapters.

    i.e. IceGrid app config looking like this ....
                <adapter name="SimpleApp" endpoints="tcp -h raffles" id="SimpleApp"/>
    

    (where 'raffles is my laptop name :-) )

    Needs to become something like this...
                <adapter name="SimpleApp" endpoints="tcp -h raffles:ws -h raffles" id="SimpleApp"/>
    

    I'm connecting to a well-known proxy of the form '[email protected]'.
    It works intermittently for javascript clients (approx 50% of the time hint hint),

    NB in the failure trace - here is the stacktrace generated in the browser.
    TypeError: Cannot read property 'createOutgoing' of null
        at Class.connect (http://localhost:8080/bower_components/ice/lib/Ice.js:16835:38)
        at Class.nextEndpoint (http://localhost:8080/bower_components/ice/lib/Ice.js:23955:79)
        at Class.getConnection (http://localhost:8080/bower_components/ice/lib/Ice.js:23385:20)
        at Class.getConnection (http://localhost:8080/bower_components/ice/lib/Ice.js:23915:52)
        at Class.start (http://localhost:8080/bower_components/ice/lib/Ice.js:23904:22)
        at Class.create (http://localhost:8080/bower_components/ice/lib/Ice.js:23114:27)
        at Class.createConnection (http://localhost:8080/bower_components/ice/lib/Ice.js:22106:29)
        at http://localhost:8080/bower_components/ice/lib/Ice.js:21888:34
        at resolveImp (http://localhost:8080/bower_components/ice/lib/Ice.js:4115:43)
        at Ice.Class.resolve (http://localhost:8080/bower_components/ice/lib/Ice.js:4252:21)
    

    I've a similar python client and it behaves fine.

    I did a bit of drilling on the python side to see what type of connection would be returned - here's code and output
    import Ice
    import time
    
    for i in range(10):
        communicator = Ice.initialize( [ '--Ice.Config=locator.properties'])
        pyPrx = communicator.stringToProxy('[email protected]')
        print pyPrx.ice_getConnection().type()
        time.sleep(1)
    
    ws
    ws
    tcp
    tcp
    tcp
    tcp
    tcp
    ws
    ws
    ws
    

    So it looks like I'm getting a random choice between the tcp or ws endpoins. Looks like the behaviour I'd expect to get with a replicated adapter. I guess since the locator is oblivious to client type the javascript is receiving the same pattern. The python guy is happy talking to either I guess as the python language mapping can talk TCP and WS quite happily. I guess the javascript client, however, is effectively playing russian roulette ( with three bullets in the gun!) and only succeeds in the case where he gets a proxy with a websocket endpoint.

    I guess a workaround would be to loop around checking the type of ice_getConnection but that seems like a horrible solution. Another obvious solution would be to create adapters specific to endpoint type, but that's also quite smelly ( and goes against my previous point about the adapter/endpoint abstraction being quite nice!).

    I've also tried a few attempts at constructing a well-known proxy name that would force websocket use but nothing I've tried works.

    So for now I'm stumped - is there an easy way to ensure I always get a websocket transport from the javascript side. I guess ( maybe not quite as important), I'd prefer to get TCP endpoints from the other language bindings ( guess there's a reasonable performance difference in TCP vs Websocket).

    Cheers,

    A.





  • xdmxdm La Coruña, SpainAdministrators, ZeroC Staff Jose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    Hi,

    The JavaScript error is a bug in the TCP endpoint implementation, it must not attempt to connect to a TCP endpoints in the browser.

    Can you try to replace line 16830 in Ice.js

    Replace
    return !this.secure(); // We don't support SSL, we can only connect with plain TCP
    

    By
    return TcpTransceiver !== null && !this.secure();
    
  • smandysmandy Member Andy SmithOrganization: Self EmployedProject: Learning Ice
    That looks to have worked!! Thanks for quick fix.... Thought it had failed at first but then realised I needed to delete the gz file to prevent that being preferred over Ice.js as an artifact.

    Follow-up question, is there a way to prevent non-javascript clients from selecting a ws endpoint, where the adapter has both ws and tcp endpoints enabled? (e.g the python example I used for debugging would get a ws connection 50% of the time, my feel is that where possible tcp endpoints should be preferred right? ).

    Cheers,

    A.



  • dwaynedwayne St. John's, NewfoundlandMember Dwayne BooneOrganization: ZeroC, Inc.Project: Internet Communications Engine
    Hi,

    By default Ice will use a Random order for selecting the endpoint sequence used to attempt to establish a connection. You can change this behavior so that it uses Ordered instead, meaning it tries the endpoints in the order they appear in the proxy. You can do this in a few ways

    1. Call ice_endpointSelection() on the proxy and set it to Ordered
    2. If using propertyToProxy() set the <proxy>.EndpointSelection property to Ordered
    3. Set the global default selection policy to Ordered using the Ice.Default.EndpointSelection property

    See Ice documentation here: https://doc.zeroc.com/display/Doc/Connection+Management+in+Ice#ConnectionManagementinIce-EndpointOrder
  • smandysmandy Member Andy SmithOrganization: Self EmployedProject: Learning Ice
    Dwayne,

    Thanks for that - yes that'll work. Just tested it - put the TCP endpoints before the WS endpoints in the config and the Ordererd endpoint selection works!

    Thanks a lot!

    A.
  • xdmxdm La Coruña, SpainAdministrators, ZeroC Staff Jose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    Hi,

    We have updated our bower and npm packages to include this update. The fix is included in version (3.6.1-pre.1).

    Cheers,
    José
  • smandysmandy Member Andy SmithOrganization: Self EmployedProject: Learning Ice
    Ah thanks - that helps a lot.
Sign In or Register to comment.