launchdarkly / okhttp-eventsource

Server-sent events (SSE) client implementation for Java, based on OkHttp: http://javadoc.io/doc/com.launchdarkly/okhttp-eventsource
Other
143 stars 31 forks source link

Supporting Content-Encoding #65

Closed shengLin-alex closed 2 years ago

shengLin-alex commented 2 years ago

Hello, I'm using this project with a simple SSE demo. The server backend is .NET 5 WebAPI, when response compression is disabled, everything works fine, but when compression is on, onMessage cannot be triggered.

Here's my connection code:

    private void connectSSE(String token) {
        var headerBuilder = new Headers.Builder();
        headerBuilder.add("Accept-Encoding", "br, gzip, deflate");
        headerBuilder.add("Accept", "text/event-stream");

        var url = "http://localhost:8888/events";
        var eventSourceBuilder = new EventSource.Builder(new SimpleEventHandler(), URI.create(url))
                .headers(headerBuilder.build())
                .connectTimeout(Duration.ofSeconds(10));

        try (var eventSource = eventSourceBuilder.build()) {
            eventSource.start();

            TimeUnit.MINUTES.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
eli-darkly commented 2 years ago

I think that this is an issue with the backend, rather than the client. One way to verify whether my guess is right would be to load the same SSE URL from JavaScript code in a browser (like, just do new EventSource("http://localhost:8888/events")), look in the browser's Network tab, and see if it's showing any event traffic. Or, just do curl --raw http://localhost:8888/events from a Linux command line and see if the events are showing up as they're sent. If not, then the problem is not on the client side.

The client that we're using here is OkHttp, which handles gzip compression transparently. However, often when you enable gzip on a server, it will want to buffer the responses by default - since compression algorithms of this kind work best if you already know what the most frequently used characters are before you start doing the compression, which assumes that you've already seen more than a tiny piece of the data. And SSE can't work if the response is being buffered, no matter what client implementation you're using.

Of course, without access to your server, I have no way to know if that's the issue - and if I'm right, I can't give you any advice on how to disable buffering on your server, since that's a general issue that's outside the scope of maintaining the okhttp-eventsource code. And, again, we did not write the OkHttp client implementation so I'm not sure how much we would be able to do about this in any case. Still, please let me know what you see from either of the tests I mentioned above.

shengLin-alex commented 2 years ago

I think i found the reason why this approach not work, just remove headerBuilder.add("Accept-Encoding", "br, gzip, deflate");