Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální vydání najdete v článku pro verzi .NET 9.
Varování
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální vydání najdete v článku pro verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální vydání najdete v článku pro verzi .NET 9.
Tento článek vysvětluje, jak nakonfigurovat a spravovat SignalR připojení v Blazor aplikacích.
Obecné pokyny k konfiguraci ASP.NET Core
Aplikace na straně serveru používají ke komunikaci s prohlížečem ASP.NET Core SignalR . SignalRPodmínky hostování a škálování se vztahují na aplikace na straně serveru.
Blazor funguje nejlépe při použití protokolu WebSocket jako SignalR přenosu kvůli nižší latenci, spolehlivosti a zabezpečení. Dlouhé dotazování se používá SignalR , když webSockets není k dispozici nebo když je aplikace explicitně nakonfigurovaná tak, aby používala dlouhé dotazování.
Služba Azure SignalR se stavovým opětovným připojením
Služba Azure SignalR se sadou SDK verze 1.26.1 nebo novější podporuje SignalR stavové opětovné připojení (WithStatefulReconnect).
Komprese protokolu WebSocket pro komponenty interaktivního serveru
Ve výchozím nastavení jsou součásti interaktivního serveru:
Povolte kompresi připojení WebSocket. DisableWebSocketCompression (výchozí:
false
) řídí kompresi protokolu WebSocket.Přijměte direktivu
frame-ancestors
Content Security Policy (CSP) nastavenou na'self'
, což je výchozí nastavení a povoluje pouze vložení aplikace do<iframe>
původu, ze kterého se aplikace obsluhuje, pokud je povolena komprese nebo je poskytnuta konfigurace kontextu WebSocket.
Výchozí frame-ancestors
CSP je možné změnit nastavením hodnoty ContentSecurityFrameAncestorsPolicy na null
, pokud chcete nakonfigurovat CSP centralizovaným způsobem nebo 'none'
pro ještě přísnější zásady. Když je frame-ancestors
CSP spravován centralizovaným způsobem, je nutné aplikovat zásadu při vykreslení prvního dokumentu. Nedoporučujeme zásady úplně odebírat, protože aplikace bude zranitelná vůči útokům. Další informace najdete v tématu Vynucení zásad zabezpečení obsahu pro ASP.NET Core Blazor a v průvodci MDN CSP.
Pomocí ConfigureWebSocketAcceptContext nakonfigurujte WebSocketAcceptContext pro připojení Protokolu WebSocket, která používají součásti serveru. Ve výchozím nastavení se použije zásada, která umožňuje kompresi a nastaví CSP pro předky rámce definované v ContentSecurityFrameAncestorsPolicy .
Příklady použití:
Zakažte kompresi nastavením DisableWebSocketCompression na true
, což snižuje zranitelnost aplikace vůči útokům, ale může vést ke snížení výkonu.
builder.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(o => o.DisableWebSocketCompression = true)
Pokud je komprese povolená, nakonfigurujte přísnější frame-ancestors
CSP s hodnotou 'none'
(vyžaduje se jednoduché uvozovky), což umožňuje kompresi protokolu WebSocket, ale brání prohlížečům v vkládání aplikace do <iframe>
:
builder.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = "'none'")
Pokud je povolena komprese, odeberte frame-ancestors
CSP nastavením ContentSecurityFrameAncestorsPolicy na null
. Tento scénář se doporučuje jenom pro aplikace, které nastavují CSP centralizovaným způsobem:
builder.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(o => o.ContentSecurityFrameAncestorsPolicy = null)
Důležité
Prohlížeče používají směrnice CSP z více hlaviček CSP pomocí nejpřísnější hodnoty zásad direktivy. Vývojář proto nemůže přidat záměrně nebo omylem slabší frame-ancestors
zásadu než 'self'
.
Jednoduché uvozovky jsou vyžadovány pro řetězcovou hodnotu přenesenou k ContentSecurityFrameAncestorsPolicy:
Nepodporované hodnoty:none
, self
Podporované hodnoty:'none'
, 'self'
Mezi další možnosti patří zadání jednoho nebo více zdrojů pro hostování a zdrojů pro schémata.
Podívejte se na pokyny k mitigaci hrozeb pro ASP.NET Core frame-ancestors
(dokumentace MDN).
Zakázání komprese odpovědí pro Hot Reload
Při použití Hot Reload zakažte middleware pro kompresi odpovědí v Development
prostředí. Bez ohledu na to, jestli se používá výchozí kód ze šablony projektu, vždy volejte UseResponseCompression nejprve v kanálu zpracování požadavků.
V souboru Program
:
if (!app.Environment.IsDevelopment())
{
app.UseResponseCompression();
}
Vyjednávání mezi různými doménami na straně SignalR klienta pro autentizaci
Tato část vysvětluje, jak nakonfigurovat SignalRzákladního klienta pro odesílání přihlašovacích údajů, jako jsou soubory cookie nebo hlavičky ověřování HTTP.
Použijte SetBrowserRequestCredentials k nastavení Include při požadavcích mezi zdroji fetch
.
IncludeRequestCredentialsMessageHandler.cs
:
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Http;
public class IncludeRequestCredentialsMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
return base.SendAsync(request, cancellationToken);
}
}
Pokud bylo vytvořeno připojení rozbočovače, přiřaďte HttpMessageHandler k možnost HttpMessageHandlerFactory:
private HubConnectionBuilder? hubConnection;
...
hubConnection = new HubConnectionBuilder()
.WithUrl(new Uri(Navigation.ToAbsoluteUri("/chathub")), options =>
{
options.HttpMessageHandlerFactory = innerHandler =>
new IncludeRequestCredentialsMessageHandler { InnerHandler = innerHandler };
}).Build();
Předchozí příklad nakonfiguruje URL připojení hubu na absolutní URI na /chathub
. Identifikátor URI lze také nastavit pomocí řetězce, například https://signalr.example.com
nebo prostřednictvím konfigurace.
Navigation
je injektovaný NavigationManager.
Další informace najdete v tématu konfigurace SignalR ASP.NET Core.
Vykreslování na straně klienta
Pokud je předrenderování nakonfigurováno, dojde k němu dříve, než je navázáno připojení klienta k serveru. Další informace naleznete v tématu Prerender ASP.NET Základní Razor komponenty.
Pokud je předrenderování nakonfigurováno, dojde k němu dříve, než je navázáno připojení klienta k serveru. Další informace najdete v následujících článcích:
Předem vytyčovaná velikost stavu a SignalR omezení velikosti zprávy
Velikost stavu při předběžném renderování může překročit limit velikosti zprávy okruhu BlazorSignalR, což vede k následujícímu výsledku:
- Okruh SignalR se nepodaří inicializovat s chybou v klientovi: Circuit host not initialized.
- Uživatelské rozhraní pro opětovné připojení v klientovi se zobrazí, když okruh selže. Obnovení není možné.
Pokud chcete tento problém vyřešit, použijte některý z následujících přístupů:
- Snižte množství dat, která vkládáte do předzpracovaného stavu.
- SignalR Zvětšete limit velikosti zprávy. UPOZORNĚNÍ: Zvýšení limitu může zvýšit riziko DoS útoků.
Další prostředky na straně klienta
- Zabezpečte SignalR centrum
- Přehled ASP.NET Core SignalR
- Konfigurace SignalR pro ASP.NET Core
-
Blazor ukázkový GitHub repozitář (
dotnet/blazor-samples
) (jak stáhnout)
Použití spřažení relací (perzistentní relace) pro hostování webové farmy na straně serveru
Pokud se používá více než jeden backendový server, musí aplikace implementovat spřažení relací, označované také jako sticky sessions. Vazba relace zajišťuje, že se připojení klienta znovu naváže ke stejnému serveru, pokud dojde k přerušení spojení. To je důležité, protože stav klienta je uchováván pouze v paměti serveru, který jako první navázal připojení klienta.
Následující chyba je vyvolána aplikací, která na webfarmě nepovolila vazbu relací.
Uncaught (in promise) Error: Invocation canceled due to the underlying connection being closed.
Další informace o spřažení relace s hostováním služby Azure App Service viz Hostování a nasazení aplikací ASP.NET Core na straně Blazor serveru.
Služba Azure SignalR
Volitelná služba Azure funguje ve spojení s rozbočovačem aplikace pro škálování serverové aplikace na velký počet souběžných připojení. Globální dosah služby a vysoce výkonná datová centra navíc výrazně pomáhají snížit latenci kvůli zeměpisné poloze.
Služba se nevyžaduje pro Blazor aplikace hostované ve službě Aplikace Azure Service nebo Azure Container Apps, ale může být užitečná v jiných hostitelských prostředích:
- Pro usnadnění škálování kapacity připojení.
- Řízení globální distribuce
Další informace najdete v tématu Hostování a nasazování aplikací na straně Blazorserveru ASP.NET Core.
Možnosti zpracovatele okruhů na straně serveru
Nakonfigurujte okruh pomocí CircuitOptions. Zobrazit výchozí hodnoty ve zdroji odkazu.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Přečtěte si nebo nastavte možnosti v souboru Program
pomocí delegáta možností na AddInteractiveServerComponents. Zástupný {OPTION}
symbol představuje možnost a {VALUE}
zástupný symbol je hodnota.
V souboru Program
:
builder.Services.AddRazorComponents().AddInteractiveServerComponents(options =>
{
options.{OPTION} = {VALUE};
});
Přečtěte si nebo nastavte možnosti v souboru Program
pomocí delegáta možností na AddServerSideBlazor. Zástupný {OPTION}
symbol představuje možnost a {VALUE}
zástupný symbol je hodnota.
V souboru Program
:
builder.Services.AddServerSideBlazor(options =>
{
options.{OPTION} = {VALUE};
});
Přečtěte si nebo nastavte možnosti v Startup.ConfigureServices
pomocí delegáta k nastavení možností ve AddServerSideBlazor. Zástupný {OPTION}
symbol představuje možnost a {VALUE}
zástupný symbol je hodnota.
V Startup.ConfigureServices
z Startup.cs
:
services.AddServerSideBlazor(options =>
{
options.{OPTION} = {VALUE};
});
Chcete-li konfigurovat HubConnectionContext, použijte HubConnectionContextOptions s AddHubOptions. Zobrazení výchozích hodnot pro možnosti kontextu připojení centra v referenčním zdroji Pro popisy možností v dokumentaci viz {OPTION}
symbol představuje možnost a {VALUE}
zástupný symbol je hodnota.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
V souboru Program
:
builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddHubOptions(options =>
{
options.{OPTION} = {VALUE};
});
V souboru Program
:
builder.Services.AddServerSideBlazor().AddHubOptions(options =>
{
options.{OPTION} = {VALUE};
});
V Startup.ConfigureServices
z Startup.cs
:
services.AddServerSideBlazor().AddHubOptions(options =>
{
options.{OPTION} = {VALUE};
});
Varování
Výchozí hodnota MaximumReceiveMessageSize je 32 kB. Zvýšení hodnoty může zvýšit riziko útoků DoS (Denial of Service).
Blazor spoléhá na MaximumParallelInvocationsPerClient hodnotu 1, což je výchozí hodnota. Další informace naleznete v tématu MaximumParallelInvocationsPerClient > 1 narušuje nahrávání souborů v Blazor Server režimu (dotnet/aspnetcore
#53951).
Informace o správě paměti najdete v tématu Správa paměti v nasazených aplikacích na straně Blazor serveru ASP.NET Core.
Blazor Možnosti rozbočovače
Nakonfigurujte MapBlazorHub možnosti pro řízení HttpConnectionDispatcherOptionsBlazor hubu. Zobrazit výchozí nastavení pro volby spojení rozbočovače v referenčním zdroji {OPTION}
symbol představuje možnost a {VALUE}
zástupný symbol je hodnota.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Volání app.MapBlazorHub
umístěte za volání app.MapRazorComponents
do souboru aplikace Program
:
app.MapBlazorHub(options =>
{
options.{OPTION} = {VALUE};
});
Konfigurace hubu použitého AddInteractiveServerRenderMode s MapBlazorHub selže s chybou AmbiguousMatchException
:
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints.
Pokud chcete tento problém vyřešit u aplikací, které cílí na .NET 8, dejte vlastnímu nakonfigurovanému hubu vyšší prioritu pomocí metody Blazor:
app.MapBlazorHub(options =>
{
options.CloseOnAuthenticationExpiration = true;
}).WithOrder(-1);
Další informace naleznete v následujících zdrojích:
Zadejte možnosti pro app.MapBlazorHub
do souboru Program
v aplikaci.
app.MapBlazorHub(options =>
{
options.{OPTION} = {VALUE};
});
Uveďte možnosti ke app.MapBlazorHub
v konfiguraci směrování koncového bodu:
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub(options =>
{
options.{OPTION} = {VALUE};
});
...
});
Maximální velikost příjmu zprávy
Tato část se vztahuje pouze na projekty, které implementují SignalR.
Maximální povolená velikost příchozí SignalR zprávy pro metody rozbočovače je omezena podle nastavení HubOptions.MaximumReceiveMessageSize (výchozí hodnota: 32 kB). SignalR zprávy větší než MaximumReceiveMessageSize vyvolají chybu. Architektura neukládá omezení velikosti SignalR zprávy z centra na klienta.
Pokud SignalR není protokolování nastaveno na Ladění nebo Trasování, chyba velikosti zprávy se zobrazí pouze v konzoli nástrojů pro vývojáře v prohlížeči:
Chyba: Připojení bylo odpojeno s chybou Chyba: Server vrátil chybu při zavření: Připojení se ukončilo s chybou.
Pokud SignalR je protokolování na straně serveru nastaveno na ladění nebo trasování, protokolování na straně serveru zobrazí InvalidDataException chybu velikosti zprávy.
appsettings.Development.json
:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
...
"Microsoft.AspNetCore.SignalR": "Debug"
}
}
}
Chyba:
System.IO.InvalidDataException: Byla překročena maximální velikost zprávy 32768B. Velikost zprávy se dá nakonfigurovat v AddHubOptions.
Jedním z přístupů je zvýšení limitu nastavením MaximumReceiveMessageSize v Program
souboru. Následující příklad nastaví maximální velikost příjmu zprávy na 64 kB:
builder.Services.AddRazorComponents().AddInteractiveServerComponents()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);
Zvýšení limitu SignalR velikosti příchozích zpráv s sebou nese nároky na více prostředků serveru a zvyšuje riziko útoků Denial of Service (DoS). Navíc čtení velkého množství obsahu do paměti jako řetězců nebo bajtových polí může také vést k přidělení, která neefektivně spolupracují s garbage collectorem, což má za následek dodatečné výkonnostní postihy.
Lepší možností pro čtení velkých datových částí je odeslat obsah v menších blocích a zpracovat datovou část jako .Stream To lze použít při čtení velkých JSON zatížení z JavaScript JS interopu nebo pokud je JS interop data dostupná jako nezpracované bajty. Pro příklad, který ukazuje odesílání velkých binárních datových částí v serverových aplikacích používajících techniky podobné InputFile
komponentě, se podívejte na ukázkovou aplikaci Binary Submit a BlazorInputLargeTextArea
vzorovou aplikaci komponent.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Formuláře, které zpracovávají velké datové balíčky, můžou také přímo používat streamovací rozhraní SignalRJS. Další informace naleznete v tématu Volání metod .NET z funkcí JavaScriptu v ASP.NET Core Blazor. Příklad formulářů, který streamuje <textarea>
data na server, najdete v článku Řešení potíží s Blazor formuláři v ASP.NET Core.
Jedním z přístupů je zvýšení limitu nastavením MaximumReceiveMessageSize v Program
souboru. Následující příklad nastaví maximální velikost příjmu zprávy na 64 kB:
builder.Services.AddServerSideBlazor()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);
Zvýšení limitu SignalR velikosti příchozích zpráv s sebou nese nároky na více prostředků serveru a zvyšuje riziko útoků Denial of Service (DoS). Navíc čtení velkého množství obsahu do paměti jako řetězců nebo bajtových polí může také vést k přidělení, která neefektivně spolupracují s garbage collectorem, což má za následek dodatečné výkonnostní postihy.
Lepší možností pro čtení velkých datových částí je odeslat obsah v menších blocích a zpracovat datovou část jako .Stream To lze použít při čtení velkých JSON zatížení z JavaScript JS interopu nebo pokud je JS interop data dostupná jako nezpracované bajty. Příklad, který ukazuje odesílání velkých binárních datových částí v Blazor Server pomocí technik podobných komponentě InputFile
, naleznete v ukázkové aplikaci Binary Submit a v ukázce komponenty BlazorInputLargeTextArea
.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Formuláře, které zpracovávají velké datové balíčky, můžou také přímo používat streamovací rozhraní SignalRJS. Další informace naleznete v tématu Volání metod .NET z funkcí JavaScriptu v ASP.NET Core Blazor. Pro příklad formulářů, který streamuje <textarea>
data v aplikaci Blazor Server, se podívejte na Řešení problémů ASP.NET Core Blazor formulářů.
Zvýšení limitu nastavením MaximumReceiveMessageSize v Startup.ConfigureServices
:
services.AddServerSideBlazor()
.AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024);
Zvýšení limitu SignalR velikosti příchozích zpráv s sebou nese nároky na více prostředků serveru a zvyšuje riziko útoků Denial of Service (DoS). Navíc čtení velkého množství obsahu do paměti jako řetězců nebo bajtových polí může také vést k přidělení, která neefektivně spolupracují s garbage collectorem, což má za následek dodatečné výkonnostní postihy.
Při vývoji kódu, který přenáší velké množství dat, zvažte následující pokyny:
- Využijte nativní podporu streamovací interoperability JS pro přenos dat, která překračují SignalR limit velikosti příchozí zprávy.
- Obecné tipy:
- Nealokujte velké objekty v JS a v kódu C#.
- Volné spotřebované paměti po dokončení nebo zrušení procesu
- Vynucujte následující další požadavky pro účely zabezpečení:
- Deklarujte maximální velikost souboru nebo dat, které lze předat.
- Deklarujte minimální rychlost nahrávání z klienta na server.
- Po přijetí dat serverem mohou být tato data následující:
- Dočasně uložené ve vyrovnávací paměti, dokud nejsou všechny segmenty shromážděny.
- Spotřebováno okamžitě. Data se například dají okamžitě uložit do databáze nebo zapisovat na disk při přijetí jednotlivých segmentů.
- Rozdělte data na menší části a posílejte datové segmenty postupně, dokud server neobdrží všechna data.
- Nealokujte velké objekty v JS a v kódu C#.
- Při odesílání nebo přijímání dat neblokujte hlavní vlákno uživatelského rozhraní po dlouhou dobu.
- Volné spotřebované paměti po dokončení nebo zrušení procesu
- Vynucujte následující další požadavky pro účely zabezpečení:
- Deklarujte maximální velikost souboru nebo dat, které lze předat.
- Deklarujte minimální rychlost nahrávání z klienta na server.
- Po přijetí dat serverem mohou být tato data následující:
- Dočasně uložené ve vyrovnávací paměti, dokud nejsou všechny segmenty shromážděny.
- Spotřebováno okamžitě. Data se například dají okamžitě uložit do databáze nebo zapisovat na disk při přijetí jednotlivých segmentů.
Blazor Konfigurace směrování koncového bodu Hubu na serverové straně
V souboru Program
zavolejte MapBlazorHub pro namapování BlazorHub na výchozí cestu aplikace. Skript Blazor (blazor.*.js
) automaticky odkazuje na koncový bod vytvořený MapBlazorHub.
Reflektujte stav připojení na straně serveru v uživatelském rozhraní.
Pokud klient zjistí ztracené připojení k serveru, zobrazí se uživateli výchozí uživatelské rozhraní, zatímco se klient pokusí znovu připojit:
Pokud se opětovné připojení nezdaří, uživateli se zobrazí pokyn, aby se znovu zkusil nebo znovu načte stránku:
Pokud opětovné připojení proběhne úspěšně, stav uživatele se často ztratí. Vlastní kód lze přidat do libovolné komponenty, aby se při selhání připojení uložil a znovu načítá stav uživatele. Další informace najdete v tématu ASP.NET Core Blazor správa stavu.
Pokud chcete vytvořit prvky uživatelského rozhraní, které sledují stav opětovného připojení, popisuje následující tabulka:
- Sada tříd CSS
components-reconnect-*
(třída CSS sloupec), které jsou nastaveny nebo vypnuty pomocí Blazor na prvku s vlastnostíid
components-reconnect-modal
. - Událost
components-reconnect-state-changed
(sloupecUdálost), která označuje změnu stavu opětovného připojení.
CSS třída | Událost | Označuje... |
---|---|---|
components-reconnect-show |
show |
Ztracené připojení. Klient se pokouší znovu připojit. Zobrazí se dialog opětovného připojení. |
components-reconnect-hide |
hide |
Na serveru se znovu naváže aktivní připojení. Model opětovného připojení je zavřený. |
components-reconnect-retrying |
retrying |
Klient se pokouší znovu připojit. |
components-reconnect-failed |
failed |
Opětovné připojení se nezdařilo, pravděpodobně kvůli selhání sítě. |
components-reconnect-rejected |
rejected |
Opětovné připojení bylo odmítnuto. |
Když se stav opětovného připojení v components-reconnect-state-changed
změní na failed
, zavolejte v JavaScriptu Blazor.reconnect()
a pokuste se o opětovné připojení.
Když dojde ke změně stavu opětovného připojení na rejected
, bylo navázáno spojení se serverem, ale ten odmítl připojení, a uživatelský stav na serveru je ztracen. Pokud chcete aplikaci znovu načíst, zavolejte location.reload()
v JavaScriptu. Tento stav připojení může mít za následek následující:
- V okruhu na straně serveru dojde k selhání.
- Klient je odpojen natolik dlouho, že server resetuje stav uživatele. Instance komponent uživatele jsou likvidovány.
- Server se restartuje nebo se pracovní proces aplikace recykluje.
Vývojář přidá posluchač událostí k prvku modálního okna pro opětovné připojení, aby monitoroval a reagoval na změny stavu opětovného připojení, jak je vidět v následujícím příkladu.
const reconnectModal = document.getElementById("components-reconnect-modal");
reconnectModal.addEventListener("components-reconnect-state-changed",
handleReconnectStateChanged);
function handleReconnectStateChanged(event) {
if (event.detail.state === "show") {
reconnectModal.showModal();
} else if (event.detail.state === "hide") {
reconnectModal.close();
} else if (event.detail.state === "failed") {
Blazor.reconnect();
} else if (event.detail.state === "rejected") {
location.reload();
}
}
Prvek s označením id
a components-reconnect-max-retries
zobrazuje maximální počet pokusů o opětovné připojení:
<span id="components-reconnect-max-retries"></span>
Prvek s id
a components-reconnect-current-attempt
zobrazuje aktuální pokus o opětovné připojení:
<span id="components-reconnect-current-attempt"></span>
Prvek s id
o hodnotě components-seconds-to-next-attempt
zobrazuje počet sekund do dalšího pokusu o opětovné připojení:
<span id="components-seconds-to-next-attempt"></span>
Šablona projektu Blazor Web App obsahuje komponentu ReconnectModal
(Components/Layout/ReconnectModal.razor
) s kompletovanými soubory stylů a javascriptovými soubory (ReconnectModal.razor.css
, ReconnectModal.razor.js
), které je možné přizpůsobit podle potřeby. Tyto soubory je možné prozkoumat v referenčním zdroji ASP.NET Core nebo kontrolou aplikace vytvořené ze šablony projektu Blazor Web App. Komponenta se přidá do projektu, když je projekt vytvořen v sadě Visual Studio s interaktivním režimem vykreslování nastaveným na Server nebo Auto, nebo je vytvořen pomocí nástroje .NET CLI s volbou --interactivity server
(výchozí) nebo --interactivity auto
.
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Chcete-li přizpůsobit uživatelské rozhraní, definujte jeden prvek s id
a components-reconnect-modal
v obsahu elementu <body>
. Následující příklad umístí prvek do App
komponenty.
App.razor
:
Chcete-li přizpůsobit uživatelské rozhraní, definujte jeden prvek s id
a components-reconnect-modal
v obsahu elementu <body>
. Následující příklad umístí prvek na stránku hostitele.
Pages/_Host.cshtml
:
Chcete-li přizpůsobit uživatelské rozhraní, definujte jeden prvek s id
a components-reconnect-modal
v obsahu elementu <body>
. Následující příklad umístí prvek na stránku rozložení.
Pages/_Layout.cshtml
:
Chcete-li přizpůsobit uživatelské rozhraní, definujte jeden prvek s id
a components-reconnect-modal
v obsahu elementu <body>
. Následující příklad umístí prvek na stránku hostitele.
Pages/_Host.cshtml
:
<div id="components-reconnect-modal">
Connection lost.<br>Attempting to reconnect...
</div>
Poznámka:
Pokud aplikace vykresluje více než jeden prvek s id
typu components-reconnect-modal
, pouze první vykreslený prvek obdrží změny třídy CSS ke zobrazení nebo skrytí tohoto elementu.
Do šablony stylů webu přidejte následující styly CSS.
wwwroot/app.css
:
wwwroot/css/site.css
:
#components-reconnect-modal {
display: none;
}
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
display: block;
background-color: white;
padding: 2rem;
border-radius: 0.5rem;
text-align: center;
box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
margin: 50px 50px;
position: fixed;
top: 0;
z-index: 10001;
}
Následující tabulka popisuje třídy CSS použité u components-reconnect-modal
elementu rozhraním Blazor .
CSS třída | Označuje... |
---|---|
components-reconnect-show |
Ztracené připojení. Klient se pokouší znovu připojit. Zobrazit dialogové okno. |
components-reconnect-hide |
Na serveru se znovu naváže aktivní připojení. Skryjte dialogové okno. |
components-reconnect-failed |
Opětovné připojení se nezdařilo, pravděpodobně kvůli selhání sítě. Pokud se chcete pokusit znovu připojit, zavolejte window.Blazor.reconnect() v JavaScriptu. |
components-reconnect-rejected |
Opětovné připojení bylo odmítnuto. Server byl dosažen, ale odmítl připojení a stav uživatele na serveru se ztratil. Pokud chcete aplikaci znovu načíst, zavolejte location.reload() v JavaScriptu. Tento stav připojení může mít za následek následující:
|
Přizpůsobte zpoždění před zobrazením uživatelského rozhraní pro opětovné připojení nastavením transition-delay
vlastnosti v šabloně stylů CSS webu pro modální prvek. Následující příklad nastaví zpoždění přechodu z 500 ms (výchozí) na 1 000 ms (1 sekunda).
wwwroot/app.css
:
wwwroot/css/site.css
:
#components-reconnect-modal {
transition: visibility 0s linear 1000ms;
}
Chcete-li zobrazit aktuální pokus o opětovné připojení, definujte prvek s `id
` a `components-reconnect-current-attempt
`. Chcete-li zobrazit maximální počet opakovaných pokusů o opětovné připojení, definujte prvek s id
nastaveným na components-reconnect-max-retries
. Následující příklad umístí tyto prvky do modálního prvku pokusu o opětovné připojení za předchozím příkladem.
<div id="components-reconnect-modal">
There was a problem with the connection!
(Current reconnect attempt:
<span id="components-reconnect-current-attempt"></span> /
<span id="components-reconnect-max-retries"></span>)
</div>
Když se zobrazí modální okno vlastního opětovného připojení, zobrazí následující obsah s počítadlem pokusů o opětovné připojení.
Došlo k problému s připojením! (Aktuální pokus o opětovné připojení: 1 / 8)
Vykreslování na straně serveru
Ve výchozím nastavení jsou komponenty předváděné na serveru před navázáním připojení klienta k serveru. Další informace naleznete v tématu Prerender ASP.NET Základní Razor komponenty.
Ve výchozím nastavení jsou komponenty předváděné na serveru před navázáním připojení klienta k serveru. Další informace naleznete v sekci Pomocník značky komponenty v ASP.NET Core.
Monitorování aktivity obvodu na straně serveru
Sledujte příchozí aktivitu okruhu pomocí metody CreateInboundActivityHandler na CircuitHandler. Příchozí aktivita okruhu je jakákoli aktivita odesílaná z prohlížeče na server, například události UI nebo volání interoperability z JavaScriptu do .NET.
Například můžete použít obslužnou rutinu aktivity okruhu k zjištění, zda je klient nečinný, a k zaznamenání jeho ID okruhu (Circuit.Id):
using Microsoft.AspNetCore.Components.Server.Circuits;
using Microsoft.Extensions.Options;
using Timer = System.Timers.Timer;
public sealed class IdleCircuitHandler : CircuitHandler, IDisposable
{
private Circuit? currentCircuit;
private readonly ILogger logger;
private readonly Timer timer;
public IdleCircuitHandler(ILogger<IdleCircuitHandler> logger,
IOptions<IdleCircuitOptions> options)
{
timer = new Timer
{
Interval = options.Value.IdleTimeout.TotalMilliseconds,
AutoReset = false
};
timer.Elapsed += CircuitIdle;
this.logger = logger;
}
private void CircuitIdle(object? sender, System.Timers.ElapsedEventArgs e)
{
logger.LogInformation("{CircuitId} is idle", currentCircuit?.Id);
}
public override Task OnCircuitOpenedAsync(Circuit circuit,
CancellationToken cancellationToken)
{
currentCircuit = circuit;
return Task.CompletedTask;
}
public override Func<CircuitInboundActivityContext, Task> CreateInboundActivityHandler(
Func<CircuitInboundActivityContext, Task> next)
{
return context =>
{
timer.Stop();
timer.Start();
return next(context);
};
}
public void Dispose() => timer.Dispose();
}
public class IdleCircuitOptions
{
public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromMinutes(5);
}
public static class IdleCircuitHandlerServiceCollectionExtensions
{
public static IServiceCollection AddIdleCircuitHandler(
this IServiceCollection services,
Action<IdleCircuitOptions> configureOptions)
{
services.Configure(configureOptions);
services.AddIdleCircuitHandler();
return services;
}
public static IServiceCollection AddIdleCircuitHandler(
this IServiceCollection services)
{
services.AddScoped<CircuitHandler, IdleCircuitHandler>();
return services;
}
}
Zaregistrujte službu v Program
souboru. Následující příklad nakonfiguruje výchozí časový limit nečinnosti pět minut až pět sekund, aby bylo možné otestovat předchozí IdleCircuitHandler
implementaci:
builder.Services.AddIdleCircuitHandler(options =>
options.IdleTimeout = TimeSpan.FromSeconds(5));
Obslužné rutiny aktivit obvodu také poskytují přístup k definovaným Blazor službám z jiných Blazor rozsahů injektáže závislostí (DI). Další informace a příklady najdete tady:
Blazor spuštění
Nakonfigurujte ruční spuštění okruhu BlazorSignalR v App.razor
souboru Blazor Web App:
Nakonfigurujte ruční spuštění okruhu BlazorSignalR v souboru Pages/_Host.cshtml
(Blazor Server):
Nakonfigurujte ruční spuštění okruhu BlazorSignalR v souboru Pages/_Layout.cshtml
(Blazor Server):
Nakonfigurujte ruční spuštění okruhu BlazorSignalR v souboru Pages/_Host.cshtml
(Blazor Server):
- Přidejte atribut
autostart="false"
do značky<script>
pro skriptblazor.*.js
. - Umístěte skript, který volá
Blazor.start()
, poté, co je načten skript Blazor, a to uvnitř koncové značky</body>
.
Když je autostart
zakázána, funguje normálně každý aspekt aplikace, který není závislý na obvodu. Například směrování na straně klienta je funkční. Jakýkoli aspekt, který závisí na okruhu, není funkční, dokud se nezavolá Blazor.start()
. Chování aplikace je nepředvídatelné bez zavedeného okruhu. Například metody komponent se nespustí při odpojení okruhu.
Další informace, včetně toho, jak inicializovat Blazor, když je dokument připravený a jak se zřetězit s JS Promise
, viz ASP.NET Core Blazor startup.
Konfigurace SignalR časových limitů a Keep-Alive u klienta
Nakonfigurujte pro klienta následující hodnoty:
-
withServerTimeout
: Nakonfiguruje časový limit serveru v milisekundách. Pokud tento časový limit uplynou bez příjmu zpráv ze serveru, připojení se ukončí s chybou. Výchozí hodnota časového limitu je 30 sekund. Časový limit serveru by měl být alespoň dvojnásobný, než je hodnota přiřazená intervalu keep-Alive (withKeepAliveInterval
). -
withKeepAliveInterval
: Nakonfiguruje interval Keep-Alive v milisekundách (výchozí interval, ve kterém se má server otestovat příkazem ping). Toto nastavení umožňuje serveru rozpoznat pevné odpojení, například když klient odpojí počítač od sítě. Příkaz ping se vyskytuje nanejvýš tak často, jak server provádí ping. Pokud server odešle příkaz ping každých pět sekund, přiřazení hodnoty nižší než5000
(5 sekund) způsobí, že server stále odesílá příkaz ping každých pět sekund. Výchozí hodnota je 15 sekund. Interval Keep-Alive by měl být menší nebo roven polovině hodnoty přiřazené k vypršení časového limitu serveru (withServerTimeout
).
Následující příklad souboru App.razor
(Blazor Web App) ukazuje přiřazení výchozích hodnot.
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
configureSignalR: function (builder) {
builder.withServerTimeout(30000).withKeepAliveInterval(15000);
}
}
});
</script>
Následující příklad souboru Pages/_Host.cshtml
(Blazor Servervšechny verze kromě ASP.NET Core v .NET 6) nebo Pages/_Layout.cshtml
soubor (Blazor ServerASP.NET Core v .NET 6).
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.withServerTimeout(30000).withKeepAliveInterval(15000);
}
});
</script>
V předchozím příkladu je zástupný symbol {BLAZOR SCRIPT}
cestou ke skriptu a název souboru je Blazor. Umístění skriptu a cestu, kterou je třeba použít, naleznete v části struktura projektu ASP.NET Core Blazor.
Při vytváření připojení rozbočovače v komponentě nastavte ServerTimeout (výchozí: 30 sekund) a KeepAliveInterval (výchozí: 15 sekund) na HubConnectionBuilder. Nastavte HandshakeTimeout (výchozí: 15 sekund) na sestavené HubConnection. Následující příklad ukazuje přiřazení výchozích hodnot:
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.WithServerTimeout(TimeSpan.FromSeconds(30))
.WithKeepAliveInterval(TimeSpan.FromSeconds(15))
.Build();
hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(15);
hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...
await hubConnection.StartAsync();
}
Nakonfigurujte pro klienta následující hodnoty:
-
serverTimeoutInMilliseconds
: Časový limit serveru v milisekundách. Pokud tento časový limit uplynou bez příjmu zpráv ze serveru, připojení se ukončí s chybou. Výchozí hodnota časového limitu je 30 sekund. Časový limit serveru by měl být alespoň dvojnásobný, než je hodnota přiřazená intervalu keep-Alive (keepAliveIntervalInMilliseconds
). -
keepAliveIntervalInMilliseconds
: Výchozí interval, ve kterém se má server otestovat příkazem ping. Toto nastavení umožňuje serveru rozpoznat pevné odpojení, například když klient odpojí počítač od sítě. Příkaz ping se vyskytuje nanejvýš tak často, jak server provádí ping. Pokud server odešle příkaz ping každých pět sekund, přiřazení hodnoty nižší než5000
(5 sekund) způsobí, že server stále odesílá příkaz ping každých pět sekund. Výchozí hodnota je 15 sekund. Interval Keep-Alive by měl být menší nebo roven polovině hodnoty přiřazené k vypršení časového limitu serveru (serverTimeoutInMilliseconds
).
Následující příklad souboru Pages/_Host.cshtml
(Blazor Servervšechny verze kromě ASP.NET Core v .NET 6) nebo Pages/_Layout.cshtml
soubor (Blazor ServerASP.NET Core v .NET 6):
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
let c = builder.build();
c.serverTimeoutInMilliseconds = 30000;
c.keepAliveIntervalInMilliseconds = 15000;
builder.build = () => {
return c;
};
}
});
</script>
V předchozím příkladu je zástupný symbol {BLAZOR SCRIPT}
cestou ke skriptu a název souboru je Blazor. Umístění skriptu a cestu, kterou je třeba použít, naleznete v části struktura projektu ASP.NET Core Blazor.
Při vytváření připojení k rozbočovači v komponentě nastavte ServerTimeout (výchozí: 30 sekund), HandshakeTimeout (výchozí: 15 sekund) a KeepAliveInterval (výchozí: 15 sekund) pro sestavený HubConnection. Následující příklad ukazuje přiřazení výchozích hodnot:
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.Build();
hubConnection.ServerTimeout = TimeSpan.FromSeconds(30);
hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(15);
hubConnection.KeepAliveInterval = TimeSpan.FromSeconds(15);
hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...
await hubConnection.StartAsync();
}
Při změně hodnot časového limitu serveru (ServerTimeout) nebo intervalu Keep-Alive (KeepAliveInterval):
- Časový limit serveru by měl být alespoň dvojnásobný, než je hodnota přiřazená intervalu Keep-Alive.
- Interval Keep-Alive by měl být menší nebo roven polovině hodnoty přiřazené k vypršení časového limitu serveru.
Další informace najdete v částech globálního nasazení a selhání připojení v následujících článcích:
- Hostování a nasazování aplikací na straně Blazor serveru ASP.NET Core
- Hostování a nasazení serveru ASP.NET Core Blazor WebAssembly
Úprava obslužné rutiny opětovného připojení na straně serveru
Události spojení okruhu obslužné rutiny pro opětovné připojení je možné upravit pro vlastní chování, například:
- Chcete-li upozornit uživatele, pokud je připojení ukončeno.
- Pro provedení logování z klienta při připojení okruhu.
Pokud chcete upravit události připojení, zaregistrujte zpětná volání pro následující změny připojení:
- Zrušená připojení používají
onConnectionDown
. - Navázaná/znovu navázaná připojení se používají
onConnectionUp
.
Je nutné zadat jak onConnectionDown
, tak onConnectionUp
.
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
reconnectionHandler: {
onConnectionDown: (options, error) => console.error(error),
onConnectionUp: () => console.log("Up, up, and away!")
}
}
});
</script>
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
reconnectionHandler: {
onConnectionDown: (options, error) => console.error(error),
onConnectionUp: () => console.log("Up, up, and away!")
}
});
</script>
V předchozím příkladu je zástupný symbol {BLAZOR SCRIPT}
cestou ke skriptu a název souboru je Blazor. Umístění skriptu a cestu, kterou je třeba použít, naleznete v části struktura projektu ASP.NET Core Blazor.
Automatická aktualizace stránky při selhání opětovného připojení na straně serveru
Výchozí chování opětovného připojení vyžaduje, aby uživatel po selhání opětovného připojení ručně aktualizoval stránku. Nicméně, k automatickému obnovení stránky lze použít vlastní obslužná rutina opětovného připojení.
App.razor
:
Pages/_Host.cshtml
:
<div id="reconnect-modal" style="display: none;"></div>
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script src="boot.js"></script>
V předchozím příkladu je zástupný symbol {BLAZOR SCRIPT}
cestou ke skriptu a název souboru je Blazor. Umístění skriptu a cestu, kterou je třeba použít, naleznete v části struktura projektu ASP.NET Core Blazor.
Vytvořte následující wwwroot/boot.js
soubor.
Blazor Web App:
(() => {
const maximumRetryCount = 3;
const retryIntervalMilliseconds = 5000;
const reconnectModal = document.getElementById('reconnect-modal');
const startReconnectionProcess = () => {
reconnectModal.style.display = 'block';
let isCanceled = false;
(async () => {
for (let i = 0; i < maximumRetryCount; i++) {
reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;
await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));
if (isCanceled) {
return;
}
try {
const result = await Blazor.reconnect();
if (!result) {
// The server was reached, but the connection was rejected; reload the page.
location.reload();
return;
}
// Successfully reconnected to the server.
return;
} catch {
// Didn't reach the server; try again.
}
}
// Retried too many times; reload the page.
location.reload();
})();
return {
cancel: () => {
isCanceled = true;
reconnectModal.style.display = 'none';
},
};
};
let currentReconnectionProcess = null;
Blazor.start({
circuit: {
reconnectionHandler: {
onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
onConnectionUp: () => {
currentReconnectionProcess?.cancel();
currentReconnectionProcess = null;
}
}
}
});
})();
Blazor Server:
(() => {
const maximumRetryCount = 3;
const retryIntervalMilliseconds = 5000;
const reconnectModal = document.getElementById('reconnect-modal');
const startReconnectionProcess = () => {
reconnectModal.style.display = 'block';
let isCanceled = false;
(async () => {
for (let i = 0; i < maximumRetryCount; i++) {
reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;
await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));
if (isCanceled) {
return;
}
try {
const result = await Blazor.reconnect();
if (!result) {
// The server was reached, but the connection was rejected; reload the page.
location.reload();
return;
}
// Successfully reconnected to the server.
return;
} catch {
// Didn't reach the server; try again.
}
}
// Retried too many times; reload the page.
location.reload();
})();
return {
cancel: () => {
isCanceled = true;
reconnectModal.style.display = 'none';
},
};
};
let currentReconnectionProcess = null;
Blazor.start({
reconnectionHandler: {
onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
onConnectionUp: () => {
currentReconnectionProcess?.cancel();
currentReconnectionProcess = null;
}
}
});
})();
Další informace o spuštění Blazor viz spuštění ASP.NET Core Blazor.
Upravit počet pokusů o opětovné připojení a interval na straně serveru
Pokud chcete upravit počet opakování a interval opětovného připojení, nastavte počet opakování (maxRetries
) a období v milisekundách povolených pro každý pokus o opakování (retryIntervalMilliseconds
).
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
reconnectionOptions: {
maxRetries: 3,
retryIntervalMilliseconds: 2000
}
}
});
</script>
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
reconnectionOptions: {
maxRetries: 3,
retryIntervalMilliseconds: 2000
}
});
</script>
V předchozím příkladu je zástupný symbol {BLAZOR SCRIPT}
cestou ke skriptu a název souboru je Blazor. Umístění skriptu a cestu, kterou je třeba použít, naleznete v části struktura projektu ASP.NET Core Blazor.
Když se uživatel vrátí do aplikace s odpojeným okruhem, pokusí se o opětovné připojení okamžitě, a nečeká na dobu trvání dalšího intervalu opětovného připojení. Toto chování se snaží obnovit připojení co nejrychleji pro uživatele.
Výchozí časování opětovného připojení používá vypočítanou strategii zpětného odpojení. Několik opakovaných pokusů o opětovné připojení probíhá v rychlém sledu, než jsou zavedeny vypočítaná zpoždění mezi pokusy. Výchozí logika pro výpočet intervalu opakování je implementační detail, který se může bez předchozího upozornění změnit, nicméně můžete najít standardní logiku, kterou Blazor framework používá ve funkci computeDefaultRetryInterval
(referenční zdroj).
Poznámka:
Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Přizpůsobte chování intervalu opakování zadáním funkce pro výpočet intervalu opakování. V následujícím příkladu exponenciálního backoffu je počet předchozích pokusů o opětovné připojení vynásoben 1 000 ms pro výpočet intervalu znovupokusů. Pokud je počet předchozích pokusů o opětovné připojení (previousAttempts
) větší než maximální limit opakování (maxRetries
), null
je přiřazen k intervalu opakování (retryIntervalMilliseconds
), aby se zastavily další pokusy o opětovné připojení:
Blazor.start({
circuit: {
reconnectionOptions: {
retryIntervalMilliseconds: (previousAttempts, maxRetries) =>
previousAttempts >= maxRetries ? null : previousAttempts * 1000
},
},
});
Alternativou je určit přesnou sekvenci intervalů opakování. Po posledním zadaném intervalu opakování se opakování zastaví, protože retryIntervalMilliseconds
funkce vrátí undefined
:
Blazor.start({
circuit: {
reconnectionOptions: {
retryIntervalMilliseconds:
Array.prototype.at.bind([0, 1000, 2000, 5000, 10000, 15000, 30000]),
},
},
});
Další informace o spuštění Blazor viz spuštění ASP.NET Core Blazor.
Ovládejte, kdy se zobrazí uživatelské rozhraní pro opětovné připojení
Řízení, kdy se zobrazí uživatelské rozhraní pro opětovné připojení, může být užitečné v následujících situacích:
- Nasazená aplikace často zobrazuje rozhraní opětovného připojení kvůli vypršení časového limitu příkazu ping způsobeného zpožděním interní sítě nebo internetu, a proto byste chtěli zvýšit zpoždění.
- Aplikace by měla nahlásit uživatelům, že připojení se dříve ukončilo, a chcete zkrátit zpoždění.
Načasování vzhledu uživatelského rozhraní pro opětovné připojení je ovlivněno úpravou intervalu zachování spojení a časových limitů na straně klienta. Uživatelské rozhraní pro opětovné připojení se zobrazí po dosažení časového limitu serveru v klientovi (withServerTimeout
oddíl Konfigurace klienta). Změna hodnoty withServerTimeout
vyžaduje změny v jiných nastaveních Keep-Alive, timeout a handshake, jak je uvedeno v následujících pokynech.
Jako obecná doporučení pro následující pokyny:
- Keep-Alive interval by se měl shodovat mezi konfigurací klienta a serveru.
- Časové limity by měly být alespoň dvojnásobné, než je hodnota přiřazená intervalu Keep-Alive.
Konfigurace serveru
Nastavte následující:
- ClientTimeoutInterval (výchozí hodnota: 30 sekund): Klienti časového intervalu musí odeslat zprávu předtím, než server připojení zavře.
- HandshakeTimeout (výchozí hodnota: 15 sekund): Interval, který server používá k časovému omezení příchozích požadavků na handshake od klientů.
- KeepAliveInterval (výchozí hodnota: 15 sekund): Interval používaný serverem k vysílání udržovacích pingů připojeným klientům. Všimněte si, že v klientovi je také nastavení intervalu Keep-Alive, které by mělo odpovídat hodnotě serveru.
ClientTimeoutInterval a HandshakeTimeout mohou být zvýšeny, a KeepAliveInterval může zůstat stejný. Důležité je, že pokud změníte hodnoty, ujistěte se, že časové limity jsou alespoň dvojnásobné hodnoty intervalu Keep-Alive a že interval Keep-Alive odpovídá mezi serverem a klientem. Další informace najdete v části Konfigurace SignalR časových limitů a Keep-Alive na klientu.
V následujícím příkladu:
- Hodnota ClientTimeoutInterval se zvýší na 60 sekund (výchozí hodnota: 30 sekund).
- Hodnota HandshakeTimeout se zvýší na 30 sekund (výchozí hodnota: 15 sekund).
- Není KeepAliveInterval nastaven v kódu vývojáře a používá výchozí hodnotu 15 sekund. Snížení hodnoty intervalu Keep-Alive zvyšuje frekvenci příkazů ping pro komunikaci, což zvyšuje zatížení aplikace, serveru a sítě. Je třeba dbát na to, abyste se vyhnuli špatnému výkonu při snížení intervalu Keep-Alive.
Blazor Web App (.NET 8 nebo novější) v souboru serverového projektu Program
:
builder.Services.AddRazorComponents().AddInteractiveServerComponents()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
options.HandshakeTimeout = TimeSpan.FromSeconds(30);
});
Blazor Server v Program
souboru:
builder.Services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
options.HandshakeTimeout = TimeSpan.FromSeconds(30);
});
Další informace najdete v části Možnosti obslužné rutiny okruhu na straně serveru.
Konfigurace klienta
Nastavte následující:
-
withServerTimeout
(výchozí hodnota: 30 sekund): Nakonfiguruje časový limit serveru zadaný v milisekundách pro připojení rozbočovače okruhu. -
withKeepAliveInterval
(výchozí hodnota: 15 sekund): Interval zadaný v milisekundách, ve kterém připojení odesílá zprávy Keep-Alive.
Časový limit serveru je možné zvýšit a interval Keep-Alive může zůstat stejný. Důležité je, že pokud změníte hodnoty, ujistěte se, že časový limit serveru je alespoň dvojnásobná hodnota intervalu Keep-Alive a že hodnoty intervalu Keep-Alive odpovídají mezi serverem a klientem. Další informace najdete v části Konfigurace SignalR časových limitů a Keep-Alive na klientu.
V následujícím příkladu konfigurace spuštění (umístění Blazor skriptu) se pro vypršení časového limitu serveru použije vlastní hodnota 60 sekund. Interval Keep-Alive (withKeepAliveInterval
) není nastavený a používá výchozí hodnotu 15 sekund.
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
circuit: {
configureSignalR: function (builder) {
builder.withServerTimeout(60000);
}
}
});
</script>
Blazor Server:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
builder.withServerTimeout(60000);
}
});
</script>
Při vytváření připojení rozbočovače v komponentě nastavte časový limit serveru (WithServerTimeout, výchozí hodnota: 30 sekund) na HubConnectionBuilder. Nastavte HandshakeTimeout (výchozí: 15 sekund) na sestavené HubConnection. Ověřte, že časové limity jsou alespoň dvojnásobkem intervalu Keep-Alive (WithKeepAliveInterval/KeepAliveInterval) a že hodnota Keep-Alive je shodná mezi serverem a klientem.
Následující příklad je založen na komponentě Index
v kurzu SignalR s Blazor. Časový limit serveru se zvýší na 60 sekund a časový limit handshake se zvýší na 30 sekund. Interval Keep-Alive není nastavený a používá výchozí hodnotu 15 sekund.
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.WithServerTimeout(TimeSpan.FromSeconds(60))
.Build();
hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);
hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...
await hubConnection.StartAsync();
}
Nastavte následující:
-
serverTimeoutInMilliseconds
(výchozí hodnota: 30 sekund): Nakonfiguruje časový limit serveru zadaný v milisekundách pro připojení rozbočovače okruhu. -
keepAliveIntervalInMilliseconds
(výchozí hodnota: 15 sekund): Interval zadaný v milisekundách, ve kterém připojení odesílá zprávy Keep-Alive.
Časový limit serveru je možné zvýšit a interval Keep-Alive může zůstat stejný. Důležité je, že pokud změníte hodnoty, ujistěte se, že časový limit serveru je alespoň dvojnásobná hodnota intervalu Keep-Alive a že hodnoty intervalu Keep-Alive odpovídají mezi serverem a klientem. Další informace najdete v části Konfigurace SignalR časových limitů a Keep-Alive na klientu.
V následujícím příkladu konfigurace spuštění (umístění Blazor skriptu) se pro vypršení časového limitu serveru použije vlastní hodnota 60 sekund. Interval Keep-Alive (keepAliveIntervalInMilliseconds
) není nastavený a používá výchozí hodnotu 15 sekund.
V Pages/_Host.cshtml
:
<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start({
configureSignalR: function (builder) {
let c = builder.build();
c.serverTimeoutInMilliseconds = 60000;
builder.build = () => {
return c;
};
}
});
</script>
Při vytváření připojení rozbočovače v komponentě nastavte ServerTimeout (výchozí: 30 sekund) a HandshakeTimeout (výchozí: 15 sekund) na vytvořeném HubConnection. Ověřte, že časové limity jsou nejméně dvojnásobkem intervalu Keep-Alive. Ověřte, že interval udržování spojení odpovídá mezi serverem a klientem.
Následující příklad je založen na komponentě Index
v kurzu SignalR s Blazor. Zvýší se ServerTimeout na 60 sekund a HandshakeTimeout zvýší se na 30 sekund. Interval Keep-Alive (KeepAliveInterval) není nastavený a používá výchozí hodnotu 15 sekund.
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.Build();
hubConnection.ServerTimeout = TimeSpan.FromSeconds(60);
hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);
hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...
await hubConnection.StartAsync();
}
Odpojte Blazorokruh SignalR od klienta
Blazor
SignalR Okruh se odpojí při unload
aktivaci události stránky. Chcete-li odpojit obvod pro jiné scénáře, vyvolejte Blazor.disconnect
v příslušné obslužné rutině události. V následujícím příkladu se okruh odpojí, když je stránka skrytá (pagehide
událost):
window.addEventListener('pagehide', () => {
Blazor.disconnect();
});
Další informace o spuštění Blazor viz spuštění ASP.NET Core Blazor.
Obsluha okruhu na straně serveru
Můžete definovat obslužnou rutinu okruhu, která umožňuje spouštění kódu při změnách stavu uživatelského okruhu. Obslužná rutina okruhu je implementována tím, že se odvodí z CircuitHandler a zaregistruje se třída v kontejneru služeb aplikace. Následující příklad obsluhy obvodu sleduje otevřená SignalR připojení.
TrackingCircuitHandler.cs
:
using Microsoft.AspNetCore.Components.Server.Circuits;
public class TrackingCircuitHandler : CircuitHandler
{
private HashSet<Circuit> circuits = new();
public override Task OnConnectionUpAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Add(circuit);
return Task.CompletedTask;
}
public override Task OnConnectionDownAsync(Circuit circuit,
CancellationToken cancellationToken)
{
circuits.Remove(circuit);
return Task.CompletedTask;
}
public int ConnectedCircuits => circuits.Count;
}
Obsluhy okruhu se registrují pomocí DI. Instance s vymezeným oborem se vytvářejí pro každou instanci okruhu. Pomocí TrackingCircuitHandler
v předchozím příkladu se vytvoří singletonová služba, protože musí být sledován stav všech okruhů.
V souboru Program
:
builder.Services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
V Startup.ConfigureServices
z Startup.cs
:
services.AddSingleton<CircuitHandler, TrackingCircuitHandler>();
Pokud metody správce vlastního okruhu vyvolají neošetřenou výjimku, je tato výjimka pro okruh smrtelná. Chcete-li tolerovat výjimky v kódu obslužné rutiny nebo volaných metodách, zabalte kód do jednoho nebo více try-catch
příkazů pomocí zpracování chyb a protokolování.
Když okruh skončí, protože se uživatel odpojil a rámec čistí stav okruhu, rámec zruší rozsah DI okruhu. Zničení rozsahu zničí všechny služby DI v rámci obvodu, které implementují System.IDisposable. Pokud některá služba DI během vyřazení vyvolá neošetřenou výjimku, architektura ji zaznamená do protokolu. Další informace najdete v tématu ASP.NET Core Blazor injektáž závislostí.
Zpracovatel okruhu na straně serveru pro sledování uživatelů pro přizpůsobené služby
Použijte CircuitHandler k zachycení uživatele z AuthenticationStateProvider a nastavte tohoto uživatele ve službě. Další informace a ukázkový kód najdete v tématu ASP.NET Core na straně serveru a Blazor Web App v dalších scénářích zabezpečení.
Uzavření okruhů, pokud neexistují žádné zbývající součásti interaktivního serveru
Komponenty interaktivního serveru zpracovávají události webového uživatelského rozhraní pomocí připojení v reálném čase s prohlížečem označovaným jako okruh. Okruh a jeho přidružený stav se vytvoří, když se vykreslí kořenová součást Interactive Serveru. Okruh se zavře, pokud na stránce nejsou žádné zbývající součásti interaktivního serveru, které uvolní prostředky serveru.
Spusťte SignalR okruh na jiné adrese URL
Zabraňte automatickému spuštění aplikace přidáním autostart="false"
do značky Blazor<script>
(umístění spuštění skriptu Blazor). Ručně vytvořte adresu URL okruhu pomocí Blazor.start
. Následující příklady používají cestu /signalr
.
Blazor Web Apps:
- <script src="_framework/blazor.web.js"></script>
+ <script src="_framework/blazor.web.js" autostart="false"></script>
+ <script>
+ Blazor.start({
+ circuit: {
+ configureSignalR: builder => builder.withUrl("/signalr")
+ },
+ });
+ </script>
Blazor Server:
- <script src="_framework/blazor.server.js"></script>
+ <script src="_framework/blazor.server.js" autostart="false"></script>
+ <script>
+ Blazor.start({
+ configureSignalR: builder => builder.withUrl("/signalr")
+ });
+ </script>
Do souboru MapBlazorHub v serverové aplikaci přidejte následující volání Program
s cestou k hubu do zpracování middlewaru.
Blazor Web Apps:
app.MapBlazorHub("/signalr");
Blazor Server:
Ponechte stávající volání MapBlazorHub v souboru a přidejte nové volání MapBlazorHub se specifikovanou cestou:
app.MapBlazorHub();
+ app.MapBlazorHub("/signalr");
Zosobnění pro ověřování systému Windows
Ověřená připojení rozbočovače (HubConnection) se vytvářejí s UseDefaultCredentials, které označuje použití výchozích přihlašovacích údajů pro požadavky HTTP. Další informace najdete v tématu Ověřování a autorizace v ASP.NET Core SignalR.
Když aplikace běží ve službě IIS Express jako přihlášený uživatel v rámci ověřování systému Windows, což je pravděpodobně osobní nebo pracovní účet uživatele, výchozí přihlašovací údaje jsou přihlašovací údaje přihlášeného uživatele.
Když je aplikace publikovaná ve službě IIS, spustí se ve fondu aplikací Identity. HubConnection se připojí jako účet "uživatel" služby IIS, který je hostitelem aplikace, nikoli jako uživatel, který ke stránce přistupuje.
Implementujte zosobnění s HubConnection, aby se použila identita procházejícího uživatele.
V následujícím příkladu:
- Uživatel z poskytovatele stavu autentizace je přetypován do WindowsIdentity.
- Přístupový token identity je předán WindowsIdentity.RunImpersonatedAsync pomocí kódu, který sestaví a spustí HubConnection.
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (authState?.User.Identity is not null)
{
var user = authState.User.Identity as WindowsIdentity;
if (user is not null)
{
await WindowsIdentity.RunImpersonatedAsync(user.AccessToken,
async () =>
{
hubConnection = new HubConnectionBuilder()
.WithUrl(NavManager.ToAbsoluteUri("/hub"), config =>
{
config.UseDefaultCredentials = true;
})
.WithAutomaticReconnect()
.Build();
hubConnection.On<string>("name", userName =>
{
name = userName;
InvokeAsync(StateHasChanged);
});
await hubConnection.StartAsync();
});
}
}
}
V předchozím kódu je NavManager
NavigationManagera AuthenticationStateProvider
je služební instance AuthenticationStateProvider (AuthenticationStateProvider
dokumentace).
Další prostředky na straně serveru
- Pokyny pro hostování a nasazení na straně serveru: SignalR konfigurace
- Přehled ASP.NET Core SignalR
- Konfigurace SignalR pro ASP.NET Core
- Dokumentace k zabezpečení na straně serveru
- IHttpContextAccessor/HttpContext v aplikacích ASP.NET Core Blazor
- Události opětovného připojení na straně serveru a události životního cyklu komponent
- Co je služba Azure SignalR ?
- Průvodce výkonem pro službu Azure SignalR
- Publikování aplikace ASP.NET Core SignalR do služby Aplikace Azure Service
-
Blazor ukázkový GitHub repozitář (
dotnet/blazor-samples
) (jak stáhnout)