Delen via


SignalR Service schalen met meerdere exemplaren

SignalR Service SDK ondersteunt meerdere eindpunten voor SignalR Service-exemplaren. U kunt deze functie gebruiken om de gelijktijdige verbindingen te schalen of te gebruiken voor berichten tussen regio's.

Belangrijk

Onbewerkte verbindingsreeks worden alleen in dit artikel weergegeven voor demonstratiedoeleinden.

Een verbindingsreeks bevat de autorisatiegegevens die nodig zijn voor uw toepassing om toegang te krijgen tot Azure SignalR Service. De toegangssleutel in de verbindingsreeks is vergelijkbaar met een hoofdwachtwoord voor uw service. Beveilig uw toegangssleutels altijd in productieomgevingen. Gebruik Azure Key Vault om uw sleutels veilig te beheren en te roteren en uw verbindingsreeks te beveiligen met behulp van Microsoft Entra-id en toegang te autoriseren met Microsoft Entra ID.

Vermijd het distribueren van toegangssleutels naar andere gebruikers, het coderen ervan of het opslaan van ze ergens in tekst zonder opmaak die toegankelijk is voor anderen. Draai uw sleutels als u denkt dat ze mogelijk zijn aangetast.

Voor ASP.NET Core

Meerdere eindpunten toevoegen vanuit de configuratie

Onbewerkte verbindingsreeks worden alleen in dit artikel weergegeven voor demonstratiedoeleinden. Beveilig uw toegangssleutels altijd in productieomgevingen. Gebruik Azure Key Vault om uw sleutels veilig te beheren en te roteren en uw verbindingsreeks te beveiligen met behulp van Microsoft Entra-id en toegang te autoriseren met Microsoft Entra ID.

Configureer met sleutel Azure:SignalR:ConnectionString of Azure:SignalR:ConnectionString: voor SignalR Service verbindingsreeks.

Als de sleutel begint met Azure:SignalR:ConnectionString:, moet deze de indeling Azure:SignalR:ConnectionString:{Name}:{EndpointType}hebben, waar Name en EndpointType eigenschappen van het ServiceEndpoint object zijn en toegankelijk zijn vanuit code.

U kunt meerdere exemplaren verbindingsreeks toevoegen met behulp van de volgende dotnet opdrachten:

dotnet user-secrets set Azure:SignalR:ConnectionString:east-region-a <ConnectionString1>
dotnet user-secrets set Azure:SignalR:ConnectionString:east-region-b:primary <ConnectionString2>
dotnet user-secrets set Azure:SignalR:ConnectionString:backup:secondary <ConnectionString3>

Meerdere eindpunten toevoegen vanuit code

Een ServiceEndpoint klasse beschrijft de eigenschappen van een Azure SignalR Service-eindpunt. U kunt meerdere exemplaareindpunten configureren wanneer u azure SignalR Service SDK gebruikt via:

services.AddSignalR()
        .AddAzureSignalR(options =>
        {
            options.Endpoints = new ServiceEndpoint[]
            {
                // Note: this is just a demonstration of how to set options.Endpoints
                // Having ConnectionStrings explicitly set inside the code is not encouraged
                // You can fetch it from a safe place such as Azure KeyVault
                new ServiceEndpoint("<ConnectionString0>"),
                new ServiceEndpoint("<ConnectionString1>", type: EndpointType.Primary, name: "east-region-a"),
                new ServiceEndpoint("<ConnectionString2>", type: EndpointType.Primary, name: "east-region-b"),
                new ServiceEndpoint("<ConnectionString3>", type: EndpointType.Secondary, name: "backup"),
            };
        });

Eindpuntrouter aanpassen

De SDK gebruikt standaard de DefaultEndpointRouter om eindpunten op te halen.

Standaardgedrag

  1. Routering van clientaanvragen:

    Wanneer client /negotiate met de app-server. Standaard selecteert SDK willekeurig één eindpunt in de set beschikbare service-eindpunten.

  2. Routering van serverberichten:

    Wanneer u een bericht naar een specifieke verbinding verzendt en de doelverbinding naar de huidige server wordt gerouteerd, gaat het bericht rechtstreeks naar dat verbonden eindpunt. Anders worden de berichten uitgezonden naar elk Azure SignalR-eindpunt.

