Partager via


Utiliser ASP.NET Core SignalR avec Blazor

Remarque

Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 8 de cet article.

Avertissement

Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la Stratégie de prise en charge de .NET et .NET Core. Pour la version actuelle, consultez la version .NET 8 de cet article.

Important

Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Pour la version actuelle, consultez la version .NET 8 de cet article.

Ce didacticiel fournit une expérience de travail de base pour créer une application en temps réel SignalR à l'aide de Blazor. Cet article s’adresse aux développeurs qui connaissent déjà SignalR et qui cherchent à savoir comment utiliser SignalR dans une application Blazor. Pour obtenir une aide détaillée sur les frameworks SignalR et Blazor, consultez les ensembles de documentation de référence suivants et la documentation des API :

Apprenez à :

  • Créer une application Blazor
  • Ajouter la bibliothèque cliente SignalR
  • Ajouter un hub SignalR
  • Ajouter des services SignalR et un point de terminaison pour le hub SignalR
  • Ajouter un code de composant Razor pour la conversation

À la fin de ce tutoriel, vous disposerez d’une application de conversation opérationnelle.

Prérequis

Visual Studio (dernière version) avec la charge de travail Développement web et ASP.NET

Exemple d’application

Le téléchargement de l’exemple d’application de conversation du tutoriel n’est pas requis pour ce tutoriel. L’exemple d’application est l’application de travail opérationnelle finale produite en suivant les étapes de ce tutoriel. Lorsque vous ouvrez le référentiel d’exemples, ouvrez le dossier de version que vous envisagez de cibler et recherchez l’exemple nommé BlazorSignalRApp.

Le téléchargement de l’exemple d’application de conversation du tutoriel n’est pas requis pour ce tutoriel. L’exemple d’application est l’application de travail opérationnelle finale produite en suivant les étapes de ce tutoriel. Lorsque vous ouvrez le référentiel d’exemples, ouvrez le dossier de version que vous envisagez de cibler et recherchez l’exemple nommé BlazorWebAssemblySignalRApp.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Créez une classe Blazor Web App

Suivez l’aide pour votre choix d’outils :

Remarque

Visual Studio 2022 ou version ultérieure et .NET Core SDK 8.0.0 ou version ultérieure sont requis.

Dans Visual Studio :

  • Sélectionnez Créer un projet à partir de la fenêtre de démarrage ou sélectionnez Fichier>Nouveau>Projet dans la barre de menus.
  • Dans la boîte de dialogue Créer un projet, sélectionnez l’Blazor Web App dans la liste des modèles de projet. Cliquez sur le bouton Suivant.
  • Dans la boîte de dialogue Configurer votre nouveau projet, nommez le projet BlazorSignalRApp dans le champ Nom du projet, y compris la mise en majuscules. L’utilisation de ce nom exact de projet est importante pour vous assurer de la correspondance des espaces de noms au code copié à partir du didacticiel dans l’application que vous générez.
  • Vérifiez que l’Emplacement de l’application convient. Laissez la case à cocher Placer la solution et le projet dans le même répertoire activée. Cliquez sur le bouton Suivant.
  • Dans la boîte de dialogue Informations supplémentaires, utilisez les paramètres suivants :
    • Infrastructure : vérifiez la sélection de la dernière infrastructure. Si la liste déroulante Framework de Visual Studio n’inclut pas le dernier .NET Framework disponible, mettez à jour Visual Studio et redémarrez le didacticiel.
    • Type d’authentification : Aucun
    • Configurer pour HTTPS : sélectionné
    • Mode de rendu interactif : WebAssembly
    • Emplacement d’interactivité : par page/composant
    • Inclure des exemples de pages : sélectionné
    • N’utilisez pas d’instructions de niveau supérieur : non sélectionné
    • Sélectionnez Créer.

Les instructions de cet article utilisent un composant WebAssembly pour le client SignalR, car il n’est pas judicieux d’utiliser SignalR pour se connecter à un hub à partir d’un composant de serveur interactif dans la même application, car cela peut entraîner l’épuisement des ports du serveur.

Ajouter la bibliothèque cliente SignalR

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet BlazorSignalRApp.Client, puis sélectionnez Gérer les packages NuGet.

Dans la boîte de dialogue Gérer les packages NuGet, confirmez que la source du package est définie sur nuget.org.

Avec Parcourir sélectionné, entrez Microsoft.AspNetCore.SignalR.Client dans la zone de recherche.

Dans les résultats de la recherche, sélectionnez la dernière version du package Microsoft.AspNetCore.SignalR.Client. Cliquez sur Installer.

Si la fenêtre de dialogue Aperçu des modifications s’affiche, sélectionnez OK.

Si la boîte de dialogue Acceptation de la licence s’affiche, sélectionnez J’accepte si vous acceptez les termes du contrat de licence.

Ajouter un hub SignalR

Dans le projet serveur BlazorSignalRApp, créez un dossier (au pluriel) Hubs et ajoutez la classe ChatHub (Hubs/ChatHub.cs) suivante :

using Microsoft.AspNetCore.SignalR;

