Support for sending InputStreams using remoting has been added to CVS and will be in the JBossRemoting 1.2.0 release. It is important to note that this feature DOES NOT copy the stream data directly from the client to the server, but is a true on demand stream. Although this is obviously slower than reading from a stream on the server that has been copied locally, it does allow for true streaming on the server. It also for better memory control by the user (verses the framework trying to copy a 3 Gig file into memory and blowing up ).
Use of this new feature is simple. From the client side, there is new method in org.jboss.remoting.Client with the signature:
public Object invoke(InputStream inputStream, Object param) throws Throwable
So from the client side, would just call invoke as done in the past, and pass the InputStream and the payload as the parameters. An example of the code from the client side would be (this is taken directly from org.jboss.test.remoting.stream.StreamingTestClient):
String param = "foobar"; File testFile = new File(fileURL.getFile()); ... Object ret = remotingClient.invoke(fileInput, param);
From the server side, will need to implement org.jboss.remoting.stream.StreamInvocationHandler instead of org.jboss.remoting.ServerInvocationHandler. StreamInvocationHandler extends ServerInvocationHandler, with the addition of one new method:
public Object handleStream(InputStream stream, Object param)
The stream passed to this method can be called on just as any regular local stream. Under the covers, the InputStream passed is really proxy to the real input stream that exists in the client's VM. Subsequent calls to the stream passed will actually be converted to calls on the real stream on the client via this proxy. If the client makes an invocation on the server passing an InputStream as the parameter and the server handler does not implement StreamInvocationhandler, an exception will be thrown to the client caller.
It is VERY IMPORTANT that the StreamInvocationHandler implementation close the InputStream when it finished reading, as will close the real stream that lives within the client VM.
By default, the stream server which runs within the client JVM uses the following values for its locator uri:
transport - socket
host - tries to first get local host name and if that fails, the local ip (if that fails, localhost).
port - 5405
Currently, the only way to override these settings is to set the following system properties (either via JVM arguments or via System.setProperty() method):
remoting.stream.transport - sets the transport type (rmi, http, socket, etc.)
remoting.stream.host - host name or ip address to use
remoting.stream.port - the port to listen on
These properties are important because currently the only way for a target server to get the stream data from the stream server (running within the client JVM) is to have the server socket make the invocation an a new connection back to the client (see issues below).
This is a first pass at the implementation and needs some work in regards to optimizations and configuration. In particular, there is a remoting server that is started to service request from the stream proxy on the target server for data from the original stream. This raises an issue with the current transports, since the client will have to accept calls for the original stream on a different socket. This may be difficult when control over the client's environment (including firewalls) may not be available. A bi-directional transport, based of the JMS UIL2 invocation layer, is planned for remoting which will allow calls from the server to go over the same socket connection established by the client to the server (JBREM-91). This will make communications back to client much simpler from this standpoint. However, I won't be able to get to this transport implementation for a while, so if you are interested in getting it done sooner, please e-mail me (tom dat jboss).