Writing a Source to multiple Okhttp request.
See original GitHub issueIm aware this is a strange requirement but hear me out. Lets imagine I’m reading binary data from a hardware sensor, like a microphone, so I wrap that in a Source. Then I’m sending this data across the wire via Okhttp.
Source source = AudioSource.getThreeSeconds();
server.sendDataToMicrosoftVoiceRecogniser(source, callback);
Because we want to stream the data when the web request starts. we use the Recipe for post streaming from Okhttp.
void sendDataToMicrosoftVoiceRecogniser(Source sources, Callback callback){
RequestBody requestBody = new RequestBody() {
@Override public MediaType contentType() {
return MediaType.parse("application/octet-stream");
}
@Override public void writeTo(final BufferedSink sink) throws IOException {
sink.write(source);
}
};
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)
.build();
Response response = client.newCall(request). enqueue(callback);
...
}
How can I stream the same data to multiple API’s in parallel. I.E
Source source = AudioSource.getSource();
server.sendDataToMicrosoftVoiceRecogniser(source, callback);
server.sendDataToMyServer(source, callback);
The first request consumes the bytes then the second receives random data. I have managed to get this to work by:
public static Source tee(final Source source, final Buffer copy) {
return new Source() {
@Override public long read(final Buffer sink, final long byteCount) throws IOException {
final long bytesRead = source.read(sink, byteCount);
if (bytesRead > 0) {
sink.copyTo(copy, sink.size() - bytesRead, bytesRead);
}
return bytesRead;
}
@Override public Timeout timeout() {
return source.timeout();
}
@Override public void close() throws IOException {
source.close();
}
};
}
final Source source = AudioSource.getSource();
final Buffer buffer = new Buffer();
final Source speechToText = tee(source, trigger);
server.sendDataToMicrosoftVoiceRecogniser(speechToText, callback);
server.sendDataToMyServer(source, buffer);
This has its problems, as if the web requests consume data at different speeds the buffer can be emptied, I get round this by knowing how much data “server.sendDataToMyServer” expects.
Any ideas on how I could do this? I suppose what I really need is a Mirrored source that buffers the bytes emitted from another Source until they are consumed again.
Issue Analytics
- State:
- Created 7 years ago
- Comments:11 (6 by maintainers)
Github should have a “buy me a beer option”. Thanks!
(putting
synchronized
outside ofwhile
is probably okay)