3 Replies Latest reply on Jun 1, 2005 1:09 AM by Tom Elrod

    Object*Stream wrapping of raw socket streams

    Mats Forslöf Newbie

      Currently Object*Streams are wrapped around the raw socket streams since the ObjectOutputStream needs to be reset between ping-packets.

      To be able to forward the raw socket streams directly to the marshallers (needed if you want to implement a proprietary protocol) one could implement a new subclassed OutputStream that wraps the ObjectOutputStream if needed. In this way the ObjectOutputStream is only used when needed and has the least impact on the architecture. See code below.

      This class is then used within ServerThread.java and SocketClientInvoker.java instead of the ObjectOutputStream. The marshallers has several options, either use the ResetOutputStream directly or ask it to generate or use an ObjectOutputStream. When a reset is being issued it is propagated to the ObjectOutputStream if available. The ObjectInputStream doesn't need to be reset (it is automatically reset from the stream) so it is simply removed.

      I have run some tests and it seems to work. Do you think this is possible way to go?

      package org.jboss.remoting;
      import java.io.IOException;
      import java.io.ObjectOutputStream;
      import java.io.OutputStream;
      public class ResetOutputStream extends OutputStream
       ObjectOutputStream oout ;
       OutputStream out ;
       public ResetOutputStream(OutputStream out)
       this.out = out ;
       public void write(int value) throws IOException
       out.write(value) ;
       out.flush() ;
       public ObjectOutputStream getObjectStream() throws IOException
       if( oout == null )
       oout = new ObjectOutputStream(out) ;
       return oout ;
       public void setObjectStream(ObjectOutputStream oout)
       this.oout = oout ;
       public void reset() throws IOException
       if( oout != null )
       oout.reset() ;

        • 1. Re: Object*Stream wrapping of raw socket streams
          Tom Elrod Master

          I would most prefer to come up with a solution that passes the socket's output/inputstream directly to the marshaller without wrapping at all. I have coded up something for this that works like this, yet still able to keep the socket alive via pings. Only problem is that it is twice as slow, so need to profile it some. Will need a little more time to work on it. Will post back when get it worked out.

          I have opened a Jira issue for this at (http://jira.jboss.com/jira/browse/JBREM-111)

          • 2. Re: Object*Stream wrapping of raw socket streams
            Mats Forslöf Newbie

            There is another way to solve but it requires some refactoring to move the ping handling to intermediate filter streams. In this way, even if the marshallers wraps the stream with an Object*Stream, the intermediate streams will manage the pings.

            Stream hierarchy:

            Raw*Stream -> Buffered*Stream -> Ping*Stream (-> Object*Stream)

            The PingOutputStream wraps the raw socket output stream and adds a thin layer of ping management. The PingOutputStream contains a timer that generates a ping at predefined intervals. The ping timer is reset every time some real data is written so a ping is only generated when needed. The logic for this is located within the write(int) method and is synchronized so no other data can be written during pings. Immediately after sending the ping the stream will try to read the responding pong packet.

            A corresponding PongInputStream similiarly wraps the raw socket input stream and adds a thin layer looking for the arrival of a ping packets. If a ping packet is received it immediately replies by sending back a pong packet. Otherwise the data is just forwarded as usual.

            Since the ping/pong packets are totally managed within the intermediate filter streams there is no need to issue a reset on the Object*Streams used by the marshallers.

            • 3. Re: Object*Stream wrapping of raw socket streams
              Tom Elrod Master

              Have added the ability to customize streams for socket invoker. See http://wiki.jboss.org/wiki/Wiki.jsp?page=Remoting_customizations for details.