Ontwikkeling en configuratie van Azure Functions met Azure SignalR Service

Azure Functions-toepassingen kunnen de Azure SignalR Service-bindingen gebruiken om realtime mogelijkheden toe te voegen. Clienttoepassingen gebruiken client-SDK's die beschikbaar zijn in verschillende talen om verbinding te maken met Azure SignalR Service en realtime berichten te ontvangen.

In dit artikel worden de concepten beschreven voor het ontwikkelen en configureren van een Azure Function-app die is geïntegreerd met SignalR Service.

SignalR Service-configuratie

Azure SignalR Service kan in verschillende modi worden geconfigureerd. Wanneer deze wordt gebruikt met Azure Functions, moet de service worden geconfigureerd in de serverloze modus.

Zoek in Azure Portal de Instellingen pagina van uw SignalR Service-resource. Stel de servicemodus in op Serverloos.

SignalR Service-modus

Azure Functions-ontwikkeling

Voor een serverloze realtime-toepassing die is gebouwd met Azure Functions en Azure SignalR Service, zijn ten minste twee Azure Functions vereist:

  • Een negotiate functie die de client aanroept om een geldig SignalR Service-toegangstoken en eindpunt-URL te verkrijgen.
  • Een of meer functies die berichten verwerken die vanuit SignalR Service naar clients worden verzonden.

Onderhandelingsfunctie

Voor een clienttoepassing is een geldig toegangstoken vereist om verbinding te maken met Azure SignalR Service. Een toegangstoken kan anoniem of geverifieerd zijn voor een gebruikers-id. Serverloze SignalR Service-toepassingen vereisen een HTTP-eindpunt met de naam negotiate om een token en andere verbindingsgegevens te verkrijgen, zoals de EINDPUNT-URL van signalR Service.

Gebruik een door HTTP geactiveerde Azure-functie en de SignalRConnectionInfo invoerbinding om het verbindingsinformatieobject te genereren. De functie moet een HTTP-route hebben die eindigt op /negotiate.

Met een model op basis van klasse in C# hebt u de SignalRConnectionInfo invoerbinding niet nodig en kunt u eenvoudiger aangepaste claims toevoegen. Zie Onderhandelingservaring in een model op basis van klassen voor meer informatie.

Zie Azure Functions-ontwikkeling voor meer informatie over de negotiate functie.

Raadpleeg App Service-verificatie gebruiken voor meer informatie over het maken van een geverifieerd token.

Berichten verwerken die worden verzonden vanuit SignalR Service

Gebruik de SignalRTrigger binding om berichten te verwerken die worden verzonden vanuit SignalR Service. U kunt een melding ontvangen wanneer clients berichten verzenden of clients verbinding maken of de verbinding verbreken.

Zie de triggerbindingsreferentie voor SignalR Service voor meer informatie.

U moet uw functie-eindpunt ook configureren als een upstream-eindpunt, zodat de service de functie activeert wanneer er een bericht van een client is. Zie Upstream-eindpunten voor meer informatie over het configureren van upstream-eindpunten.

Notitie

SignalR Service biedt geen ondersteuning voor het StreamInvocation bericht van een client in de serverloze modus.

Berichten verzenden en groepslidmaatschap beheren

Gebruik de SignalR uitvoerbinding om berichten te verzenden naar clients die zijn verbonden met Azure SignalR Service. U kunt berichten uitzenden naar alle clients of u kunt ze verzenden naar een subset van clients. Verzend bijvoorbeeld alleen berichten naar clients die zijn geverifieerd met een specifieke gebruikers-id of alleen naar een specifieke groep.

Gebruikers kunnen worden toegevoegd aan een of meer groepen. U kunt ook de SignalR uitvoerbinding gebruiken om gebruikers toe te voegen aan of te verwijderen uit groepen.

Zie de verwijzing naar de SignalR uitvoerbinding voor meer informatie.

SignalR Hubs

SignalR heeft een concept van hubs. Elke clientverbinding en elk bericht dat vanuit Azure Functions wordt verzonden, is gericht op een specifieke hub. U kunt hubs gebruiken als een manier om uw verbindingen en berichten te scheiden in logische naamruimten.

Model op basis van klasse

Het model op basis van klasse is toegewezen voor C#.

Het model op basis van klasse biedt een betere programmeerervaring, die SignalR-invoer- en uitvoerbindingen kan vervangen door de volgende functies:

  • Flexibeler onderhandelen, berichten verzenden en groepservaring beheren.
  • Meer beheerfuncties worden ondersteund, waaronder het sluiten van verbindingen, het controleren of er een verbinding, gebruiker of groep bestaat.
  • Sterk getypte hub
  • Naam van unified hub en verbindingsreeks-instelling op één plaats.

De volgende code laat zien hoe u SignalR-bindingen schrijft in een model op basis van klasse:

Definieer eerst uw hub die is afgeleid van een klasse ServerlessHub:

[SignalRConnection("AzureSignalRConnectionString")]
public class Functions : ServerlessHub
{
    private const string HubName = nameof(Functions); // Used by SignalR trigger only

    public Functions(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }

    [Function("negotiate")]
    public async Task<HttpResponseData> Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
    {
        var negotiateResponse = await NegotiateAsync(new() { UserId = req.Headers.GetValues("userId").FirstOrDefault() });
        var response = req.CreateResponse();
        response.WriteBytes(negotiateResponse.ToArray());
        return response;
    }

    [Function("Broadcast")]
    public Task Broadcast(
    [SignalRTrigger(HubName, "messages", "broadcast", "message")] SignalRInvocationContext invocationContext, string message)
    {
        return Clients.All.SendAsync("newMessage", new NewMessage(invocationContext, message));
    }

    [Function("JoinGroup")]
    public Task JoinGroup([SignalRTrigger(HubName, "messages", "JoinGroup", "connectionId", "groupName")] SignalRInvocationContext invocationContext, string connectionId, string groupName)
    {
        return Groups.AddToGroupAsync(connectionId, groupName);
    }
}

Registreer uw serverloze hub in het Program.cs-bestand :

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(b => b.Services
        .AddServerlessHub<Functions>())
    .Build();

Onderhandelingservaring in model op basis van klassen

In plaats van SignalR-invoerbinding [SignalRConnectionInfoInput]te gebruiken, kan onderhandeling in een model op basis van klassen flexibeler zijn. Basisklasse ServerlessHub heeft een methode NegotiateAsync, waarmee gebruikers onderhandelingsopties zoals userId, claimsenzovoort kunnen aanpassen.

Task<BinaryData> NegotiateAsync(NegotiationOptions? options = null)

Berichten verzenden en ervaring beheren in een model op basis van klassen

U kunt berichten verzenden, groepen beheren of clients beheren door toegang te krijgen tot de leden van de basisklasse ServerlessHub.

  • ServerlessHub.Clients voor het verzenden van berichten naar clients.
  • ServerlessHub.Groups voor het beheren van verbindingen met groepen, zoals het toevoegen van verbindingen aan groepen, het verwijderen van verbindingen uit groepen.
  • ServerlessHub.UserGroups voor het beheren van gebruikers met groepen, zoals het toevoegen van gebruikers aan groepen, het verwijderen van gebruikers uit groepen.
  • ServerlessHub.ClientManager voor het controleren van het bestaan van verbindingen, het sluiten van verbindingen, enzovoort.

Sterk getypte hub

Met sterk getypte hub kunt u sterk getypte methoden gebruiken wanneer u berichten naar clients verzendt. Als u sterk getypte hub in een model op basis van klassen wilt gebruiken, extraheert u clientmethoden in een interface Ten maakt u uw hubklasse afgeleid van ServerlessHub<T>.

De volgende code is een interfacevoorbeeld voor clientmethoden.

public interface IChatClient
{
    Task newMessage(NewMessage message);
}

Vervolgens kunt u de sterk getypte methoden als volgt gebruiken:

[SignalRConnection("AzureSignalRConnectionString")]
public class Functions : ServerlessHub<IChatClient>
{
    private const string HubName = nameof(Functions);  // Used by SignalR trigger only

    public Functions(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }

    [Function("Broadcast")]
    public Task Broadcast(
    [SignalRTrigger(HubName, "messages", "broadcast", "message")] SignalRInvocationContext invocationContext, string message)
    {
        return Clients.All.newMessage(new NewMessage(invocationContext, message));
    }
}

Notitie