Routeringsalgoritmen aanpassen

U kunt uw eigen router maken wanneer u speciale kennis hebt om te bepalen naar welke eindpunten de berichten moeten gaan.

In het volgende voorbeeld wordt een aangepaste router gedefinieerd waarmee berichten worden gerouteerd met een groep die begint met east- het eindpunt met de naam east:

private class CustomRouter : EndpointRouterDecorator
{
    public override IEnumerable<ServiceEndpoint> GetEndpointsForGroup(string groupName, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the group broadcast behavior, if the group name starts with "east-", only send messages to endpoints inside east
        if (groupName.StartsWith("east-"))
        {
            return endpoints.Where(e => e.Name.StartsWith("east-"));
        }

        return base.GetEndpointsForGroup(groupName, endpoints);
    }
}

In het volgende voorbeeld wordt het standaardonderhandelingsgedrag overschreven en wordt het eindpunt geselecteerd, afhankelijk van de locatie van de app-server.

private class CustomRouter : EndpointRouterDecorator
{    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
          // Sample code showing how to choose endpoints based on the incoming request endpoint query
          var endpointName = context.Request.Query["endpoint"].FirstOrDefault() ?? "";
          // Select from the available endpoints, don't construct a new ServiceEndpoint object here
          return endpoints.FirstOrDefault(s => s.Name == endpointName && s.Online) // Get the endpoint with name matching the incoming request
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Vergeet niet om de router te registreren bij de DI-container met behulp van:

services.AddSingleton(typeof(IEndpointRouter), typeof(CustomRouter));
services.AddSignalR()
        .AddAzureSignalR(
            options =>
            {
                options.Endpoints = new ServiceEndpoint[]
                {
                    new ServiceEndpoint(name: "east", connectionString: "<connectionString1>"),
                    new ServiceEndpoint(name: "west", connectionString: "<connectionString2>"),
                    new ServiceEndpoint("<connectionString3>")
                };
            });

ServiceOptions.Endpoints ondersteunt ook hot-reload. In de onderstaande voorbeeldcode ziet u hoe u verbindingsreeks s laadt vanuit een configuratiesectie en openbare URL die wordt weergegeven door omgekeerde proxy's van een andere, en zolang de configuratie ondersteuning biedt voor dynamisch opnieuw laden, kunnen de eindpunten tegelijkertijd worden bijgewerkt.

services.Configure<ServiceOptions>(o =>
{
        o.Endpoints = [
            new ServiceEndpoint(Configuration["ConnectionStrings:AzureSignalR:East"], name: "east")
            {
                ClientEndpoint = new Uri(Configuration.GetValue<string>("PublicClientEndpoints:East"))
            },
            new ServiceEndpoint(Configuration["ConnectionStrings:AzureSignalR:West"], name: "west")
            {
                ClientEndpoint = new Uri(Configuration.GetValue<string>("PublicClientEndpoints:West"))
            },
        ];
});

Voor ASP.NET

Meerdere eindpunten toevoegen vanuit de configuratie

Configuratie met sleutel Azure:SignalR:ConnectionString of Azure:SignalR:ConnectionString: voor SignalR Service verbindingsreeks.

Als de sleutel begint met Azure:SignalR:ConnectionString:, moet deze in indeling Azure:SignalR:ConnectionString:{Name}:{EndpointType}zijn, waar Name en EndpointType eigenschappen van het ServiceEndpoint object zijn en toegankelijk zijn vanuit code.

U kunt meerdere exemplaren verbindingsreeks s toevoegen aanweb.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="Azure:SignalR:ConnectionString" connectionString="<ConnectionString1>"/>
    <add name="Azure:SignalR:ConnectionString:en-us" connectionString="<ConnectionString2>"/>
    <add name="Azure:SignalR:ConnectionString:zh-cn:secondary" connectionString="<ConnectionString3>"/>
    <add name="Azure:SignalR:ConnectionString:Backup:secondary" connectionString="<ConnectionString4>"/>
  </connectionStrings>
  ...
</configuration>

Meerdere eindpunten toevoegen vanuit code

Een ServiceEndpoint klasse beschrijft de eigenschappen van een Azure SignalR Service-eindpunt. U kunt meerdere exemplaareindpunten configureren wanneer u azure SignalR Service SDK gebruikt via:

app.MapAzureSignalR(
    this.GetType().FullName,
    options => {
            options.Endpoints = new ServiceEndpoint[]
            {
                // Note: this is just a demonstration of how to set options. Endpoints
                // Having ConnectionStrings explicitly set inside the code is not encouraged.
                // You can fetch it from a safe place such as Azure KeyVault
                new ServiceEndpoint("<ConnectionString1>"),
                new ServiceEndpoint("<ConnectionString2>"),
                new ServiceEndpoint("<ConnectionString3>"),
            }
        });

Een router aanpassen

Het enige verschil tussen ASP.NET SignalR en ASP.NET Core SignalR is het http-contexttype voor GetNegotiateEndpoint. Voor ASP.NET SignalR is het van het type IOwinContext .

De volgende code is een aangepast onderhandelingsvoorbeeld voor ASP.NET SignalR:

private class CustomRouter : EndpointRouterDecorator
{
    public override ServiceEndpoint GetNegotiateEndpoint(IOwinContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Sample code showing how to choose endpoints based on the incoming request endpoint query
        var endpointName = context.Request.Query["endpoint"] ?? "";
        // Select from the available endpoints, don't construct a new ServiceEndpoint object here
        return endpoints.FirstOrDefault(s => s.Name == endpointName && s.Online) // Get the endpoint with name matching the incoming request
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Vergeet niet om de router te registreren bij de DI-container met behulp van:

var hub = new HubConfiguration();
var router = new CustomRouter();
hub.Resolver.Register(typeof(IEndpointRouter), () => router);
app.MapAzureSignalR(GetType().FullName, hub, options => {
    options.Endpoints = new ServiceEndpoint[]
                {
                    new ServiceEndpoint(name: "east", connectionString: "<connectionString1>"),
                    new ServiceEndpoint(name: "west", connectionString: "<connectionString2>"),
                    new ServiceEndpoint("<connectionString3>")
                };
});

Metrische gegevens voor service-eindpunt

Als u een geavanceerde router wilt inschakelen, biedt SignalR Server SDK meerdere metrische gegevens om de server te helpen slimme beslissingen te nemen. De eigenschappen bevinden zich onder ServiceEndpoint.EndpointMetrics.

Naam meetwaarde Beschrijving
ClientConnectionCount Totaal aantal gelijktijdige clientverbindingen op alle hubs voor het service-eindpunt
ServerConnectionCount Totaal aantal gelijktijdige serververbindingen op alle hubs voor het service-eindpunt
ConnectionCapacity Totaal verbindingsquotum voor het service-eindpunt, inclusief client- en serververbindingen

De volgende code is een voorbeeld van het aanpassen van een router op ClientConnectionCountbasis van .

private class CustomRouter : EndpointRouterDecorator
{
    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        return endpoints.OrderBy(x => x.EndpointMetrics.ClientConnectionCount).FirstOrDefault(x => x.Online) // Get the available endpoint with minimal clients load
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Dynamic Scale ServiceEndpoints

Vanaf SDK-versie 1.5.0 schakelen we ServiceEndpoints voor dynamische schaal in voor ASP.NET Core-versie. U hoeft de app-server dus niet opnieuw op te starten wanneer u een ServiceEndpoint wilt toevoegen of verwijderen. Omdat ASP.NET Core ondersteuning biedt voor een standaardconfiguratie zoals appsettings.json bij reloadOnChange: true, hoeft u geen code te wijzigen en wordt deze door de aard ondersteund. En als u een aangepaste configuratie wilt toevoegen en wilt werken met hot-reload, raadpleegt u Configuratie in ASP.NET Core.

Notitie

Gezien de tijd van het instellen van de verbinding tussen server/service en client/service kan verschillen, om ervoor te zorgen dat er tijdens het schaalproces geen berichten verloren gaan, hebben we een faseringsperiode die wacht tot serververbindingen gereed zijn voordat de nieuwe ServiceEndpoint voor clients wordt geopend. Meestal duurt het seconden om te voltooien en kunt u een logboekbericht zien, zoals Succeed in adding endpoint: '{endpoint}' dit aangeeft dat het proces is voltooid.

In sommige verwachte situaties, zoals netwerkproblemen tussen regio's of inconsistenties in de configuratie op verschillende app-servers, is de faseringsperiode mogelijk niet correct voltooid. In deze gevallen wordt aangeraden de app-server opnieuw op te starten wanneer het schaalproces niet goed werkt.

De standaardtime-outperiode voor de schaal is vijf minuten en kan worden aangepast door de waarde in ServiceOptions.ServiceScaleTimeoutte wijzigen. Als u veel app-servers hebt, wordt u aangeraden om de waarde iets meer uit te breiden.

Notitie

Momenteel wordt de functie voor meerdere eindpunten alleen ondersteund voor Persistent het transporttype.

Voor SignalR Functions-extensies

Configuratie

Als u meerdere SignalR Service-exemplaren wilt inschakelen, moet u het volgende doen:

  1. Gebruik Persistent transporttype.

    Het standaardtransporttype is Transient de modus. Voeg de volgende vermelding toe aan uw local.settings.json bestand of de toepassingsinstelling in Azure.

    {
        "AzureSignalRServiceTransportType":"Persistent"
    }
    

    Notitie

    Wanneer u overschakelt van Transient de modus naar Persistent de modus, kan het gedrag van JSON-serialisatie worden gewijzigd, omdat onder Transient de modus bibliotheek Newtonsoft.Json wordt gebruikt om argumenten van hubmethoden te serialiseren, maar onder Persistent de modus wordt System.Text.Json bibliotheek als standaard gebruikt. System.Text.Json heeft enkele belangrijke verschillen in standaardgedrag met Newtonsoft.Json. Als u de modus wilt Persistent gebruikenNewtonsoft.Json, kunt u een configuratie-item toevoegen: "Azure:SignalR:HubProtocol":"NewtonsoftJson" in local.settings.json bestand of Azure__SignalR__HubProtocol=NewtonsoftJson in Azure Portal.

  2. Configureer meerdere vermeldingen voor SignalR Service-eindpunten in uw configuratie.

    We gebruiken een ServiceEndpoint object om een SignalR Service-exemplaar weer te geven. U kunt een service-eindpunt definiëren met <EndpointName> <EndpointType> de vermeldingssleutel en de verbindingsreeks in de invoerwaarde. De sleutels hebben de volgende indeling:

    Azure:SignalR:Endpoints:<EndpointName>:<EndpointType>
    

    <EndpointType> is optioneel en wordt standaard ingesteld op primary. Zie de voorbeelden hieronder:

    {
        "Azure:SignalR:Endpoints:EastUs":"<ConnectionString>",
    
        "Azure:SignalR:Endpoints:EastUs2:Secondary":"<ConnectionString>",
    
        "Azure:SignalR:Endpoints:WestUs:Primary":"<ConnectionString>"
    }
    

    Notitie

    • Wanneer u Azure SignalR-eindpunten configureert in de App Service in Azure Portal, vergeet dan niet om het dubbele onderstrepingsteken in de sleutels te vervangen ":" "__". Zie omgevingsvariabelen om redenen.

    • De verbindingsreeks die is geconfigureerd met de sleutel {ConnectionStringSetting} (standaard ingesteld op 'AzureSignalRConnectionString') wordt ook herkend als een primair service-eindpunt met een lege naam. Deze configuratiestijl wordt echter niet aanbevolen voor meerdere eindpunten.

Routering

Standaardgedrag

De functiebinding maakt standaard gebruik van de DefaultEndpointRouter om eindpunten op te halen.

  • Clientroutering: Selecteer willekeurig één eindpunt van primaire online-eindpunten . Als alle primaire eindpunten offline zijn, selecteert u willekeurig één secundair online-eindpunt . Als de selectie opnieuw mislukt, wordt er een uitzondering gegenereerd.

  • Routering van serverberichten: alle service-eindpunten worden geretourneerd.

Aanpassing

C#-model voor in-proces

Dit zijn de stappen:

  1. Implementeer een aangepaste router. U kunt gebruikmaken van informatie van ServiceEndpoint waaruit u routeringsbeslissing kunt nemen. Zie de handleiding hier: customize-route-algorithm. Houd er rekening mee dat de HTTP-trigger is vereist in de onderhandelingsfunctie wanneer u een aangepaste onderhandelingsmethode nodig hebt HttpContext .

  2. Registreer de router bij DI-container.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.SignalR;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(SimpleChatV3.Startup))]
namespace SimpleChatV3
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IEndpointRouter, CustomizedRouter>();
        }
    }
}
Model voor geïsoleerd proces

