Sdílet prostřednictvím


Vývoj a konfigurace služby Azure Functions s využitím služby Azure SignalR Service

Aplikace Azure Functions můžou pomocí vazeb služby Azure SignalR přidat možnosti v reálném čase. Klientské aplikace používají klientské sady SDK dostupné v několika jazycích pro připojení ke službě Azure SignalR a přijímání zpráv v reálném čase.

Tento článek popisuje koncepty vývoje a konfigurace aplikace Funkcí Azure, která je integrovaná se službou SignalR.

Konfigurace služby SignalR

Službu Azure SignalR je možné nakonfigurovat v různých režimech. Při použití se službou Azure Functions musí být služba nakonfigurovaná v bezserverovém režimu.

Na webu Azure Portal vyhledejte Nastavení stránku vašeho prostředku služby SignalR. Nastavte režim služby na bezserverovou verzi.

Režim služby SignalR

Vývoj s využitím Azure Functions

Bezserverová aplikace v reálném čase vytvořená se službou Azure Functions a službou Azure SignalR vyžaduje alespoň dvě funkce Azure Functions:

  • Funkce negotiate , kterou klient volá za účelem získání platného přístupového tokenu služby SignalR Service a adresy URL koncového bodu.
  • Jedna nebo více funkcí, které zpracovávají zprávy odeslané ze služby SignalR service klientům.

Funkce vyjednávání

Klientská aplikace vyžaduje platný přístupový token pro připojení ke službě Azure SignalR. Přístupový token může být anonymní nebo ověřený pro ID uživatele. Aplikace služby SignalR Service bez serveru vyžadují, aby koncový bod HTTP s názvem negotiate získal token a další informace o připojení, jako je adresa URL koncového bodu služby SignalR.

K vygenerování objektu SignalRConnectionInfo informací o připojení použijte funkci Azure aktivovanou protokolem HTTP a vstupní vazbu. Funkce musí mít trasu HTTP, která končí ./negotiate

S modelem založeným na třídách v jazyce C# nepotřebujete SignalRConnectionInfo vstupní vazbu a můžete přidávat vlastní deklarace identity mnohem snadněji. Další informace naleznete v tématu Vyjednávání prostředí v modelu založeném na třídách.

Další informace o funkci najdete ve vývoji ve službě negotiate Azure Functions.

Informace o vytvoření ověřeného tokenu najdete v tématu Použití ověřování pomocí služby App Service.

Zpracování zpráv odeslaných ze služby SignalR

Pomocí vazby SignalRTrigger můžete zpracovávat zprávy odeslané ze služby SignalR. Můžete dostávat oznámení, když klienti odesílají zprávy nebo klienti dostanou připojení nebo odpojení.

Další informace najdete v referenčních informacích k vazbě aktivační události služby SignalR.

Musíte také nakonfigurovat koncový bod funkce jako nadřazený koncový bod, aby služba aktivovala funkci, když se zobrazí zpráva z klienta. Další informace o konfiguraci upstreamových koncových bodů najdete v tématu Nadřazené koncové body.

Poznámka:

Služba SignalR nepodporuje StreamInvocation zprávu z klienta v bezserverovém režimu.

Odesílání zpráv a správa členství ve skupinách

SignalR Výstupní vazba slouží k odesílání zpráv klientům připojeným ke službě Azure SignalR. Zprávy můžete vysílat všem klientům nebo je můžete odeslat podmnožině klientů. Například odesílat zprávy pouze klientům ověřeným pomocí konkrétního ID uživatele nebo pouze do konkrétní skupiny.

Uživatele je možné přidat do jedné nebo více skupin. Výstupní vazbu můžete použít SignalR také k přidání nebo odebrání uživatelů do a ze skupin.

Další informace najdete v referenčních informacích k SignalRvýstupním vazbě.

SignalR Hubs

SignalR má koncept center. Každé připojení klienta a každá zpráva odeslaná ze služby Azure Functions je vymezená na konkrétní centrum. Rozbočovače můžete použít jako způsob oddělení připojení a zpráv do logických oborů názvů.

Model založený na třídách

Model založený na třídách je vyhrazený pro jazyk C#.

Model založený na třídách poskytuje lepší programovací prostředí, které může nahradit vstupní a výstupní vazby SignalR následujícími funkcemi:

  • Flexibilnější vyjednávání, odesílání zpráv a správa prostředí skupin
  • Podporují se další funkce správy, včetně zavírání připojení, kontroly, jestli připojení, uživatel nebo skupina existují.
  • Rozbočovač silného typu
  • Název sjednoceného centra a nastavení připojovací řetězec na jednom místě

