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

OPEN state but no messages #68

Closed rwst closed 2 years ago

rwst commented 2 years ago

The stream using curl:

curl https://lichess.org/api/board/game/stream/5AbVbnlV -H "Authorization: Bearer xyz"
{"id":"5AbVbnlV","variant":{"key":"chess960","name":"Chess960","short":"960"},"clock":null,"speed":"correspondence","perf":{"name":"Chess960"},"rated":false,"createdAt":1650300721078,"white":{"id":"drdisentangle","name":"DrDisentangle","title":null,"rating":1543,"provisional":true},"black":{"aiLevel":1},"initialFen":"nqrknbbr/pppppppp/8/8/8/8/PPPPPPPP/NQRKNBBR w KQkq - 0 1","type":"gameFull","state":{"type":"gameState","moves":"e2e4 c7c5 f1c4 e8d6 e4e5 a8b6 e5d6 e7d6 c4b3 d6d5 f2f4 h7h6 g1e3 g8h7 e1f3 b6c4 b3c4 h7e4 h1e1 b8d6 c4b5 d6g6 d2d3 d5d4 d3e4 g6g2 b5e2 f8d6","wtime":2147483647,"btime":2147483647,"winc":0,"binc":0,"status":"started"}}

{"type":"gameState","moves":"e2e4 c7c5 f1c4 e8d6 e4e5 a8b6 e5d6 e7d6 c4b3 d6d5 f2f4 h7h6 g1e3 g8h7 e1f3 b6c4 b3c4 h7e4 h1e1 b8d6 c4b5 d6g6 d2d3 d5d4 d3e4 g6g2 b5e2 f8d6 e4e5","wtime":2147483647,"btime":2147483647,"winc":0,"binc":0,"status":"started"}
{"type":"gameState","moves":"e2e4 c7c5 f1c4 e8d6 e4e5 a8b6 e5d6 e7d6 c4b3 d6d5 f2f4 h7h6 g1e3 g8h7 e1f3 b6c4 b3c4 h7e4 h1e1 b8d6 c4b5 d6g6 d2d3 d5d4 d3e4 g6g2 b5e2 f8d6 e4e5 d8h8","wtime":2147483647,"btime":2147483647,"winc":0,"binc":0,"status":"started"}

As you can see there is one initial message and one message after each move, which I can trigger manually. There are also empty lines. Now my Kotlin code is:

    @RequiresApi(Build.VERSION_CODES.O)
    fun getBoardGameStream(gameId: String) {
        val eventHandler = GameStreamEventHandler()
        val url = RetrofitHelper.baseUrl + String.format("api/board/game/stream/$gameId");
        Log.i(TAG, "url = $url")
        val headers: Headers = Headers.headersOf("Authorization", "Bearer $theToken")
        val builder = EventSource.Builder(eventHandler, URI.create(url))
            .reconnectTime(Duration.ofMillis(3000))
            .headers(headers)

        val eventSource = builder.build()
        eventSource.start()
        runBlocking() {
            delay(5000L)
        }
        Log.i(TAG, "eventSource: ${eventSource.state}, ${eventSource.uri}, ${eventSource.lastEventId}")
    }

This gives me the following log:

I/LichessService: url = https://lichess.org/api/board/game/stream/5AbVbnlV
W/System.err: [main] INFO com.launchdarkly.eventsource.EventSource - Starting EventSource client using URI: https://lichess.org/api/board/game/stream/5AbVbnlV
W/System.err: [okhttp-eventsource-stream-[]-0] INFO com.launchdarkly.eventsource.EventSource - Connected to EventSource stream.
I/SSEventHandler: onOpen
I/LichessService: eventSource: OPEN, https://lichess.org/api/board/game/stream/5AbVbnlV, null

Nothing more, even if I trigger a move. Note the null lastEventId that I get after 5s. The GameStreamEventHandler=SSEventHandler is simply overriding EventHandler and logs every callback.

My question: how can I debug further? In the end I may need to copy and tweak your code, but maybe you have an idea?

eli-darkly commented 2 years ago

Is this definitely an SSE stream? I ask because the curl output in your description does not look like one. It's showing a series of text lines, each of which is a JSON object, but that is not the SSE format. An SSE event would have, at a minimum, a line starting with data: and would be terminated by two linefeeds.

https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events

rwst commented 2 years ago

That solves it, many thanks. This is not an SSE stream. As a suggestion maybe your code can give a hint when it encounters messages without data.

Anugrahasb commented 1 year ago

I am using the library 'okhttp-eventsource' version 2.5.0 from https://github.com/launchdarkly/okhttp-eventsource/releases/tag/2.5.0 for SSE in Android. I am facing an issue where I can connect and receive signals, but after some time (around 5 minutes), the signals stop coming to my end, even if the backend is sending the signals and the SSE connection remains open.