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.
Důležité
Nezpracované připojovací řetězec se v tomto článku zobrazují jenom pro demonstrační účely.
Připojovací řetězec obsahuje autorizační informace potřebné pro vaši aplikaci pro přístup ke službě Azure SignalR. Přístupový klíč uvnitř připojovací řetězec je podobný kořenovému heslu pro vaši službu. V produkčních prostředích vždy chraňte přístupové klíče. Pomocí služby Azure Key Vault můžete bezpečně spravovat a obměňovat klíče a zabezpečit připojovací řetězec pomocí ID Microsoft Entra a autorizovat přístup pomocí Microsoft Entra ID.
Vyhněte se distribuci přístupových klíčů ostatním uživatelům, jejich pevnému kódování nebo jejich uložení kdekoli ve formátu prostého textu, který je přístupný ostatním uživatelům. Otočte klíče, pokud se domníváte, že mohly být ohroženy.
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 stránku Nastavení vašeho prostředku služby SignalR. Nastavte režim služby na bezserverovou verzi.
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 SignalR
vý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 userId
je , claims
atd.
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í T
a 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.
Nezpracované připojovací řetězec se v tomto článku zobrazují jenom pro demonstrační účely. V produkčních prostředích vždy chraňte přístupové klíče. Pomocí služby Azure Key Vault můžete bezpečně spravovat a obměňovat klíče a zabezpečit připojovací řetězec pomocí ID Microsoft Entra a autorizovat přístup pomocí Microsoft Entra ID.
[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:
Umožňuje přizpůsobit, kde je připojovací řetězec pro bezserverové centrum. Pokud chybí, použije se výchozí hodnota[SignalRConnection("AzureSignalRConnectionString")] public class Functions : ServerlessHub<IChatClient>
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ů:
- Provedení požadavku na
negotiate
koncový bod HTTP probíraný výše za účelem získání platných informací o připojení - Připojení ke službě 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 natrue
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.
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, X, úč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.