U kunt een volledig projectvoorbeeld ophalen uit GitHub.

Naam van unified hub en verbindingsreeks-instelling op één plaats

  • De klassenaam van de serverloze hub wordt automatisch gebruikt als HubName.
  • Mogelijk hebt u het SignalRConnection kenmerk dat wordt gebruikt voor serverloze hubklassen als volgt opgemerkt:
    [SignalRConnection("AzureSignalRConnectionString")]
    public class Functions : ServerlessHub<IChatClient>
    
    Hiermee kunt u aanpassen waar de verbindingsreeks voor serverloze hub is. Als deze niet aanwezig is, wordt de standaardwaarde AzureSignalRConnectionString gebruikt.

Belangrijk

SignalR-triggers en serverloze hubs zijn onafhankelijk. Daarom verandert de klassenaam van serverloze hub en SignalRConnection kenmerk de instellingen van SignalR-triggers niet, ook al gebruikt u SignalR-triggers in de serverloze hub.

Clientontwikkeling

SignalR-clienttoepassingen kunnen de SignalR-client-SDK in een van de verschillende talen gebruiken om eenvoudig verbinding te maken met en berichten te ontvangen van Azure SignalR Service.

Een clientverbinding configureren

Als u verbinding wilt maken met SignalR Service, moet een client een geslaagde verbindingsonderhandeling voltooien die uit deze stappen bestaat:

  1. Een aanvraag indienen bij het negotiate HIERBOVEN besproken HTTP-eindpunt om geldige verbindingsgegevens te verkrijgen
  2. Verbinding maken naar SignalR Service met behulp van de URL van het service-eindpunt en het toegangstoken dat is verkregen van het negotiate eindpunt

SignalR-client-SDK's bevatten al de logica die nodig is om de onderhandelingshanddruk uit te voeren. Geef de URL van het onderhandelingseindpunt, minus het negotiate segment, door aan de SDK's HubConnectionBuilder. Hier volgt een voorbeeld in JavaScript:

const connection = new signalR.HubConnectionBuilder()
  .withUrl("https://my-signalr-function-app.azurewebsites.net/api")
  .build();

Volgens de conventie voegt de SDK automatisch toe /negotiate aan de URL en gebruikt deze om de onderhandeling te starten.

Notitie

Als u de JavaScript/TypeScript SDK in een browser gebruikt, moet u CROSS-Origin Resource Sharing (CORS) inschakelen in uw functie-app.

Zie de documentatie voor uw taal voor meer informatie over het gebruik van de SignalR-client-SDK:

Berichten verzenden van een client naar de service

Als u upstream hebt geconfigureerd voor uw SignalR-resource, kunt u berichten van een client naar uw Azure Functions verzenden met behulp van een SignalR-client. Hier volgt een voorbeeld in JavaScript:

connection.send("method1", "arg1", "arg2");

Azure Functions-configuratie

Azure Function-apps die worden geïntegreerd met Azure SignalR Service kunnen worden geïmplementeerd zoals elke typische Azure Function-app, met behulp van technieken zoals doorlopende implementatie, zip-implementatie en uitvoering vanuit pakket.

Er zijn echter enkele speciale overwegingen voor apps die gebruikmaken van de SignalR Service-bindingen. Als de client wordt uitgevoerd in een browser, moet CORS zijn ingeschakeld. En als de app verificatie vereist, kunt u het onderhandelingseindpunt integreren met App Service-verificatie.

CORS inschakelen

De JavaScript-/TypeScript-client doet EEN HTTP-aanvraag naar de onderhandelingsfunctie om de verbindingsonderhandeling te initiëren. Wanneer de clienttoepassing wordt gehost in een ander domein dan de Azure Function-app, moet CORS (Cross-Origin Resource Sharing) zijn ingeschakeld in de functie-app, anders blokkeert de browser de aanvragen.

Localhost

Wanneer u de functie-app uitvoert op uw lokale computer, kunt u een Host sectie toevoegen aan local.settings.json om CORS in te schakelen. Voeg in de Host sectie twee eigenschappen toe:

  • CORS - voer de basis-URL in die de oorsprong is van de clienttoepassing
  • CORSCredentials - stel deze in om true aanvragen voor 'withCredentials' toe te staan

Voorbeeld:

