6 Replies Latest reply on Jul 21, 2009 10:42 AM by Mark Beierl

    Writing a custom invoker howto?

    Mark Beierl Newbie

      Sorry if I'm in the wrong forum, but I've been trying to find some information on how to extend and write my own custom invoker.

      For example, I've created a ClientFactory which returns my ClientInvoker. My ClientInvoker extends RemoteClientInvoker which requires me to implement the transport(String arg0, Object arg1, Map arg2, Marshaller arg3, UnMarshaller arg4) method.

      But where do I find out what arg0, arg1, ... etc are and how I am supposed to use them?

        • 1. Re: Writing a custom invoker howto?
          Ron Sigal Master

           

          "mbeierl" wrote:

          But where do I find out what arg0, arg1, ... etc are and how I am supposed to use them?


          Take a look at an existing transport. For example, org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(). Also, note that the transport() method is called by org.jboss.remoting.MicroRemoteClientInvoker.invoke().

          • 2. Re: Writing a custom invoker howto?
            Mark Beierl Newbie

            Thank-you. I have been sifting through the source code, but there are so many layers of abstraction that it becomes hard to follow, and not all of it is clear.

            There is no documentation on how to write a custom transport?

            • 3. Re: Writing a custom invoker howto?
              Ron Sigal Master

               

              "mbeierl" wrote:

              There is no documentation on how to write a custom transport?


              Well, there's Chapter 6. Adding a New Transport in the Remoting Guide: http://www.jboss.org/jbossremoting/docs/guide/2.5/html/index.html.

              • 4. Re: Writing a custom invoker howto?
                Mark Beierl Newbie

                Thanks. That unfortunately is where I started and didn't know what I was supposed to do with locator or config, and don't really know how to register the "nio" (or whichever url is to be used). Unfortunately I've had to put this on a bit of a back burner at work due to the learning curve.

                • 5. Re: Writing a custom invoker howto?
                  Ron Sigal Master

                  Well, I've written probably the simplest possible transport, called "test". It's dumb, but it works.

                  The client invoker is

                  package org.jboss.remoting.transport.test;
                  
                  /* imports */
                  
                  public class TestClientInvoker extends RemoteClientInvoker {
                  
                   public TestClientInvoker(InvokerLocator locator, Map configuration) {
                   super(locator, configuration);
                   }
                  
                   protected String getDefaultDataType() {
                   return SerializableMarshaller.DATATYPE;
                   }
                  
                   protected void handleConnect() throws ConnectionFailedException {
                   }
                  
                   protected void handleDisconnect() {
                   }
                  
                   protected Object transport(String sessionId, Object invocation, Map metadata, Marshaller marshaller, UnMarshaller unmarshaller)
                   throws IOException, ConnectionFailedException, ClassNotFoundException {
                   Socket s = new Socket(locator.getHost(), locator.getPort());
                   InputStream is = s.getInputStream();
                   OutputStream os = s.getOutputStream();
                   System.out.println(this + " writing " + invocation);
                   marshaller.write(invocation, os);
                   Object response = unmarshaller.read(is, metadata);
                   System.out.println(this + " returning " + response);
                   s.close();
                   return response;
                   }
                  }
                  


                  and the server invoker is

                  package org.jboss.remoting.transport.test;
                  
                  /* imports */
                  
                  public class TestServerInvoker extends ServerInvoker
                  {
                   private Thread t;
                   private ServerSocket ss;
                   private boolean running;
                   private UnMarshaller unmarshaller;
                   private Marshaller marshaller;
                  
                   public TestServerInvoker(InvokerLocator locator, Map configuration) {
                   super(locator, configuration);
                   }
                  
                   protected String getDefaultDataType() {
                   return SerializableMarshaller.DATATYPE;
                   }
                  
                   public boolean isTransportBiDirectional() {
                   return false;
                   }
                  
                   public void start() throws IOException {
                   super.start();
                   unmarshaller = MarshalFactory.getUnMarshaller(getDataType(), serializationType);
                   marshaller = MarshalFactory.getMarshaller(getDataType(), serializationType);
                   ss = new ServerSocket(locator.getPort(), -1, InetAddress.getByName(locator.getHost()));
                   t = new Thread() {
                   public void run() {
                   try {
                   while (running) {
                   Socket s = ss.accept();
                   InputStream is = s.getInputStream();
                   OutputStream os = s.getOutputStream();
                   Object request = unmarshaller.read(is, null);
                   System.out.println(TestServerInvoker.this + " read " + request);
                   Object response = invoke(request);
                   System.out.println(TestServerInvoker.this + " returning " + response);
                   marshaller.write(response, os);
                   s.close();
                   }
                   } catch (Exception e) {
                   running = false;
                   }
                   }
                   };
                   t.start();
                   running = true;
                   }
                  
                   public void stop() {
                   running = false;
                   try {
                   ss.close();
                   } catch (IOException e) {
                   }
                   }
                  }
                  


                  Note that by setting the default datatype to "serializable", I'm reusing the standard serializing marshaller and unmarshaller used by, for example, the "socket" transport.

                  Hope that helps.

                  • 6. Re: Writing a custom invoker howto?
                    Mark Beierl Newbie

                    Thanks! That does appear quite simple and is an excellent starting point for me indeed.

                    This falls under the "nice to have" components of a project that I really want to put in, but there are other features that we need to complete, so I did not have the resources to dedicate to fully strip down the micro socket client/server code to get it to this level. It's always easier to build up from a known simple base than to strip down until it appears to be the simplest.

                    Thank you once again.