namespace BlazorSignalRApp.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

Ajouter des services et un point de terminaison au hub SignalR

Ouvrez le fichier Program du projet serveur BlazorSignalRApp.

Ajoutez l’espace de noms de Microsoft.AspNetCore.ResponseCompression et de la classe ChatHub en haut du fichier :

using Microsoft.AspNetCore.ResponseCompression;
using BlazorSignalRApp.Hubs;

Ajoutez SignalR et des services Middleware de compression des réponses :

builder.Services.AddSignalR();

builder.Services.AddResponseCompression(opts =>
{
   opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
       ["application/octet-stream"]);
});

Utilisez l’intergiciel de compression des réponses en haut de la configuration du pipeline de traitement. Placez la ligne de code suivante immédiatement après la ligne qui génère l’application (var app = builder.Build();) :

app.UseResponseCompression();

Ajoutez un point de terminaison pour le hub immédiatement avant la ligne exécutant l’application (app.Run();) :

app.MapHub<ChatHub>("/chathub");

Ajouter le code de composant Razor pour la conversation

Ajoutez le fichier Pages/Chat.razor suivant au projet BlazorSignalRApp.Client :

@page "/chat"
@rendermode InteractiveWebAssembly
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Chat</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = [];
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
        {
            await hubConnection.SendAsync("SendMessage", userInput, messageInput);
        }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

Ajoutez une entrée au composant NavMenu pour accéder à la page de conversation. Dans Components/Layout/NavMenu.razor? immédiatement après le bloc <div> du composant Weather, ajoutez le bloc <div> suivant :

<div class="nav-item px-3">
    <NavLink class="nav-link" href="chat">
        <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Chat
    </NavLink>
</div>

Remarque

Lorsque vous utilisez le Rechargement à chaud, désactivez l’intergiciel de compression de réponse dans l’environnement Development. Pour plus d’informations, consultez Aide relative à ASP.NET Core BlazorSignalR.

Exécuter l’application

Suivez l’aide relative à vos outils :

Avec le projet de serveur BlazorSignalRApp sélectionné dans l’Explorateur de solutions, appuyez sur  F5 pour exécuter l’application avec le débogage ou sur Ctrl+F5 (Windows)/+F5 (macOS) pour exécuter l’application sans débogage.

Copiez l’URL à partir de la barre d’adresse, ouvrez un autre onglet ou instance du navigateur, puis collez l’URL dans la barre d’adresse.

Choisissez un des navigateurs, entrez un nom et un message, puis sélectionnez le bouton pour envoyer le message. Le nom et le message sont affichés instantanément dans les deux pages :

Exemple SignalRBlazor d’application ouverte dans deux fenêtres de navigateur affichant des messages échangés.

Citations : Star Trek VI : Terre inconnue ©1991 Paramount

Expérience Blazor WebAssembly hébergée

Créer l’application

Suivez les instructions des outils que vous avez choisis pour créer une application Blazor WebAssembly hébergée :

Remarque

Visual Studio 2022 ou version ultérieure et SDK .NET Core 6.0.0 ou version ultérieure sont requis.

Créer un nouveau projet.

Choisissez le modèle d’application Blazor WebAssembly. Sélectionnez Suivant.

Entrez BlazorWebAssemblySignalRApp dans le champ Nom du projet. Vérifiez que l’entrée Emplacement est correcte ou indiquez un emplacement pour le projet. Sélectionnez Suivant.

Dans la boîte de dialogue Informations supplémentaires, cochez la case ASP.NET Core Hébergée.

Sélectionnez Créer.

Confirmez qu’une application hébergée Blazor WebAssembly a été créée : dans Explorateur de solutions, confirmez la présence d’un projet Client et d’un projet Server. Si les deux projets ne sont pas présents, recommencez et confirmez la sélection de la case ASP.NET Core Hébergé avant de sélectionner Créer.

Ajouter la bibliothèque cliente SignalR

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet BlazorWebAssemblySignalRApp.Client, puis sélectionnez Gérer les packages NuGet.

Dans la boîte de dialogue Gérer les packages NuGet, confirmez que la source du package est définie sur nuget.org.

Avec Parcourir sélectionné, entrez Microsoft.AspNetCore.SignalR.Client dans la zone de recherche.

Dans les résultats de la recherche, sélectionnez le package Microsoft.AspNetCore.SignalR.Client. Définissez la version pour qu’elle corresponde à l’infrastructure partagée de l’application. Cliquez sur Installer.

Si la fenêtre de dialogue Aperçu des modifications s’affiche, sélectionnez OK.

Si la boîte de dialogue Acceptation de la licence s’affiche, sélectionnez J’accepte si vous acceptez les termes du contrat de licence.

Ajouter un hub SignalR

Dans le projet BlazorWebAssemblySignalRApp.Server, créez un dossier (au pluriel) Hubs et ajoutez la classe ChatHub suivante (Hubs/ChatHub.cs) :

using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

namespace BlazorWebAssemblySignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Ajouter des services et un point de terminaison au hub SignalR

