0 Replies Latest reply on May 31, 2006 3:28 AM by Ron Sigal

    Configuring multiplex Clients and callback Connectors

    Ron Sigal Master

      I would like to respond in the public forum to an issue expressed in the following e-mail from Michael Voß . It concerns the configuration of a Client and callback Connector using the sslmultiplex transport.


      > I have discovered another problem but I am not sure if it is about Linux/Windows differences or the cpu speed or sth. else:
      > Regarding the client:
      >
      > On a Unix system I first build up the client object and run connect() and then build up and start the connector so that the program works fine.
      > The other way round I get the exception: java.lang.InvocationTargetException ... caused by java.lang.RuntimeException: Address already in use when adding a callback listener to the client object
      > + also getting Exception in thread "Timer-2" java.lang.NullPointerException
      >
      > Running the client application in Windows I need to build up and run the connector object first and then the client object to run properly
      > The other way round I get the exception: java.lang.InvocationTargetException ... caused by java.lang.RuntimeException: Connection refused by Client client = new Client(locator, "subsys", configuration);
      >
      >
      > I use sslmultiplex
      > How already mentioned I do not know the cause for this but I can not imagine that it is about Windows or Unix
      >
      > What do you think about it?
      >

      The multiplex and sslmultiplex transports have been in flux recently (as has been much of Remoting), and the primary solution is to use the newest version. With CVS version JBossRemoting_2_0_0_beta_2 I was able to get Michael's example to work, in all of its variations, with only a single code modification (other than a change of ports), and I want to talk about that modification because it concerns the admittedly complicated invoker group rules.

      Michael creates a Connector with InvokerLocator, say, sslmultiplex://localhost:2001, and then creates, in some order, a Client and a callback Connector. Simplifying somewhat, suppose the Client is set up so:

       configuration.put(Multiplex.MULTIPLEX_BIND_HOST, "localhost");
       configuration.put(Multiplex.MULTIPLEX_BIND_PORT, "3001");
       client = new Client("sslmultiplex://localhost:2001", configuration);
       client.connect();
      


      and then the Connector is set up so:

       connector = new Connector("sslmultiplex://localhost:3001", configuration);
       connector.create();
       SSLMultiplexServerInvoker invoker=(SSLMultiplexServerInvoker)connector.getServerInvoker();
       invoker.setClientConnectAddress("localhost");
       invoker.setClientConnectPort(2001);
       connector.start();
      


      The result of starting the callback Connector will be: java.net.BindException: Address already in use.

      The reason is that the InvokerLocator "sslmultiplex://localhost:3001" gives MultiplexServerInvoker no clue that it is meant to share a connection with a MultiplexClientInvoker. In the absence of any hint to the contrary, it will create, during the call to Connector.create(), a "real" server socket, i.e., MasterServerSocket, instead of a VirtualServerSocket, and try to bind it to port 3001. This behavior is determined by server rule 4.

      One solution is to rewrite the callback Connector code as follows:

       configuration.put(Multiplex.MULTIPLEX_CONNECT_HOST, "localhost");
       configuration.put(Multiplex.MULTIPLEX_CONNECT_PORT, "2001");
       connector = new Connector("sslmultiplex://localhost:3001", configuration);
       connector.create();
       connector.start();
      


      The presence of the "connect" information tells MultiplexServerInvoker to look for an existing invoker group to join, and it will create a VirtualServerSocket that uses the real socket bound to port 3001.

      This example suggests that it might be reasonable to change the invoker group rules so that a MultiplexServerInvoker will try to create VirtualServerSocket bound to a given port if it finds that port in use. It's something to think about.