Zane W
01/19/2024, 2:39 AMval res = serviceClient.post(url) {
headers {
append(HttpHeaders.Accept, "text/event-stream")
}
contentType(ContentType.Application.Json)
setBody(requestBody)
}
val channel: ByteReadChannel = res.body()
while (!channel.isClosedForRead) {
channel.readUTF8Line()?.let { line ->
// process SSE chunk
}
}
2. Does the above code behave the same in Ktor 2.3.x and Ktor 3.0?
i saw the [original request of implementing SSE](https://github.com/ktorio/ktor/issues/1517), and some one pointed out, it is impossible to implement true SSE with Ktor 2.3.x, and it's fixed only in Ktor 3.0. Does that mean, with Ktor 3.x, the above code function as expected?Aleksei Tirman [JB]
01/19/2024, 7:08 AMZane W
01/19/2024, 7:13 AMSo, as SSE is a very simple protocol, I tried to implement this, but it turns out it's impossible to implement, because most (if not all) of the Ktor client engines buffer the responses. This is fine for streaming file downloads, etc., but to implement SSE it has to be possible to stream the response byte-for-byte, one-by-one.
Ktor itself has an API to read a single byte (And this is only fixed in 3.0, so supposedly, the code above in Ktor 2.3.x doesn't really work, it buffers and output larger chunks. Isn't it?), so it's possible to write something that LOOKS like it will work, but it won't work, because the client engines will suspend until they fill an arbitrary buffer (or the connection is closed).ByteReadChannel.readByte
Aleksei Tirman [JB]
01/19/2024, 7:36 AMval request = serviceClient.preparePost(url) {
headers {
append(HttpHeaders.Accept, "text/event-stream")
}
// ...
}
request.execute { res ->
val channel: ByteReadChannel = res.body()
while (!channel.isClosedForRead) {
channel.readUTF8Line()?.let { line ->
println(line)
}
}
}
Nick
01/30/2024, 5:42 AMHTTP/1.1 200 OK
Vary: Origin
Content-Type: text/event-stream <-------
Cache-Control: no-store
Connection: keep-alive
Content-Type: text/event-stream <-------
transfer-encoding: chunked
This causes the following exception in the JS client:
SSEException: Expected Content-Type text/event-stream but was: text/event-stream, text/event-stream
This comes from installing the SSE
plugin on the client/server and sending an sse response as follows:
sse {
send("Hello")
}
Aleksei Tirman [JB]
01/30/2024, 7:37 AM3.0.0-beta-1-eap-879
?Nick
01/30/2024, 7:42 AMAleksei Tirman [JB]
01/30/2024, 7:43 AMNick
02/01/2024, 3:04 AM3.0.0-beta-2-eap-884
.Nick
02/01/2024, 4:22 AMSSEException: Expected Content-Type text/event-stream but was: application/json
when executing a get
with the client to an endpoint that returns json.
I'd be surprised if this were the expected behavior.Aleksei Tirman [JB]
02/01/2024, 7:49 AMI'm also seeing another issue where a client that has SSE installed cannot be used for normal get/post/etc.This problem is known (https://youtrack.jetbrains.com/issue/KTOR-6614).
Nick
02/02/2024, 3:10 AMNick
02/02/2024, 3:17 AMAleksei Tirman [JB]
02/02/2024, 7:40 AM