Voor functies die worden uitgevoerd op een geïsoleerd procesmodel ondersteunen we het opgeven van doeleindpunten in elke aanvraag. U gebruikt nieuwe bindingstypen om eindpuntgegevens op te halen.

Clientroutering

De SignalRConnectionInfo binding selecteert één eindpunt volgens de standaardrouteringsregel. Als u routeringsregel wilt aanpassen, moet u binding gebruiken SignalRNegotiation in plaats van SignalRConnectionInfo binding.

SignalRNegotiation bindingsconfiguratie-eigenschappen zijn hetzelfde als SignalRConnectionInfo. Hier volgt een function.json voorbeeldbestand:

{
    "type": "signalRNegotiation",
    "name": "negotiationContext",
    "hubName": "<HubName>",
    "direction": "in"
}

U kunt ook andere bindingsgegevens toevoegen, zoals userId, idToken en claimTypeList net als SignalRConnectionInfo.

Het object dat u op basis van SignalRNegotiation binding krijgt, heeft de volgende indeling:

{
    "endpoints": [
        {
            "endpointType": "Primary",
            "name": "<EndpointName>",
            "endpoint": "https://****.service.signalr.net",
            "online": true,
            "connectionInfo": {
                "url": "<client-access-url>",
                "accessToken": "<client-access-token>"
            }
        },
        {
            "...": "..."
        }
    ]
}

