Blazor Server Dll loading progress [duplicate] - c#

I have a Blazor server-side application that could be viewed by users from remote regions with slower internet connections to the server. After typing the URL in the browser, it displays a blank screen for a few seconds and then my loading animation shows up, and then content loads.
Loading animation is what I have on the page while waiting for the API call to return data. Nothing special. However, what about the blank screen? Is that when the browser is attempting to establish SignalR connection to the server?
I am OK with the slow speed, but is there a way to also use a loading animation while this connection is established? A blank screen is not ideal at all.
Thanks for any advice.

How about change the loading indicator to be visible from start and if you have a bool field it will be true initially. That way as soon as page is displayed you would see the loading screen and after the API data is fetched you can mark it as hidden.
Some example code for a razor below:
#if (IsLoading)
{
<div class="loader">Loading...</div>
}
#code {
public bool IsLoading { get; set; } = true;
protected override async Task OnInitializedAsync()
{
await _apiClient.Get(...);
IsLoading = false;
}
}

Related

Blazor web assembly: cannot stop img streaming when leaving page

I'm having a problem with the disposing of a Blazor Web Assembly page containing an img tag having as src the path of a camera stream. In short, when I leave the page, the stream is not interrupted and remains active, wasting bandwitdh and resources.
I've the following Blazor page:
#page "/counter"
#implements IDisposable
<img src="#imgSrc" />
<br />
<button #onclick="OnBtnClicked">Hide/Show Image</button>
#code {
private string imgSrc;
private string imgPath = "http://192.168.x.x/axis-cgi/mjpg/video.cgi";
protected override async void OnInitialized() {
imgsrc=imgPath;
}
private void OnBtnClicked() {
imgsrc=(imgSrc.Equals("") ? imgPath : "");
StateHasChanged();
}
public void Dispose() {
Console.WriteLine("Disposing!");
}
}
When I enter counter page the streaming starts, and I can see badwitdh increasing from 0Mbps to about 4Mbps from Task Manager; if I click the button to "hide" the image, the bandwitdh goes back to 0Mbps.
However, if while the live stream is being shown I navigate e.g. to Home page, the bandwitdh remains to 4Mbps. At this point, even if I go back to the counter page and click the button to hide the image, even if the image correctly hides, the bandwitdh remains 4Mbps.
It's like an underlying connection remains active and Blazor has no means to stop it, and disposing the page does not stop it either.
Do you know if there is a clean way to stop this stream?
please note calling OnBtnClicked from inside Dispose() yield no result, as if once entered in Dispose(), user interface is no more updated and thus the instructions have no effect
There actually is a very dirty way to solve this, managing manually all the navigation related stuff from the main layout page and performing some cleaning before disposing the page... but the use of this workaround force me to setup a complex structure just to fix this problem.
Tests have been performed on
Mozilla Firefox 94.0.2 64-bit
Microsoft Edge 96.0.1054.41 64-bit
Google Chrome 96.0.4664.45 64-bit
I've tried with Blazor Server as well (same .razor page code) and the problem is still there.
Thank you very much!
EDIT: I've added browser used for testing and I have to remove the username and password from the Url since otherwise Chrome and Edge would block the request. I've also added Blazor Server test result.

How do I keep the CefSharp browser from opening 2 windows when following an html link?