Následující kód ukazuje, jak psát vazby SignalR v modelu založeném na třídách:

Nejprve definujte centrum odvozené z třídy 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);
    }
}

V souboru Program.cs zaregistrujte bezserverové centrum:

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

Zkušenosti s vyjednáváním v modelu založeném na třídách

Místo použití vstupní vazby [SignalRConnectionInfoInput]SignalR může být vyjednávání v modelu založeném na třídě flexibilnější. Základní třída ServerlessHub má metodu NegotiateAsync, která uživatelům umožňuje přizpůsobit možnosti vyjednávání, jako userIdje , claimsatd.

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

Odesílání zpráv a správa prostředí v modelu založeném na třídách

Můžete odesílat zprávy, spravovat skupiny nebo spravovat klienty přístupem k členům poskytovaným základní třídou ServerlessHub.

  • ServerlessHub.Clients pro odesílání zpráv klientům.
  • ServerlessHub.Groups pro správu připojení se skupinami, jako je přidání připojení ke skupinám, odebrání připojení ze skupin.
  • ServerlessHub.UserGroups pro správu uživatelů se skupinami, jako je přidání uživatelů do skupin, odebrání uživatelů ze skupin.
  • ServerlessHub.ClientManager pro kontrolu existence připojení, uzavření připojení atd.

Rozbočovač silného typu

Rozbočovač silného typu umožňuje používat metody silného typu při odesílání zpráv klientům. Chcete-li použít rozbočovač silného typu v modelu založeném na třídách, extrahujte klientské metody do rozhraní Ta vytvořte třídu centra odvozenou z ServerlessHub<T>.

Následující kód je ukázka rozhraní pro klientské metody.

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

Pak můžete použít metody silného typu následujícím způsobem:

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

Poznámka:

Kompletní ukázku projektu můžete získat z GitHubu.

Název sjednoceného centra a nastavení připojovací řetězec na jednom místě

  • Název třídy bezserverového centra se automaticky používá jako HubName.
  • Možná jste si všimli atributu používaného SignalRConnection v třídách bezserverového centra následujícím způsobem:
    [SignalRConnection("AzureSignalRConnectionString")]
    public class Functions : ServerlessHub<IChatClient>
    
    Umožňuje přizpůsobit, kde je připojovací řetězec pro bezserverové centrum. Pokud chybí, použije se výchozí hodnota AzureSignalRConnectionString .

Důležité

Triggery SignalR a bezserverové rozbočovače jsou nezávislé. Proto název třídy bezserverového centra a SignalRConnection atributu nemění nastavení triggerů SignalR, i když používáte triggery SignalR uvnitř bezserverového centra.

Vývoj klientů

Klientské aplikace SignalR můžou používat klientskou sadu SDK služby SignalR v jednom z několika jazyků, abyste se mohli snadno připojit ke službě Azure SignalR a přijímat zprávy.

Konfigurace připojení klienta

Aby se klient připojil ke službě SignalR, musí dokončit úspěšné vyjednávání připojení, které se skládá z těchto kroků:

  1. Provedení požadavku na negotiate koncový bod HTTP probíraný výše za účelem získání platných informací o připojení
  2. Připojení do služby SignalR Pomocí adresy URL koncového bodu služby a přístupového tokenu získaného z koncového negotiate bodu

Klientské sady SDK služby SignalR již obsahují logiku potřebnou k provedení metody handshake vyjednávání. Předejte adresu URL koncového bodu vyjednávání bez negotiate segmentu do sady SDK HubConnectionBuilder. Tady je příklad v JavaScriptu:

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

Sada SDK se podle konvence automaticky připojí /negotiate k adrese URL a použije ji k zahájení vyjednávání.

Poznámka:

Pokud v prohlížeči používáte sadu JavaScript/TypeScript SDK, musíte ve své aplikaci funkcí povolit sdílení prostředků mezi zdroji (CORS ).

Další informace o tom, jak používat klientskou sadu SDK služby SignalR, najdete v dokumentaci pro váš jazyk:

Odesílání zpráv z klienta do služby

Pokud jste pro prostředek SignalR nakonfigurovali upstream , můžete odesílat zprávy z klienta do služby Azure Functions pomocí libovolného klienta SignalR. Tady je příklad v JavaScriptu:

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

