Sviluppo e configurazione di Funzioni di Azure e con il Servizio Azure SignalR

Funzioni di Azure applicazioni possono usare le associazioni Servizio Azure SignalR per aggiungere funzionalità in tempo reale. Le applicazioni client usano gli SDK client disponibili in diverse lingue per connettersi a Servizio Azure SignalR e ricevere messaggi in tempo reale.

Questo articolo descrive i concetti per lo sviluppo e la configurazione di un'app per le funzioni di Azure integrata con Servizio SignalR.

configurazione di Servizio SignalR

Servizio Azure SignalR possono essere configurati in modalità diverse. Se usato con Funzioni di Azure, il servizio deve essere configurato in modalità serverless.

Nella portale di Azure individuare la pagina Impostazioni della risorsa Servizio SignalR. Impostare modalità servizio su Serverless.

Modalità del servizio SignalR

Sviluppo di Funzioni di Azure

Un'applicazione serverless in tempo reale compilata con Funzioni di Azure e Servizio Azure SignalR richiede almeno due Funzioni di Azure:

  • Funzione negotiate chiamata dal client per ottenere un token di accesso valido Servizio SignalR e un URL dell'endpoint.
  • Una o più funzioni che gestiscono i messaggi inviati da Servizio SignalR ai client.

Funzione di negoziazione

Un'applicazione client richiede un token di accesso valido per connettersi a Servizio Azure SignalR. Un token di accesso può essere anonimo o autenticato in un ID utente. Le applicazioni Servizio SignalR serverless richiedono un endpoint HTTP denominato negotiate per ottenere un token e altre informazioni di connessione, ad esempio l'URL dell'endpoint Servizio SignalR.

Usare una funzione di Azure attivata da HTTP e l'associazione SignalRConnectionInfo di input per generare l'oggetto informazioni di connessione. La funzione deve avere una route HTTP che termina in /negotiate.

Con il modello basato su classi in C# non è necessaria l'associazione SignalRConnectionInfo di input e è possibile aggiungere attestazioni personalizzate molto più facilmente. Per altre informazioni, vedere Esperienza di negoziazione nel modello basato su classi.

Per altre informazioni sulla negotiate funzione, vedere Funzioni di Azure sviluppo.

Per informazioni su come creare un token autenticato, vedere Uso dell'autenticazione servizio app.

Gestire i messaggi inviati da Servizio SignalR

Usare l'associazione SignalRTrigger per gestire i messaggi inviati da Servizio SignalR. È possibile ricevere una notifica quando i client inviano messaggi o client vengono connessi o disconnessi.

Per altre informazioni, vedere informazioni di riferimento sull'associazione di trigger Servizio SignalR.

È anche necessario configurare l'endpoint della funzione come endpoint upstream in modo che il servizio attivi la funzione quando viene visualizzato un messaggio da un client. Per altre informazioni su come configurare gli endpoint upstream, vedere Endpoint upstream.

Nota

Servizio SignalR non supporta il StreamInvocation messaggio da un client in modalità serverless.

Invio di messaggi e gestione dell'appartenenza ai gruppi

Usare l'associazione SignalR di output per inviare messaggi ai client connessi a Servizio Azure SignalR. È possibile trasmettere messaggi a tutti i client oppure inviarli a un subset di client. Ad esempio, inviare messaggi solo ai client autenticati con un ID utente specifico o solo a un gruppo specifico.

Gli utenti possono essere aggiunti a uno o più gruppi. È anche possibile usare l'associazione SignalR di output per aggiungere o rimuovere utenti da/verso i gruppi.

Per altre informazioni, vedere il riferimento all'associazione SignalR di output.

Hub SignalR

SignalR ha un concetto di hub. Ogni connessione client e ogni messaggio inviato da Funzioni di Azure ha come ambito un hub specifico. È possibile usare hub come modo per separare le connessioni e i messaggi in spazi dei nomi logici.

Modello basato su classi

Il modello basato su classi è dedicato per C#.

Il modello basato su classi offre un'esperienza di programmazione migliore, che può sostituire le associazioni di input e output signalR, con le funzionalità seguenti:

  • Negoziazione più flessibile, invio di messaggi e gestione dei gruppi.
  • Sono supportate altre funzionalità di gestione, tra cui la chiusura delle connessioni, la verifica dell'esistenza di una connessione, di un utente o di un gruppo.
  • Hub fortemente tipizzato
  • Nome dell'hub unificato e impostazione stringa di connessione in un'unica posizione.

