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.
Ga in Azure Portal naar de pagina Instellingen van uw SignalR Service-resource. Stel de servicemodus in op Serverloos.
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
, claims
enzovoort 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 T
en 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:
Hiermee kunt u aanpassen waar de verbindingsreeks voor serverloze hub is. Als deze niet aanwezig is, wordt de standaardwaarde[SignalRConnection("AzureSignalRConnectionString")] public class Functions : ServerlessHub<IChatClient>
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:
- Een aanvraag indienen bij het
negotiate
HIERBOVEN besproken HTTP-eindpunt om geldige verbindingsgegevens te verkrijgen - Verbinding maken met SignalR Service met behulp van de SERVICE-eindpunt-URL en het toegangstoken dat is verkregen via 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 clienttoepassingCORSCredentials
- stel deze in omtrue
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.
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, X, 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.