Search code examples
javascriptandroidandroid-asynctaskokhttp

Sending GET request while simultaneously reading stream


Here's the scenario:

I'm using OkHttp to send get requests asynchronously which works great. Code as follows:

private void doGetRequest(String url){
        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request)
                .enqueue(new Callback() {

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                        Log.i(TAG,"Response: " + response);
                    }

                    @Override
                    public void onFailure(@NotNull Call call, @NotNull final IOException e) {
                        // Error
                        Log.e(TAG,"Error: " + e);
                       requireActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(requireActivity(), getResources().getString(R.string.error, e.toString()), Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                });
    }

I'm also using a AsyncTask to decode a Mjpeg stream. Inside the doInBackground function of my AsyncTask I have:

protected Long doInBackground(String... urls) {

    //Get InputStream
    URL url = new URL(urls[0]);
    HttpURLConnection connect = (HttpURLConnection) url.openConnection();
    DataInputStream inputStream = new DataInputStream (connect .getInputStream());
    mjpegStream = new MjpegInputStreamDefault(inputStream);

    //Start decoding mjpeg stream
    while (doRun) {
        publishProgress(mjpegStream.readMjpegFrame());
    }
}

The important takeaway is I'm continuously decoding a network stream over WIFI from the same device that I have to send the GET requests to.

The problem I'm having is as soon as I start the mjpeg stream my GET requests stop being received. If I stop the mjpeg stream eventually my GET requests get received assuming the timeout hasn't been reached yet.

My question is can I be sending and receiving stuff to the same device at the same time? If so why are my requests not getting received while my mjpeg stream is being received?


Solution

  • Ended up figuring out what was going on and thought I'd offer a little explanation to help future readers

    What was happening?

    Basically as you can see in this quick diagram two pieces of code where trying to use the same connection.

    My streaming code continuously takes hold of the wifi camera preventing a new connection from my send code as so:

    Diagram explaining problem

    How to avoid/solutions?

    To rectify this we need to share the connection. The stream gets updated at 50fps but the phone can do network stuff faster. This means we don't need to be processing the mjpeg stream constantly to get 50fps so having it wait every now and then as a command gets sent is fine in my case.

    So to simply put it the receiving code needs to know that it can't keep on using the connection if there's a command that's waiting to be send. There are many ways to do this and the implementation will depend on the overall design of your project.

    One good approach is to use the observables pattern. RxJava implements the best ideas of the observables pattern and more.

    Other thoughts At first I thought I would be able to use some sort of duplex approach where the sending code and receiving code could act independently but unless I'm mistaken I don't think that's possible in this case as my receiving code will always block the connection.