0

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?

Jameson
  • 170
  • 1
  • 11
  • not trying to be funny, but how much RxJava do you know? since you're using AsyncTask I'm going to assume 0, so you may want to start learning RxJava, particularly about observables, and some functions like .zip or .merge, or BiFunctions. unfortunately that'll likely be a full rewrite of your existing code, therefore it is not a simple stack overflow answer. good luck – TooManyEduardos Nov 22 '19 at 04:17
  • I'd like to think I have a bit of experience. I know my way around observables, but I'm not sure exactly how I want to structure things. I think the issue is blocking related because I'm sharing my connection poorly. – Jameson Nov 22 '19 at 07:06
  • `why are my requests not getting received while my mjpeg stream is being received?`. Good question. I have not an answer yet but would like you know that the problem is interesting. – blackapps Nov 22 '19 at 10:30
  • 1
    so, if you use RxJava you can fire off both network calls at the same time, and (depending on your needs) you can either wait for both to finish, or just do things as they are coming (the stream, if its a real stream would last way longer). your current issue is likely being caused by the fact that you're calling these background threads from the main thread, after the "doGetRequest" completes – TooManyEduardos Nov 22 '19 at 15:55
  • Thanks that helps a bit, There's actually more going on than meets the eye at first. Firstly the get request is something I tried from another stack overflow answer https://stackoverflow.com/questions/34967505/android-okhttp-asynchronous-calls It's meant to send the requests asynchronous but at least in my case it just refuses to send requests after ~8 times. – Jameson Nov 24 '19 at 21:39
  • Also it's worth noting that I care 0% about the response from the get request. – Jameson Nov 24 '19 at 21:40

1 Answers1

1

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.

Jameson
  • 170
  • 1
  • 11