Improve initialization and SignalR configuration
Fixes: #6887 and #6887 and #5624 Adds support for calling Blazor.start({...}) and passing in a configuration object. For now all you can configure is the SignalR HubConnectionBuilder. This is a priority right now because we want to make configuring SignalR's logging accessible.
This commit is contained in:
parent
555b506a97
commit
f2e9ef3441
|
|
@ -2,7 +2,7 @@ import '@dotnet/jsinterop';
|
|||
import './GlobalExports';
|
||||
import * as signalR from '@aspnet/signalr';
|
||||
import { MessagePackHubProtocol } from '@aspnet/signalr-protocol-msgpack';
|
||||
import { fetchBootConfigAsync, loadEmbeddedResourcesAsync } from './BootCommon';
|
||||
import { fetchBootConfigAsync, loadEmbeddedResourcesAsync, shouldAutoStart } from './BootCommon';
|
||||
import { CircuitHandler } from './Platform/Circuits/CircuitHandler';
|
||||
import { AutoReconnectCircuitHandler } from './Platform/Circuits/AutoReconnectCircuitHandler';
|
||||
import RenderQueue from './Platform/Circuits/RenderQueue';
|
||||
|
|
@ -10,9 +10,21 @@ import { ConsoleLogger } from './Platform/Logging/Loggers';
|
|||
import { LogLevel, ILogger } from './Platform/Logging/ILogger';
|
||||
import { discoverPrerenderedCircuits, startCircuit } from './Platform/Circuits/CircuitManager';
|
||||
|
||||
let renderingFailed = false;
|
||||
|
||||
async function boot(): Promise<void> {
|
||||
type SignalRBuilder = (builder: signalR.HubConnectionBuilder) => void;
|
||||
interface BlazorOptions {
|
||||
configureSignalR?: SignalRBuilder,
|
||||
};
|
||||
|
||||
let renderingFailed = false;
|
||||
let started = false;
|
||||
|
||||
async function boot(options?: BlazorOptions): Promise<void> {
|
||||
|
||||
if (started) {
|
||||
throw new Error('Blazor has already started.');
|
||||
}
|
||||
started = true;
|
||||
|
||||
// For development.
|
||||
// Simply put a break point here and modify the log level during
|
||||
|
|
@ -30,7 +42,9 @@ async function boot(): Promise<void> {
|
|||
return loadEmbeddedResourcesAsync(bootConfig);
|
||||
});
|
||||
|
||||
const initialConnection = await initializeConnection(circuitHandlers, logger);
|
||||
// pass options.configureSignalR to configure the signalR.HubConnectionBuilder
|
||||
const configureSignalR = (options && options.configureSignalR) || null;
|
||||
const initialConnection = await initializeConnection(configureSignalR, circuitHandlers, logger);
|
||||
|
||||
const circuits = discoverPrerenderedCircuits(document);
|
||||
for (let i = 0; i < circuits.length; i++) {
|
||||
|
|
@ -55,7 +69,7 @@ async function boot(): Promise<void> {
|
|||
// We can't reconnect after a failure, so exit early.
|
||||
return false;
|
||||
}
|
||||
const reconnection = await initializeConnection(circuitHandlers, logger);
|
||||
const reconnection = await initializeConnection(configureSignalR, circuitHandlers, logger);
|
||||
const results = await Promise.all(circuits.map(circuit => circuit.reconnect(reconnection)));
|
||||
|
||||
if (reconnectionFailed(results)) {
|
||||
|
|
@ -81,14 +95,20 @@ async function boot(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
async function initializeConnection(circuitHandlers: CircuitHandler[], logger: ILogger): Promise<signalR.HubConnection> {
|
||||
async function initializeConnection(configureSignalR: SignalRBuilder | null, circuitHandlers: CircuitHandler[], logger: ILogger): Promise<signalR.HubConnection> {
|
||||
|
||||
const hubProtocol = new MessagePackHubProtocol();
|
||||
(hubProtocol as any).name = 'blazorpack';
|
||||
const connection = new signalR.HubConnectionBuilder()
|
||||
|
||||
const connectionBuilder = new signalR.HubConnectionBuilder()
|
||||
.withUrl('_blazor')
|
||||
.withHubProtocol(hubProtocol)
|
||||
.configureLogging(signalR.LogLevel.Information)
|
||||
.build();
|
||||
.withHubProtocol(hubProtocol);
|
||||
|
||||
if (configureSignalR) {
|
||||
configureSignalR(connectionBuilder);
|
||||
}
|
||||
|
||||
const connection = connectionBuilder.build();
|
||||
|
||||
connection.on('JS.BeginInvokeJS', DotNet.jsCallDispatcher.beginInvokeJSFromDotNet);
|
||||
connection.on('JS.RenderBatch', (browserRendererId: number, batchId: number, batchData: Uint8Array) => {
|
||||
|
|
@ -131,4 +151,7 @@ function unhandledError(connection: signalR.HubConnection, err: Error, logger: I
|
|||
}
|
||||
}
|
||||
|
||||
boot();
|
||||
window['Blazor'].start = boot;
|
||||
if (shouldAutoStart()) {
|
||||
boot();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,17 @@ import { getAssemblyNameFromUrl } from './Platform/Url';
|
|||
import { renderBatch } from './Rendering/Renderer';
|
||||
import { SharedMemoryRenderBatch } from './Rendering/RenderBatch/SharedMemoryRenderBatch';
|
||||
import { Pointer } from './Platform/Platform';
|
||||
import { fetchBootConfigAsync, loadEmbeddedResourcesAsync } from './BootCommon';
|
||||
import { fetchBootConfigAsync, loadEmbeddedResourcesAsync, shouldAutoStart } from './BootCommon';
|
||||
|
||||
let started = false;
|
||||
|
||||
async function boot(options?: any) {
|
||||
|
||||
if (started) {
|
||||
throw new Error('Blazor has already started.');
|
||||
}
|
||||
started = true;
|
||||
|
||||
async function boot() {
|
||||
// Configure environment for execution under Mono WebAssembly with shared-memory rendering
|
||||
const platform = Environment.setPlatform(monoPlatform);
|
||||
window['Blazor'].platform = platform;
|
||||
|
|
@ -43,4 +51,7 @@ async function boot() {
|
|||
platform.callEntryPoint(mainAssemblyName, bootConfig.entryPoint, []);
|
||||
}
|
||||
|
||||
boot();
|
||||
window['Blazor'].start = boot;
|
||||
if (shouldAutoStart()) {
|
||||
boot();
|
||||
}
|
||||
|
|
@ -37,3 +37,10 @@ interface BootJsonData {
|
|||
jsReferences: string[];
|
||||
linkerEnabled: boolean;
|
||||
}
|
||||
|
||||
// Tells you if the script was added without <script src="..." autostart="false"></script>
|
||||
export function shouldAutoStart() {
|
||||
return document &&
|
||||
document.currentScript &&
|
||||
document.currentScript.getAttribute('autostart') !== 'false';
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
import { platform } from './Environment';
|
||||
import { navigateTo, internalFunctions as uriHelperInternalFunctions } from './Services/UriHelper';
|
||||
import { internalFunctions as httpInternalFunctions } from './Services/Http';
|
||||
import { attachRootComponentToElement } from './Rendering/Renderer';
|
||||
import { Pointer } from './Platform/Platform';
|
||||
|
||||
// Make the following APIs available in global scope for invocation from JS
|
||||
window['Blazor'] = {
|
||||
|
|
@ -13,4 +11,4 @@ window['Blazor'] = {
|
|||
http: httpInternalFunctions,
|
||||
uriHelper: uriHelperInternalFunctions
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -210,6 +210,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
..\..\.editorconfig = ..\..\.editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Components.Prerendering", "..\Mvc\Mvc.Components.Prerendering\src\Microsoft.AspNetCore.Mvc.Components.Prerendering.csproj", "{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -1324,6 +1326,18 @@ Global
|
|||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x64.Build.0 = Debug|Any CPU
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x86.ActiveCfg = Debug|Any CPU
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4}.Release|x86.Build.0 = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -1423,6 +1437,7 @@ Global
|
|||
{04262990-929C-42BF-85A9-21C25FA95617} = {2FC10057-7A0A-4E34-8302-879925BC0102}
|
||||
{DC47C40A-FC38-44E4-94A4-ADE794E76309} = {2FC10057-7A0A-4E34-8302-879925BC0102}
|
||||
{9088E4E4-B855-457F-AE9E-D86709A5E1F4} = {7260DED9-22A9-4E9D-92F4-5E8A4404DEAF}
|
||||
{3A4132B6-60DA-43A0-8E7B-4BF346F3247C} = {2FC10057-7A0A-4E34-8302-879925BC0102}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {CC3C47E1-AD1A-4619-9CD3-E08A0148E5CE}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Basic test app</title>
|
||||
<base href="/subdir/" />
|
||||
<base href="/subdir/" />
|
||||
<link href="style.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,13 @@
|
|||
|
||||
<app>@(await Html.RenderComponentAsync<App>(new { Name="Guest" }))</app>
|
||||
|
||||
<script src="_framework/components.server.js"></script>
|
||||
|
||||
<script src="_framework/components.server.js" autostart="false"></script>
|
||||
<script>
|
||||
Blazor.start({
|
||||
configureSignalR: function (builder) {
|
||||
builder.configureLogging(2); // LogLevel.Information
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -15,15 +15,11 @@
|
|||
interactive states, we only load the .js file when told to.
|
||||
*@
|
||||
<hr />
|
||||
<button id="load-boot-script" onclick="loadBootScript(event)">Load boot script</button>
|
||||
<script>
|
||||
function loadBootScript(event) {
|
||||
event.srcElement.disabled = true;
|
||||
var scriptElem = document.createElement('script');
|
||||
scriptElem.src = '_framework/components.server.js';
|
||||
document.body.appendChild(scriptElem);
|
||||
}
|
||||
|
||||
<button id="load-boot-script" onclick="Blazor.start()">Load boot script</button>
|
||||
|
||||
<script src="_framework/components.server.js" autostart="false"></script>
|
||||
<script>
|
||||
// Used by InteropOnInitializationComponent
|
||||
function setElementValue(element, newValue) {
|
||||
element.value = newValue;
|
||||
|
|
|
|||
Loading…
Reference in New Issue