New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Buffering issues when returning an SSE response #55654
Comments
That's expected, SignalR's SSE implementation has to do the same. Are you still having issues, or are you just trying to understand what component was causing the problem? |
I'm just trying to understand how things work under the hood, especially when switching between Kestrel and IIS. It seems that when running under Kestrel, there's no buffering involved? The SSE stream is being returned in chunks, unlike in IIS where everything's returned at once. |
Here's the implementation for IIS: aspnetcore/src/Servers/IIS/IIS/src/Core/IISHttpContext.FeatureCollection.cs Lines 498 to 508 in 3307bf6
Kestrel we control the entire stack and there's not explicit buffering (there's a "write behind buffer", but it's flushed immediately). |
Thank you @davidfowl for the information! This is what I needed. Am I correct in understanding that IIS buffering cannot be disabled from IIS? Compression can be though? And finally - can one control how buffering is done in IIS, like tuning the buffer size for example? In Kestrel, there's KestrelServerLimits.MaxResponseBufferSize - How does that come into the picture? |
That's right. AFAIK you have to call this API.
It doesn't. This is about internal buffer sizes, not the operation of buffering content. |
Closing this as I got what I was looking for. Thanks for the clarifications! If anyone wouldn't mind sharing internally how IIS response buffering works, that'd be cool 👍 |
In the controller I'm basically returning a server-sent event by manually setting the content type, starting the response with
Response.StartAsync(cancellationToken)
and then directly writing data toResponse.Body
, finishing with aResponse.CompleteAsync()
. For additional context - another service is returning the SSE in aStream
, so I'm effectively just callingStream.CopyToAsync(Response.Body, cancellationToken)
The issue I'm facing is that when the above code runs on Kestrel, the events in the stream are immediately returned and it seems like no buffering is being done.
The moment I switch to IIS or IIS Express though, something weird is going on as the client receives the response after writing to the response body has finished.
After investigating, I thought the Dynamic Response Caching module for IIS was at fault here. But it turns out that it was actually not installed on the system as shown here:
If Dynamic Response Caching is not involved, what else is going on that would screw up the SSE like that? If I have to follow common sense, does the above mean that:
I find it weird that Kestrel would have no response body buffering by default. Is this really the case? If not, what's going on here? Am I perhaps implementing SSE in a weird way?
Calling
HttpContext!.Features.Get<IHttpResponseBodyFeature>()!.DisableBuffering()
fixes the issue when running under IIS/IIS Express..NET Version: 8.0.300-preview.24203.14
The text was updated successfully, but these errors were encountered: