Reputation: 36001
I'd like to do something similar to the example posted in restlet's site (first applicaiton) - with one difference:
I want to stream data - not use primitive types - using an interface.
I want to define some kind of an interface between the client and the server, stream data between them and let restlet handle transmit the data seamlessly.
Example of what I have in mind:
interface Streaming {
InputStream startStream(String streamId);
}
When the client invokes a call, it starts reading from the inputstream. The server receives the call and starts providing the stream by creating an inputstream (for example, a video file, or just some raw data). Restlet should be reading from the inputstream on the server side and provide the data as an inputstream on the client side.
Any idea how can I achieve this? A code sample or link to one would be great. Thanks.
Upvotes: 1
Views: 915
Reputation: 36001
Below's an example code of what I learned so far - an interface with streaming capavilities and a client-server streaming example.
I haven't yet added parameters to the interface and it's only download - no upload yet.
Interface:
public interface DownloadResource {
public ReadableRepresentation download();
}
Interface with protocol: (separation between logic and technology):
public interface DownloadResourceProtocol extends DownloadResource {
@Get
@Override
public ReadableRepresentation download();
}
Client:
ClientResource cr = new ClientResource("http://10.0.2.2:8888/download/");
cr.setRequestEntityBuffering(true);
DownloadResource downloadResource = cr.wrap(DownloadResourceProtocol.class);
// Remote invocation - seamless:
Representation representation = downloadResource.download();
// Using data:
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
IOUtils.copy(representation.getStream(), byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
Log.i("Byte array: " + Arrays.toString(byteArray));
Server:
public class DownloadResourceImpl extends ServerResource implements DownloadResourceProtocol {
@Override
public ReadableRepresentation download() {
InputStreamChannel inputStreamChannel;
try {
inputStreamChannel = new InputStreamChannel(new ByteArrayInputStream(new byte[]{1,2,3,4,5,6,7,8,9,10}));
return new ReadableRepresentation(inputStreamChannel, MediaType.ALL);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Configuration:
public class SampleApplication extends Application {
@Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/download/", DownloadResourceImpl.class);
return router;
}
}
Upvotes: 1
Reputation: 2712
Not sure this addresses your problem completely, but one approach is to create a thread that streams data back to the client using ReadableRepresentation and a Pipe.
Create a pipe:
Pipe pipe = Pipe.open();
Create a representation like this:
ReadableRepresentation r = new ReadableRepresentation(pipe.source(), mediatype);
Start a separate thread that writes batches of bytes to the pipe like this:
pipe.sink().write(ByteBuffer.wrap(someBytes));
return the representation to the client.
Upvotes: 0