Streaming an HTTP response in Blazor WebAssembly
Blazor WebAssembly relies on the browser to execute web requests. Every call you make using HttpClient
is executed using the fetch
API (documentation) provided by the browser.
Web Browsers support streaming the response of a fetch request using the readable streams. This allows reading the response chunk by chunk without waiting for the last byte of the response. You can also cancel the request as soon as you get the data you want.
The response streaming is not enabled by default. You must enable it explicitly per request by setting 2 options:
HttpRequestMessage.SetBrowserResponseStreamingEnabled(true)
indicates to use a ReadableStream so the response is streamableHttpCompletionOption.ResponseHeadersRead
indicates the operation should complete as soon as a response is available and headers are read. The content is not read yet.
Here's the full example:
Razor
@page "/"
@inject HttpClient HttpClient
<h1>HTTP streaming</h1>
<button type="button" @onclick="Get">Get data</button>
<button type="button" @onclick="Stop">Cancel</button>
<p>Bytes read: @byteCount</p>
@code{
int byteCount;
CancellationTokenSource cts;
async Task Get()
{
cts = new CancellationTokenSource();
using var request = new HttpRequestMessage(HttpMethod.Get, "stream");
request.SetBrowserResponseStreamingEnabled(true); // Enable response streaming
// Be sure to use HttpCompletionOption.ResponseHeadersRead
using var response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
using var stream = await response.Content.ReadAsStreamAsync();
// Read the response chunk by chunk and count the number of bytes
var bytes = new byte[10];
while (!cts.Token.IsCancellationRequested)
{
var read = await stream.ReadAsync(bytes, cts.Token);
if (read == 0) // End of stream
return;
byteCount += read;
// Update the UI
StateHasChanged();
await Task.Delay(1);
}
}
// Cancel the request
void Stop() => cts?.Cancel();
}
#Additional resources
- WebAssemblyHttpRequestMessageExtensions.SetBrowserResponseStreamingEnabled(HttpRequestMessage, Boolean) Method
- HttpCompletionOption Enum
- ReadableStream
Do you have a question or a suggestion about this post? Contact me!
Enjoy this blog?💖 Sponsor on GitHub