Hier volgt een JavaScript-gebruiksvoorbeeld van SignalRNegotiation binding:

module.exports = function (context, req, negotiationContext) {
    var userId = req.query.userId;
    if (userId.startsWith("east-")) {
        //return the first endpoint whose name starts with "east-" and status is online.
        context.res.body = negotiationContext.endpoints.find(endpoint => endpoint.name.startsWith("east-") && endpoint.online).connectionInfo;
    }
    else {
        //return the first online endpoint
        context.res.body = negotiationContext.endpoints.filter(endpoint => endpoint.online)[0].connectionInfo;
    }
}
Berichtenroutering

Berichten of acties routeren heeft twee bindingstypen nodig om samen te werken. Over het algemeen hebt u eerst een nieuw type SignalREndpoints invoerbinding nodig om alle beschikbare eindpuntgegevens op te halen. Vervolgens filtert u de eindpunten en haalt u een matrix op met alle eindpunten waarnaar u wilt verzenden. Ten slotte geeft u de doeleindpunten op in de SignalR uitvoerbinding.

Dit zijn de SignalREndpoints bindingsconfiguratie-eigenschappen in functions.json het bestand:

{
      "type": "signalREndpoints",
      "direction": "in",
      "name": "endpoints",
      "hubName": "<HubName>"
}

