Hoppie
Hoppie

Reputation: 329

How do I disconnect a OkHttp3 sse connection?

Problem:

I'm trying to create a client that can receive events from a server using SSE (server-sent events) and I'm using OkHttp3 to do that, combined with the OkHttp3-sse library (com.squareup.okhttp3:okhttp:4.1.0 & com.squareup.okhttp3:okhttp-sse:4.1.0). I am able to connect to the server and receive the events just fine, but at some point in time, I want to disconnect the client and shutdown my application. That is were the problem is. The connection gets closed, but the application is not shutting down, probably due to the ConnectionPool not closing.

Attempted:

As there is hardly any documentation on the use of the OkHttp3-sse library, I have tried to reverse engineer from the code what to do. I have tried to:

Finding:

As an alternative, I have looked at https://github.com/heremaps/oksse which has the RealServerSentEvent.close() call which is doing what I expect. It closes the connection and stops all threads allowing the application to shutdown completely. I have looked at the implementation of the RealServerSentEvent class to see how the implementation differs from RealEventSource. I think the difference is in the conditions of the read loop:

RealEventSource line https://github.com/square/okhttp/blob/master/okhttp-sse/src/main/java/okhttp3/internal/sse/RealEventSource.kt#L75:

      try {
        listener.onOpen(this, response)
        while (reader.processNextEvent()) {
        }
      } catch (e: Exception) {
        listener.onFailure(this, e, response)
        return
      }

compares to RealServerSentEvent line https://github.com/heremaps/oksse/blob/master/src/main/java/com/here/oksse/RealServerSentEvent.java#L94:

            listener.onOpen(this, response);

            //noinspection StatementWithEmptyBody
            while (call != null && !call.isCanceled() && sseReader.read()) {
            }

The OkSSE implementation includes the condition if the call.isCanceled() in the loop, where as the OkHttp3-sse does not. I suspect this is causing OkHttp3-sse not to exit, but I might be mistaken.

Or, am I overseeing the intended way of disconnecting?

Upvotes: 8

Views: 3983

Answers (2)

Hoppie
Hoppie

Reputation: 329

Eventually I found the connection can be gracefully shut down by calling:

eventSource.cancel();
client.dispatcher().executorService().shutdown();

As this does not require any changes to the library, I closed the bug report.

Upvotes: 7

Jesse Wilson
Jesse Wilson

Reputation: 40623

You're using the API correctly and OkHttp should be causing the read to fail with an IOException when the call is canceled. Obviously this isn't happening which I read as a bug in OkHttp.

Next steps: report the bug to OkHttp. If you can do so with an executable test case I'll make sure this gets fixed real soon.

Upvotes: 3

Related Questions