Il codice seguente illustra come scrivere associazioni SignalR nel modello basato su classi:

In primo luogo, definire l'hub derivato da una classe 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);
    }
}

Nel file Program.cs registrare l'hub serverless:

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

Esperienza di negoziazione nel modello basato su classi

Anziché usare l'associazione [SignalRConnectionInfoInput]di input SignalR, la negoziazione nel modello basato su classi può essere più flessibile. La classe ServerlessHub base ha un metodo NegotiateAsync, che consente agli utenti di personalizzare le opzioni di negoziazione, ad userIdesempio , claimse così via.

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

Invio di messaggi e gestione dell'esperienza nel modello basato su classi

È possibile inviare messaggi, gestire gruppi o gestire i client accedendo ai membri forniti dalla classe ServerlessHubbase .

  • ServerlessHub.Clients per l'invio di messaggi ai client.
  • ServerlessHub.Groups per la gestione delle connessioni con gruppi, ad esempio l'aggiunta di connessioni ai gruppi, la rimozione di connessioni dai gruppi.
  • ServerlessHub.UserGroups per la gestione degli utenti con gruppi, ad esempio l'aggiunta di utenti a gruppi, la rimozione di utenti dai gruppi.
  • ServerlessHub.ClientManager per verificare l'esistenza delle connessioni, la chiusura di connessioni e così via.

Hub fortemente tipizzato

L'hub fortemente tipizzato consente di usare metodi fortemente tipizzato quando si inviano messaggi ai client. Per usare un hub fortemente tipizzato nel modello basato su classi, estrarre i metodi client in un'interfaccia Te rendere la classe hub derivata da ServerlessHub<T>.

Il codice seguente è un esempio di interfaccia per i metodi client.

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

È quindi possibile usare i metodi fortemente tipizzato come segue:

[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));
    }
}

Nota

È possibile ottenere un esempio di progetto completo da GitHub.

Nome dell'hub unificato e impostazione stringa di connessione in un'unica posizione

  • Il nome della classe dell'hub serverless viene usato automaticamente come HubName.
  • È possibile che l'attributo usato nelle classi dell'hub SignalRConnection serverless sia stato notato come segue:
    [SignalRConnection("AzureSignalRConnectionString")]
    public class Functions : ServerlessHub<IChatClient>
    
    Consente di personalizzare la posizione in cui si trova il stringa di connessione per l'hub serverless. Se è assente, viene usato il valore AzureSignalRConnectionString predefinito.

Importante

I trigger SignalR e gli hub serverless sono indipendenti. Pertanto, il nome della classe dell'hub serverless e SignalRConnection dell'attributo non modifica le impostazioni dei trigger SignalR, anche se si usano trigger SignalR all'interno dell'hub serverless.

Sviluppo client

Le applicazioni client SignalR possono usare l'SDK client SignalR in uno dei diversi linguaggi per connettersi e ricevere facilmente messaggi da Servizio Azure SignalR.

Configurazione di una connessione client

Per connettersi a Servizio SignalR, un client deve completare una negoziazione di connessione riuscita costituita da questi passaggi:

  1. Effettuare una richiesta all'endpoint negotiate HTTP descritto in precedenza per ottenere informazioni di connessione valide
  2. Connessione a Servizio SignalR usando l'URL dell'endpoint di servizio e il token di accesso ottenuti dall'endpoint negotiate

Gli SDK del client SignalR contengono già la logica necessaria per eseguire l'handshake di negoziazione. Passare l'URL dell'endpoint di negoziazione, meno il negotiate segmento, a HubConnectionBuilder. Ecco un esempio in JavaScript:

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

Per convenzione, l'SDK aggiunge /negotiate automaticamente all'URL e lo usa per avviare la negoziazione.

Nota

Se si usa JavaScript/TypeScript SDK in un browser, è necessario abilitare la condivisione di risorse tra le origini (CORS) nell'app per le funzioni.

Per altre informazioni su come usare l'SDK client SignalR, vedere la documentazione relativa al linguaggio:

Invio di messaggi da un client al servizio

Se è stato configurato upstream per la risorsa SignalR, è possibile inviare messaggi da un client al Funzioni di Azure usando qualsiasi client SignalR. Ecco un esempio in JavaScript:

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