{
  "IsEncrypted": false,
  "Values": {
    // values
  },
  "Host": {
    "CORS": "http://localhost:8080",
    "CORSCredentials": true
  }
}

Cloud - Azure Functions CORS

Als u CORS wilt inschakelen in een Azure Function-app, gaat u naar het CORS-configuratiescherm onder het tabblad Platformfuncties van uw functie-app in Azure Portal.

Notitie

CORS-configuratie is nog niet beschikbaar in het Linux-verbruiksabonnement van Azure Functions. Gebruik Azure API Management om CORS in te schakelen.

CORS met Access-Control-Allow-Credentials moet zijn ingeschakeld voor de SignalR-client om de onderhandelingsfunctie aan te roepen. Als u dit wilt inschakelen, schakelt u het selectievakje in.

Voeg in de sectie Toegestane origins een vermelding toe met de oorspronkelijke basis-URL van uw webtoepassing.

CORS configureren

Cloud - Azure API Management

Azure API Management biedt een API-gateway die mogelijkheden toevoegt aan bestaande back-endservices. U kunt deze gebruiken om CORS toe te voegen aan uw functie-app. Het biedt een verbruikslaag met prijzen voor betalen per actie en een maandelijkse gratis toekenning.

Raadpleeg de API Management-documentatie voor informatie over het importeren van een Azure Function-app. Nadat u het beleid voor inkomend verkeer hebt geïmporteerd, kunt u CORS inschakelen met ondersteuning voor Access-Control-Allow-Credentials.

<cors allow-credentials="true">
  <allowed-origins>
    <origin>https://azure-samples.github.io</origin>
  </allowed-origins>
  <allowed-methods>
    <method>GET</method>
    <method>POST</method>
  </allowed-methods>
  <allowed-headers>
    <header>*</header>
  </allowed-headers>
  <expose-headers>
    <header>*</header>
  </expose-headers>
</cors>

Configureer uw SignalR-clients voor het gebruik van de API Management-URL.

App Service-verificatie gebruiken

Azure Functions heeft ingebouwde verificatie, die populaire providers ondersteunt, zoals Facebook, Twitter, Microsoft-account, Google en Microsoft Entra-id. Deze functie kan worden geïntegreerd met de binding voor het SignalRConnectionInfo maken van verbindingen met Azure SignalR Service die is geverifieerd bij een gebruikers-id. Uw toepassing kan berichten verzenden met behulp van de SignalR uitvoerbinding die is gericht op die gebruikers-id.

Open in Azure Portal op het tabblad Platformfuncties van uw functie-app het venster Verificatie-/autorisatie-instellingen. Volg de documentatie voor App Service-verificatie om verificatie te configureren met behulp van een id-provider van uw keuze.

Na de configuratie bevatten geverifieerde HTTP-aanvragen respectievelijk x-ms-client-principal-name headers met x-ms-client-principal-id de gebruikersnaam en gebruikers-id van de geverifieerde identiteit.

U kunt deze headers in uw SignalRConnectionInfo bindingsconfiguratie gebruiken om geverifieerde verbindingen te maken. Hier volgt een voorbeeld van een C#-onderhandelingsfunctie die gebruikmaakt van de x-ms-client-principal-id header.

[FunctionName("negotiate")]
public static SignalRConnectionInfo Negotiate(
    [HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req,
    [SignalRConnectionInfo
        (HubName = "chat", UserId = "{headers.x-ms-client-principal-id}")]
        SignalRConnectionInfo connectionInfo)
{
    // connectionInfo contains an access key token with a name identifier claim set to the authenticated user
    return connectionInfo;
}

Vervolgens kunt u berichten naar die gebruiker verzenden door de UserId eigenschap van een SignalR-bericht in te stellen.

[FunctionName("SendMessage")]
public static Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
    [SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage
        {
            // the message will only be sent to these user IDs
            UserId = "userId1",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

Zie de Azure SignalR Service-bindingen voor Naslaginformatie over Azure Functions voor meer informatie over andere talen.

Volgende stappen

In dit artikel leert u hoe u serverloze SignalR Service-toepassingen ontwikkelt en configureert met behulp van Azure Functions. Probeer zelf een toepassing te maken met behulp van een van de quickstarts of zelfstudies op de overzichtspagina van SignalR Service.