Konfigurace Azure Functions

Aplikace Azure Functions, které se integrují se službou Azure SignalR Service, je možné nasadit stejně jako jakoukoli typickou aplikaci Azure Functions pomocí technik, jako je průběžné nasazování, nasazování zip a spouštění z balíčku.

Existuje však několik zvláštních aspektů pro aplikace, které používají vazby služby SignalR. Pokud se klient spouští v prohlížeči, musí být povolená cors. A pokud aplikace vyžaduje ověření, můžete integrovat koncový bod vyjednávání s ověřováním služby App Service.

Povolení CORS

Klient JavaScript/TypeScript odešle požadavek HTTP na funkci vyjednávání, aby zahájil vyjednávání připojení. Pokud je klientská aplikace hostovaná v jiné doméně než aplikace funkcí Azure, musí být v aplikaci funkcí povolené sdílení prostředků mezi zdroji (CORS), jinak prohlížeč požadavky zablokuje.

Localhost

Při spuštění aplikace funkcí na místním počítači můžete přidat Host oddíl, který local.settings.json a povolit CORS. Host V části přidejte dvě vlastnosti:

  • CORS – zadejte základní adresu URL, která je původem klientské aplikace.
  • CORSCredentials – nastavte ho na true povolení požadavků "withCredentials".

Příklad:

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

Cloud – CORS pro Azure Functions

Pokud chcete CORS povolit v aplikaci Funkcí Azure, přejděte na obrazovku konfigurace CORS na kartě Funkce platformy vaší aplikace funkcí na webu Azure Portal.

Poznámka:

Konfigurace CORS ještě není dostupná v plánu Využití Linuxu ve službě Azure Functions. Pomocí služby Azure API Management povolte CORS.

CORS s povolenými přihlašovacími údaji řízení přístupu musí být povolené pro klienta SignalR, aby volal funkci vyjednávání. Pokud ho chcete povolit, zaškrtněte políčko.

V části Povolené zdroje přidejte položku se základní adresou URL původu vaší webové aplikace.

Konfigurace CORS

Cloud – Azure API Management

Azure API Management poskytuje bránu rozhraní API, která přidává možnosti do stávajících back-endových služeb. Můžete ho použít k přidání CORS do aplikace funkcí. Nabízí úroveň consumption s cenami plateb za akci a měsíčním bezplatným grantem.

Informace o importu aplikace Azure Function App najdete v dokumentaci ke službě API Management. Po importu můžete přidat příchozí zásadu, která povolí CORS s podporou přístup-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>

Nakonfigurujte klienty SignalR tak, aby používali adresu URL služby API Management.

Použití ověřování pomocí služby App Service

Azure Functions má integrované ověřování, které podporuje oblíbené poskytovatele, jako jsou Facebook, Twitter, účet Microsoft, Google a Microsoft Entra ID. Tuto funkci lze integrovat s vazbou SignalRConnectionInfo a vytvořit připojení ke službě Azure SignalR, která je ověřena pro ID uživatele. Aplikace může odesílat zprávy pomocí SignalR výstupní vazby, které jsou cílem daného ID uživatele.

Na webu Azure Portal otevřete na kartě Funkce vaší aplikace funkcí okno Nastavení ověřování a autorizace . Podle dokumentace pro ověřování pomocí služby App Service nakonfigurujte ověřování pomocí zprostředkovatele identity podle vašeho výběru.

Po nakonfigurování zahrnují x-ms-client-principal-name ověřené požadavky HTTP a x-ms-client-principal-id hlavičky obsahující uživatelské jméno a ID uživatele ověřené identity.

Pomocí těchto hlaviček v SignalRConnectionInfo konfiguraci vazby můžete vytvářet ověřená připojení. Tady je příklad funkce vyjednávání jazyka C#, která používá hlavičku 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;
}

Potom můžete posílat zprávy ho uživateli nastavením UserId vlastnosti zprávy 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 }
        });
}

Informace o jiných jazycích najdete v referenčních informacích ke službě Azure SignalR Service.

Další kroky

V tomto článku se dozvíte, jak vyvíjet a konfigurovat aplikace bezserverové služby SignalR pomocí Azure Functions. Zkuste vytvořit aplikaci sami pomocí některého z rychlých startů nebo kurzů na stránce přehledu služby SignalR.