Dans le projet BlazorWebAssemblySignalRApp.Server, ouvrez le fichier Program.cs.

Ajoutez l’espace de noms de la classe ChatHub en haut du fichier :

using BlazorWebAssemblySignalRApp.Server.Hubs;

Ajoutez SignalR et des services Middleware de compression des réponses :

builder.Services.AddSignalR();
builder.Services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Utilisez le Middleware de compression des réponses en haut de la configuration du pipeline de traitement, de suite après la ligne qui génère l’application :

app.UseResponseCompression();

Entre les points de terminaison des contrôleurs et le secours côté client, ajoutez un point de terminaison pour le hub. De suite après la ligne app.MapControllers();, ajoutez la ligne suivante :

app.MapHub<ChatHub>("/chathub");

Dans le projet BlazorWebAssemblySignalRApp.Server, ouvrez le fichier Startup.cs.

Ajoutez l’espace de noms de la classe ChatHub en haut du fichier :

using BlazorWebAssemblySignalRApp.Server.Hubs;

Ajoutez SignalR et des services Middleware de compression des réponses :

services.AddSignalR();
services.AddResponseCompression(opts =>
{
      opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
         new[] { "application/octet-stream" });
});

Utilisez Response Compression Middleware en haut de la configuration du pipeline de traitement :

app.UseResponseCompression();

Entre les points de terminaison des contrôleurs et le mécanisme de secours côté client, ajoutez un point de terminaison pour le hub de suite après la ligne endpoints.MapControllers(); :

endpoints.MapHub<ChatHub>("/chathub");

Ajouter le code de composant Razor pour la conversation

Dans le projet BlazorWebAssemblySignalRApp.Client, ouvrez le fichier Pages/Index.razor.

Remplacez la balise par le code suivant :

@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@implements IAsyncDisposable

<PageTitle>Index</PageTitle>

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection? hubConnection;
    private List<string> messages = new List<string>();
    private string? userInput;
    private string? messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    private async Task Send()
    {
        if (hubConnection is not null)
            {
                await hubConnection.SendAsync("SendMessage", userInput, messageInput);
            }
    }

    public bool IsConnected =>
        hubConnection?.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IAsyncDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

<div class="form-group">
    <label>
        User:
        <input @bind="userInput" />
    </label>
</div>
<div class="form-group">
    <label>
        Message:
        <input @bind="messageInput" size="50" />
    </label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
    @foreach (var message in messages)
    {
        <li>@message</li>
    }
</ul>

@code {
    private HubConnection hubConnection;
    private List<string> messages = new List<string>();
    private string userInput;
    private string messageInput;

    protected override async Task OnInitializedAsync()
    {
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            messages.Add(encodedMsg);
            StateHasChanged();
        });

        await hubConnection.StartAsync();
    }

    async Task Send() =>
        await hubConnection.SendAsync("SendMessage", userInput, messageInput);

    public bool IsConnected =>
        hubConnection.State == HubConnectionState.Connected;

    public void Dispose()
    {
        _ = hubConnection?.DisposeAsync();
    }
}

Notes

Lorsque vous utilisez le Rechargement à chaud, désactivez l’intergiciel de compression de réponse dans l’environnement Development. Pour plus d’informations, consultez Aide relative à ASP.NET Core BlazorSignalR.

Exécuter l’application

Suivez l’aide relative à vos outils :

Dans l'Explorateur de solutions, sélectionnez le projet BlazorWebAssemblySignalRApp.Server. Appuyez sur F5 pour exécuter l’application avec le débogage ou sur Ctrl+F5 (Windows)/+F5 (macOS) pour exécuter l’application sans débogage.

Important

Lors de l’exécution d’une application Blazor WebAssembly hébergée, exécutez l’application à partir du projet Server de la solution.

Google Chrome ou Microsoft Edge doit être le navigateur sélectionné pour une session de débogage.

Si l’application ne parvient pas à démarrer dans le navigateur :

  • Dans la console .NET, confirmez que la solution s’exécute à partir du projet « Server ».
  • Actualisez le navigateur à l’aide du bouton de rechargement du navigateur.

Copiez l’URL à partir de la barre d’adresse, ouvrez un autre onglet ou instance du navigateur, puis collez l’URL dans la barre d’adresse.

Choisissez un des navigateurs, entrez un nom et un message, puis sélectionnez le bouton pour envoyer le message. Le nom et le message sont affichés instantanément dans les deux pages :

Exemple SignalRBlazor d’application ouverte dans deux fenêtres de navigateur affichant des messages échangés.

Citations : Star Trek VI : Terre inconnue ©1991 Paramount

Étapes suivantes

Dans ce didacticiel, vous avez appris à :

  • Créer une application Blazor
  • Ajouter la bibliothèque cliente SignalR
  • Ajouter un hub SignalR
  • Ajouter des services SignalR et un point de terminaison pour le hub SignalR
  • Ajouter un code de composant Razor pour la conversation

Pour obtenir une aide détaillée sur les frameworks SignalR et Blazor, consultez les ensembles de documentation de référence suivants :

Ressources supplémentaires