question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Writing a Source to multiple Okhttp request.

See original GitHub issue

Im 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:open
  • Created 7 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

6reactions
RoryKellycommented, Aug 23, 2016

Github should have a “buy me a beer option”. Thanks!

1reaction
swankjessecommented, Aug 23, 2016

(putting synchronized outside of while is probably okay)

Read more comments on GitHub >

github_iconTop Results From Across the Web

A Guide to OkHttp - Baeldung
In this tutorial, we'll explore the basics of sending different types of HTTP requests, and receiving and interpreting HTTP responses.
Read more >
Using the OkHttp library for HTTP requests - Tutorial
OkHTTP is an open source project designed to be an efficient HTTP client. It supports the SPDY protocol. SPDY is the basis for...
Read more >
Recipes - OkHttp
We've written some recipes that demonstrate how to solve common problems with OkHttp. Read through them to learn about how everything works together....
Read more >
A complete guide to OkHttp - LogRocket Blog
post (requestBody) .build(); Call cancelableCall = client.newCall( ...
Read more >
Uploading a large file in multipart using OkHttp - Stack Overflow
Get OkHttp 2.1, and use MultipartBuilder.addFormDataPart() which takes the filename as a parameter. /** * Upload Image * * @param memberId ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found