Het object waaruit u krijgt SignalREndpoints , is een matrix met eindpunten die elk worden weergegeven als een JSON-object met het volgende schema:

{
    "endpointType": "<EndpointType>",
    "name": "<EndpointName>",
    "endpoint": "https://****.service.signalr.net",
    "online": true
}

Nadat u de doeleindpuntmatrix hebt opgehaald, voegt u een endpoints eigenschap toe aan het uitvoerbindingsobject. Dit is een JavaScript-voorbeeld:

module.exports = function (context, req, endpoints) {
    var targetEndpoints = endpoints.filter(endpoint => endpoint.name.startsWith("east-"));
    context.bindings.signalRMessages = [{
        "target": "chat",
        "arguments": ["hello-world"],
        "endpoints": targetEndpoints,
    }];
    context.done();
}

Voor beheer-SDK

Meerdere eindpunten toevoegen vanuit de configuratie

Configureer met sleutel Azure:SignalR:Endpoints voor SignalR Service verbindingsreeks. De sleutel moet de indeling Azure:SignalR:Endpoints:{Name}:{EndpointType}hebben, waar Name en EndpointType zijn eigenschappen van het ServiceEndpoint object en zijn toegankelijk vanuit code.

U kunt meerdere exemplaren verbindingsreeks toevoegen met behulp van de volgende dotnet opdrachten:

dotnet user-secrets set Azure:SignalR:Endpoints:east-region-a <ConnectionString1>
dotnet user-secrets set Azure:SignalR:Endpoints:east-region-b:primary <ConnectionString2>
dotnet user-secrets set Azure:SignalR:Endpoints:backup:secondary <ConnectionString3>

Meerdere eindpunten toevoegen vanuit code

Een ServiceEndpoint klasse beschrijft de eigenschappen van een Azure SignalR Service-eindpunt. U kunt meerdere exemplaareindpunten configureren wanneer u de Azure SignalR Management SDK gebruikt via:

var serviceManager = new ServiceManagerBuilder()
                    .WithOptions(option =>
                    {
                        options.Endpoints = new ServiceEndpoint[]
                        {
                            // Note: this is just a demonstration of how to set options.Endpoints
                            // Having ConnectionStrings explicitly set inside the code is not encouraged
                            // You can fetch it from a safe place such as Azure KeyVault
                            new ServiceEndpoint("<ConnectionString0>"),
                            new ServiceEndpoint("<ConnectionString1>", type: EndpointType.Primary, name: "east-region-a"),
                            new ServiceEndpoint("<ConnectionString2>", type: EndpointType.Primary, name: "east-region-b"),
                            new ServiceEndpoint("<ConnectionString3>", type: EndpointType.Secondary, name: "backup"),
                        };
                    })
                    .BuildServiceManager();

Eindpuntrouter aanpassen

De SDK gebruikt standaard de DefaultEndpointRouter om eindpunten op te halen.

Standaardgedrag

  • Routering van clientaanvragen:

    Wanneer client /negotiate met de app-server. Standaard selecteert SDK willekeurig één eindpunt in de set beschikbare service-eindpunten.

  • Routering van serverberichten:

    Wanneer u een bericht naar een specifieke verbinding verzendt en de doelverbinding naar de huidige server wordt gerouteerd, gaat het bericht rechtstreeks naar dat verbonden eindpunt. Anders worden de berichten uitgezonden naar elk Azure SignalR-eindpunt.

Routeringsalgoritmen aanpassen

U kunt uw eigen router maken wanneer u speciale kennis hebt om te bepalen naar welke eindpunten de berichten moeten gaan.

In het volgende voorbeeld wordt een aangepaste router gedefinieerd waarmee berichten worden gerouteerd met een groep die begint met east- het eindpunt met de naam east:

private class CustomRouter : EndpointRouterDecorator
{
    public override IEnumerable<ServiceEndpoint> GetEndpointsForGroup(string groupName, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the group broadcast behavior, if the group name starts with "east-", only send messages to endpoints inside east
        if (groupName.StartsWith("east-"))
        {
            return endpoints.Where(e => e.Name.StartsWith("east-"));
        }

        return base.GetEndpointsForGroup(groupName, endpoints);
    }
}