I'm using the CefSharp browser to display the contents of emails. I pull the BodyHtmlText out of a parsed email and load it into the browser using browser.LoadHtml(BodyHtmlText, "http:\\pixemail.com\");. I want links in the BodyHtmlText to open in the system default browser, so I've implemented a BrowserRequestHandler and tell the browser to use it by setting browser.RequestHandler = BrowserRequestHandler;
This works well, except when the link anchor tag has a <a...target="_blank">. When it does, clicking the link opens two new browser windows; one with the link target page as expected, and another that is just empty. BrowserRequestHandler.OnBeforeBrowse() is called only once, even though 2 windows are opened.
How do I get rid of the empty window?
If I don't install a BrowserRequestHandler, links with target="_blank" open in a new browser without the extra window, but regular links (without target="_blank"), open in the app's CefSharp browser window, which I don't want. If, in BrowserRequestHandler.OnBeforeBrowse() I could detect that the link had target="_blank", I could let the CefBrowser handle it and get the behavior I want. Or is there some other way to configure and use the CefSharp browser to get the behavior I want?
A slightly modified version of CefSharp.MinimalExample.WinForms exhibits the same problem. My BrowserRequestHandler looks like this:
public class BrowserRequestHandler : RequestHandler {
protected override bool OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame,
IRequest request, bool userGesture, bool isRedirect) {
// Open in external default browser (chrome)
if (!request.Url.StartsWith("file:") && !request.Url.StartsWith("devtools:")
&& !request.Url.StartsWith("chrome-devtools:") && !request.Url.Contains("pixemail.com")) {
Console.WriteLine($"start new browser at {request.Url}");
System.Diagnostics.Process.Start(request.Url);
return true;
}
return false; // let Cef handle the browse request
}
}
The changes to CefSharp.MinimalExample.WinForms.BrowserForm are:
string htmlPageFromEmail;
public BrowserForm() {
InitializeComponent();
htmlPageFromEmail = File.ReadAllText("test-email.html");
//...
browser = new ChromiumWebBrowser("http://pixemail.com/"); // a dummy web address
//...
BrowserRequestHandler = new BrowserRequestHandler();
browser.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
//...
browser.Visible = true;
}
private void OnIsBrowserInitializedChanged(object sender, EventArgs e) {
var b = ((ChromiumWebBrowser) sender);
this.InvokeOnUiThreadIfRequired(() => {
b.LoadHtml(htmlPageFromEmail, "http://pixemail.com/");
b.Focus();
});
}
My test-email.html file which I use to simulate an email BodyHtmlText string an is:
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<br><br>Bad link. Opens 2 windows:
Jonny Quest Opening Titles in Stop Motion
<br><br>Good link. Opens 1 window:
https://mewe.com/group/5e35fe0f260e8853cadbe7b7
<br><br>
</body>
</html>
I'm using version CefSharp/84 on a Windows 10 PC and Visual Studio 2019 with an x64 platform target.
From memory OnBeforePopup is called before OnBeforeBrowse, so CEF internally creates the popup window then you cancel the navigation resulting in an empty window. In your OnBeforeBrowse implementation you should find Browser.IsPopup is true in cases where the link has the target attribute.
In short you are canceling the navigation too late, the popup window has already been created.
Two options are
Implement http://cefsharp.github.io/api/84.4.x/html/M_CefSharp_ILifeSpanHandler_OnBeforePopup.htm and cancel popup creation.
Inject JavaScript to remove the target attribute.

Cancel Requests on link clicked asp.net