configurazione di Funzioni di Azure

Le app per le funzioni di Azure che si integrano con Servizio Azure SignalR possono essere distribuite come qualsiasi tipica app per le funzioni di Azure, usando tecniche come distribuzione continua, distribuzione zip ed esecuzione dal pacchetto.

Esistono tuttavia alcune considerazioni speciali per le app che usano le associazioni Servizio SignalR. Se il client viene eseguito in un browser, è necessario abilitare CORS. Se l'app richiede l'autenticazione, è possibile integrare l'endpoint di negoziazione con servizio app Authentication.

Abilitazione della condivisione CORS

Il client JavaScript/TypeScript effettua una richiesta HTTP alla funzione di negoziazione per avviare la negoziazione della connessione. Quando l'applicazione client è ospitata in un dominio diverso rispetto all'app per le funzioni di Azure, è necessario abilitare la condivisione di risorse tra le origini (CORS) nell'app per le funzioni oppure il browser bloccherà le richieste.

Localhost

Quando si esegue l'app per le funzioni nel computer locale, è possibile aggiungere una Host sezione a local.settings.json per abilitare CORS. Host Nella sezione aggiungere due proprietà:

  • CORS : immettere l'URL di base che rappresenta l'origine dell'applicazione client
  • CORSCredentials - impostarlo su true per consentire le richieste "withCredentials"

Esempio:

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

Cloud - Funzioni di Azure CORS

Per abilitare CORS in un'app per le funzioni di Azure, passare alla schermata di configurazione CORS nella scheda Funzionalità della piattaforma dell'app per le funzioni nella portale di Azure.

Nota

La configurazione CORS non è ancora disponibile nel piano a consumo di Funzioni di Azure Linux. Usare Azure Gestione API per abilitare CORS.

CORS con Access-Control-Allow-Credentials deve essere abilitato per consentire al client SignalR di chiamare la funzione di negoziazione. Per abilitarla, selezionare la casella di controllo.

Nella sezione Origini consentite aggiungere una voce con l'URL di base di origine dell'applicazione Web.

Configurazione di CORS

Cloud - Azure Gestione API

Azure Gestione API fornisce un gateway API che aggiunge funzionalità ai servizi back-end esistenti. È possibile usarlo per aggiungere CORS all'app per le funzioni. Offre un piano a consumo con prezzi con pagamento in base all'azione e una concessione gratuita mensile.

Per informazioni su come importare un'app per le funzioni di Azure, vedere la documentazione Gestione API. Dopo l'importazione, è possibile aggiungere un criterio in ingresso per abilitare CORS con il supporto di 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>

Configurare i client SignalR per l'uso dell'URL Gestione API.

Uso dell'autenticazione servizio app

Funzioni di Azure ha l'autenticazione predefinita, supportando provider popolari come Facebook, Twitter, Account Microsoft, Google e Microsoft Entra ID. Questa funzionalità può essere integrata con l'associazione SignalRConnectionInfo per creare connessioni a Servizio Azure SignalR autenticate in un ID utente. L'applicazione può inviare messaggi usando l'associazione SignalR di output destinata a tale ID utente.

Nella scheda Funzionalità della piattaforma dell'app per le funzioni della portale di Azure aprire la finestra Impostazioni di autenticazione/autorizzazione. Seguire la documentazione relativa all'autenticazione servizio app per configurare l'autenticazione usando un provider di identità di propria scelta.

Dopo la configurazione, le richieste HTTP autenticate includono x-ms-client-principal-name e x-ms-client-principal-id intestazioni contenenti rispettivamente il nome utente e l'ID utente dell'identità autenticata.

È possibile usare queste intestazioni nella SignalRConnectionInfo configurazione dell'associazione per creare connessioni autenticate. Ecco un esempio di funzione di negoziazione C# che usa l'intestazione x-ms-client-principal-id .

[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;
}

È quindi possibile inviare messaggi all'utente impostando la UserId proprietà di un messaggio SignalR.

[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 }
        });
}

Per informazioni su altre lingue, vedere le associazioni Servizio Azure SignalR per Funzioni di Azure riferimento.

Passaggi successivi

Questo articolo illustra come sviluppare e configurare applicazioni serverless Servizio SignalR usando Funzioni di Azure. Provare a creare un'applicazione manualmente usando una delle guide introduttive o le esercitazioni nella pagina di panoramica Servizio SignalR.