In het volgende voorbeeld wordt het standaardonderhandelingsgedrag overschreven en wordt het eindpunt geselecteerd, afhankelijk van de locatie van de app-server.

private class CustomRouter : EndpointRouterDecorator
{    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the negotiate behavior to get the endpoint from query string
        var endpointName = context.Request.Query["endpoint"];
        if (endpointName.Count == 0)
        {
            context.Response.StatusCode = 400;
            var response = Encoding.UTF8.GetBytes("Invalid request");
            context.Response.Body.Write(response, 0, response.Length);
            return null;
        }

        return endpoints.FirstOrDefault(s => s.Name == endpointName && s.Online) // Get the endpoint with name matching the incoming request
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Vergeet niet om de router te registreren bij de DI-container met behulp van:

var serviceManager = new ServiceManagerBuilder()
                    .WithOptions(option =>
                    {
                        options.Endpoints = new ServiceEndpoint[]
                        {
                            // Note: this is just a demonstration of how to set options.Endpoints
                            // Having ConnectionStrings explicitly set inside the code is not encouraged
                            // You can fetch it from a safe place such as Azure KeyVault
                            new ServiceEndpoint("<ConnectionString0>"),
                            new ServiceEndpoint("<ConnectionString1>", type: EndpointType.Primary, name: "east-region-a"),
                            new ServiceEndpoint("<ConnectionString2>", type: EndpointType.Primary, name: "east-region-b"),
                            new ServiceEndpoint("<ConnectionString3>", type: EndpointType.Secondary, name: "backup"),
                        };
                    })
                    .WithRouter(new CustomRouter())
                    .BuildServiceManager();

Configuratie in scenario's tussen regio's

Het ServiceEndpoint object heeft een EndpointType eigenschap met waarde primary of secondary.

Primaire eindpunten zijn voorkeurseindpunten om clientverkeer te ontvangen, omdat ze betrouwbaardere netwerkverbindingen hebben. Secundaire eindpunten hebben minder betrouwbare netwerkverbindingen en worden alleen gebruikt voor server-naar-clientverkeer. Secundaire eindpunten worden bijvoorbeeld gebruikt voor het uitzenden van berichten in plaats van client-naar-serververkeer.

In gevallen tussen regio's kan het netwerk instabiel zijn. Voor een app-server in VS - oost is primary het SignalR Service-eindpunt in dezelfde regio VS - oost en eindpunten in andere regio's gemarkeerd als secondary. In deze configuratie kunnen service-eindpunten in andere regio's berichten ontvangen van deze app-server voor VS - oost, maar er worden geen clients tussen regio's doorgestuurd naar deze app-server. In het volgende diagram ziet u de architectuur:

Cross-Geo Infra

Wanneer een client probeert /negotiate met de app-server met een standaardrouter, selecteert de SDK willekeurig één eindpunt uit de set beschikbare primary eindpunten. Wanneer het primaire eindpunt niet beschikbaar is, selecteert de SDK willekeurig uit alle beschikbare secondary eindpunten. Het eindpunt wordt gemarkeerd als beschikbaar wanneer de verbinding tussen de server en het service-eindpunt actief is.

In een scenario tussen regio's, wanneer een client probeert /negotiate met de app-server die wordt gehost in VS - oost, wordt standaard altijd het primary eindpunt in dezelfde regio geretourneerd. Wanneer niet alle EINDPUNTen vs - oost beschikbaar zijn, stuurt de router de client om naar eindpunten in andere regio's. In de volgende failoversectie wordt het scenario gedetailleerd beschreven.

Normale onderhandelingen

Failover

Wanneer er geen primary eindpunt beschikbaar is, kiest de client /negotiate uit de beschikbare secondary eindpunten. Dit failovermechanisme vereist dat elk eindpunt als eindpunt primary fungeert voor ten minste één app-server.

Diagram van het failovermechanismeproces.

Volgende stappen

U kunt meerdere eindpunten gebruiken in scenario's met hoge beschikbaarheid en herstel na noodgevallen.