Closed cdaman123 closed 5 months ago
Sorry but can't justify spending the time on this - it seems the issue resides in the integration between both services and not specifically in Spring Framework. We can reopen this issue if you manage to provide a minimal sample application (something we can download or git clone and run) that only involves Spring and produces invalid SSE streams that browsers will not accept.
Hi
@bclozel thanks for reply. I tried Spring's SseEmitter
with JavaScript's default EventSource
, and it worked as expected.
However, I noticed that SseEventBuilder.build()
in Spring creates three separate packets for a single event containing only data. For instance, if I try to send an event with the value "Event at: 2024-05-22T12:10:50.985317511", the returned SetSseEventBuilder.build()
has a size of 3, containing "data:", "Event at: 2024-05-22T12:10:50.985317511", and "\n\n". This behavior causes issues with my custom event handling logic.
Code can be found below: https://github.com/spring-projects/spring-framework/blob/dae4366325f645fd83b035e229027549dcf61c50/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java#L199-L281
sample application repo : https://github.com/cdaman123/spring-sse-sample-app
I tried Spring's SseEmitter with JavaScript's default EventSource, and it worked as expected.
This points to an issue with your integration, not in Spring Framework.
However, I noticed that SseEventBuilder.build() in Spring creates three separate packets for a single event containing only data.
We're concatenating String instances, but in the end this is flushed at once on the network so this shouldn't be a problem.
We're concatenating String instances, but in the end this is flushed at once on the network so this shouldn't be a problem.
@bclozel I checked the new version of spring-framework, all chunks are flushed at once, but strings are not concatenated instead of stored in a SET
.
My question is why they are stored in a SET
instead of being appended to a string.
I think this issue has run its course. You did not provide any sample application showing our SSE support having a problem. We can't justify spending the time to discuss the details of the implementation unless this is an enhancement request.
@bclozel @cdaman123 I was troubleshooting something else with SSE and noticed this behavior in the logging/debugging. I think it's possible this was fixed in 6.0.12 with this change (edit - that said, not sure eagerly flushing should create a correctness problem really but maybe for the original example)
Which explains the
I checked the new version of spring-framework, all chunks are flushed at once
FWIW the issue I ran into (just dropping it here but it's pretty unrelated but maybe someone will find this in a search) is that I was trying to re-use an instance of SseEventBuilder
i.e. one event broadcast to many emitters. The sort of non-obvious part here was that the implementation of SseEventBuilder#build
mutates the contents therefore you cannot re-use the same event/builder to multiple calls of send
. See implementation here, resulted in extra newline characters which confused some clients.
@ryanrupp I checked this behavior with spring version 6.0.12 but it is not completely fixed, just due to flushing all chunk at once, at client side the frequency of complete event increased but not completely fixed.
@bclozel any plan for consider this as enhancement request?
@cdaman123 there's still nothing actionable for us in this issue. This was first reported as a bug because of broken chunks so I don't understand which enhancement you're talking about. I think @ryanrupp is mentioning a different case as your initial sample was not reusing the same instance of SseEventBuilder
for multiple messages.
Hi @bclozel I am talking about sending a complete event as a single string ('data:message\n\n'
)instead of breaking them in 'data:'
, 'message'
and '\n\n'
.
This should be the case already. See ResponseBodyEmitter
and:
/**
* Write a set of data and MediaType pairs in a batch.
* <p>Compared to {@link #send(Object, MediaType)}, this batches the write operations
* and flushes to the network at the end.
* @param items the object and media type pairs to write
* @throws IOException raised when an I/O error occurs
* @throws java.lang.IllegalStateException wraps any other errors
* @since 6.0.12
*/
public synchronized void send(Set<DataWithMediaType> items) throws IOException {
I have an SSE endpoint in flask which emit SSE data chunks which are according MDN standards which ends in two
\n
characters, and when I received them on my frontend they received on the same format.But I need to write a proxy for the same endpoint in spring boot which make a call on flask SSE endpoint and return same events to client. When I hit that endpoint using the same script, I received uneven chunks, for example in some chunks
data:
received and the value of that event received in the next chunk.Please help me with this issue.
Sample Flask APP
cmd to run above flask application:
Sample client :
Java spring boot controller with
SseEmitter
:Above code block have two endpoints, one which make a call on flask endpoint and emit data received from that and another endpoint generate data and omit to client.
When I make a call on flask endpoint directly I received complete chunks but when I make call on any of the java endpoint I received uneven broken chunks.
Result for all endpoints:
Please help me how to fix this issue.