Skip to content

Commit

Permalink
Blazor Hybrid CSS Hot Reload Fixes (#9645)
Browse files Browse the repository at this point in the history
* Stop copying content stream in .NET MAUI Blazor Windows

Fixes: #9206

microsoft/CsWinRT#670 and https://task.ms/31565319 have been marked as resolved. This PR removes the existing logic which copies the content into a memory stream, and replaces it with a call to `AsRandomAccessStream()` (`IRandomAccessStream` is still required per the `CoreWebView2` API).

I tried out CSS hot reload with this change and things are working as expected. Not sure if there's a particular behavior/technique we can use to verify the validity of this change. Spoke with @Eilon regarding this, and per his recollection things were immediately hanging, and that's why this change was necessitated.

* AutoCloseOnReadCompleteStream

* Ensure old response content is closed out for hot reload

* PR Feedback
  • Loading branch information
TanayParikh authored Aug 27, 2022
1 parent 41b1c9e commit ff3e934
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
1 change: 1 addition & 0 deletions Microsoft.Maui.sln
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiBlazorWebView.DeviceTes
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SharedSource", "SharedSource", "{4F2926C8-43AB-4328-A735-D9EAD699F81D}"
ProjectSection(SolutionItems) = preProject
src\BlazorWebView\src\SharedSource\AutoCloseOnReadCompleteStream.cs = src\BlazorWebView\src\SharedSource\AutoCloseOnReadCompleteStream.cs
src\BlazorWebView\src\SharedSource\QueryStringHelper.cs = src\BlazorWebView\src\SharedSource\QueryStringHelper.cs
src\BlazorWebView\src\SharedSource\UrlLoadingEventArgs.cs = src\BlazorWebView\src\SharedSource\UrlLoadingEventArgs.cs
src\BlazorWebView\src\SharedSource\UrlLoadingStrategy.cs = src\BlazorWebView\src\SharedSource\UrlLoadingStrategy.cs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#if WEBVIEW2_WINFORMS || WEBVIEW2_WPF

using System.IO;

namespace Microsoft.AspNetCore.Components.WebView.WebView2
{
internal class AutoCloseOnReadCompleteStream : Stream
{
private readonly Stream _baseStream;

public AutoCloseOnReadCompleteStream(Stream baseStream)
{
_baseStream = baseStream;
}

public override bool CanRead => _baseStream.CanRead;

public override bool CanSeek => _baseStream.CanSeek;

public override bool CanWrite => _baseStream.CanWrite;

public override long Length => _baseStream.Length;

public override long Position { get => _baseStream.Position; set => _baseStream.Position = value; }

public override void Flush() => _baseStream.Flush();

public override int Read(byte[] buffer, int offset, int count)
{
var bytesRead = _baseStream.Read(buffer, offset, count);

// Stream.Read only returns 0 when it has reached the end of stream
// and no further bytes are expected. Otherwise it blocks until
// one or more (and at most count) bytes can be read.
if (bytesRead == 0)
{
_baseStream.Close();
}

return bytesRead;
}

public override long Seek(long offset, SeekOrigin origin) => _baseStream.Seek(offset, origin);

public override void SetLength(long value) => _baseStream.SetLength(value);

public override void Write(byte[] buffer, int offset, int count) => _baseStream.Write(buffer, offset, count);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public static bool TryReplaceResponseContent(string contentRootRelativePath, str
if (_updatedContent.TryGetValue((assemblyName, relativePath), out var values))
{
responseStatusCode = 200;
responseContent.Close();
responseContent = new MemoryStream(values.Content);
if (!string.IsNullOrEmpty(values.ContentType))
{
Expand Down
5 changes: 4 additions & 1 deletion src/BlazorWebView/src/SharedSource/WebView2WebViewManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,10 @@ protected virtual Task HandleWebResourceRequest(CoreWebView2WebResourceRequested
StaticContentHotReloadManager.TryReplaceResponseContent(_contentRootRelativeToAppRoot, requestUri, ref statusCode, ref content, headers);

var headerString = GetHeaderString(headers);
eventArgs.Response = _coreWebView2Environment!.CreateWebResourceResponse(content, statusCode, statusMessage, headerString);

var autoCloseStream = new AutoCloseOnReadCompleteStream(content);

eventArgs.Response = _coreWebView2Environment!.CreateWebResourceResponse(autoCloseStream, statusCode, statusMessage, headerString);
}
#elif WEBVIEW2_MAUI
// No-op here because all the work is done in the derived WinUIWebViewManager
Expand Down

0 comments on commit ff3e934

Please sign in to comment.