I have a home page on a website (ASP.NET 4.0 C#) which loads a lot of data every time it is accessed (basically a dashboard). This can (depending on the user) take a while to load, so I broke each section into update panels and load them separately so that the user can see it loading and not just think it the page has frozen. However this presents new issues because if the user does not want to wait and clicks on the navigation menu (or a link) to a different page, they have to wait until the page has fully loaded before it moves on.
Is there anyway to stop page requests loading the data if another link is clicked and just deal with that link?
Further info - I am using a master page where the navigation menu is located and also ajax update panels on the home page.
function cancelPostBack() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
Attach this function to the onclick event of the navigation item to ensure any pending requests are cancelled before navigation continues.

Reload page in metro app C#

I'm developing metro app using Windows 8 RTM and C#(VS 2012 RTM), I'm stuck with page reload,
Can any one explains me how to reload page with out navigating to same page again.
Brief: I'm developing metro app with multilingual support. When user selects the language I'm overriding primary language by below code
Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "de";
and reload the page by using this code
this.Frame.Navigate(this.GetType());
Language changed to "de",But when i press "Back" on page its navigating same page instead of navigating to previous page.Did i miss something, Can someone please explains me how to do this. Thanks in advance
This will refresh your page:
var _Frame = Window.Current.Content as Frame;
_Frame.Navigate(_Frame.Content.GetType());
_Frame.GoBack(); // remove from BackStack
Handling OnNavigatingFrom() you can save your page's data and state.
Handling OnNavigatingTo() you can load your page's data and state.
As a caveat, my sample does not account for page parameters, you may need to.
Also, another caveat, my sample reloads your page twice. But the GoBack() is necessary to remove the new entry from the BackStack. Unlike WP, Frame does not have Refresh(). Also, the BackStack does not have Remove().
UPDATE
I no longer use the above approach. I use this:
public bool Reload() { return Reload(null); }
private bool Reload(object param)
{
Type type = this.Frame.CurrentSourcePageType;
if (this.Frame.BackStack.Any())
{
type = this.Frame.BackStack.Last().SourcePageType;
param = this.Frame.BackStack.Last().Parameter;
}
try { return this.Frame.Navigate(type, param); }
finally { this.Frame.BackStack.Remove(this.Frame.BackStack.Last()); }
}
I’m not sure I fully understand what you are trying to do, so this may be wrong.
By calling that line of code when you are refreshing the page, you are creating a brand new object of the current type and navigating to it, so this does not save changes the user makes while they are on the current page.
Are you using any type of design pattern? For things like this I use MVVM (using the MVVM light library) which implements a really cool navigation service which will keep stuff like this in check.

Update image in ASP.NET page from memory without refreshing the page

I have a command line C# server and an ASP.NET client, they both communicate via .NET Remoting. The server is sending the client still images grabbed from a webcam at say 2 frames a second. I can pass the images down to the client via a remote method call and the image ends up in this client method:
public void Update(System.Drawing.Image currentFrame)
{
// I need to display the currentFrame on my page.
}
How do i display the image on the a page without saving the image to the hard disc? If it was a winForms app i could pass currentFrame to a picturebox ie. picturebox.Image = currentFrame.
The above Update method gets fired at least 2 times a second. If the client was a winForms app i could simply put picturebox.Image = currentFrame and the current frame on the screen would automatically get updated. How do i achieve the same effect with ASP.NET? Will the whole page need to be reloaded etc? I want to basically make it look like a live video feed!
You have left one player out of your game: the browser. Your question really is: how do I make the browser, on some random computer in the Internet, update an image it is displaying based on what's happening in a server.
The answer, of course, is: you don't.
You can place the image inside of an UpdatePanel, and update the panel based on a timer. The URL for the src property of the image would have to lead to a HttpHandler (.ashx file) of your own, that would call the server to get the latest image.
Always remember how the Web works: the browser is in control, not the server side.
P.S. .NET Remoting has been deprecated in favor of WCF.
You will need to have a page or handler on the server to render the image. That's its job. Then you can have javascript in place on the page that displays the image that acts on a timer (window.setTimeout) and is constantly polling the server for an updated image. You probably want to make the request somewhat dynamic in the querystring so you don't get stuck redisplaying a cached image instead of a new image delivered by the server. Something like
<script type="text/javascript" language="javascript">
i = 0;
window.setTimeout(updateImage, 500);
var img = document.getElementById('img_to_update');
function updateImage() {
img.src = 'imageRenderer.aspx?req=' + i;
i += 1;
window.setTimeout(updateImage, 500);
}
</script>
Where i only serves to keep the request unique to prevent caching issues.
Anyway, is that the exact script? Perhaps not, I wrote it off the top of my head and it has been a while since I've done anything similar. But it should give you an idea of how you can achieve part of this client-side indepenent of the server side technology. (This script could be on any page, static or dynamically rendered.)

Categories

Resources