Uso de ASP.NET Core SignalR con Blazor

Nota

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión ASP.NET Core 8.0 de este artículo.

En este tutorial se proporciona una experiencia de trabajo básica para crear una aplicación en tiempo real mediante SignalR con Blazor. Este artículo es útil para los desarrolladores que ya están familiarizados con SignalR y que buscan comprender cómo usar SignalR en una aplicación Blazor. Para obtener instrucciones detalladas sobre los marcos SignalR y Blazor, consulte los siguientes conjuntos de documentación de referencia y la documentación de la API:

Obtenga información sobre cómo:

  • Creación de una aplicación Blazor
  • Adición de la biblioteca cliente de SignalR
  • Agregar un concentrador de SignalR
  • Agregar servicios de SignalR y un punto de conexión para el concentrador de SignalR
  • Agregar un código de componente de Razor para chat

Al final de este tutorial, tendrá una aplicación de chat funcional.

Requisitos previos

Visual Studio 2022 o versiones posteriores con la carga de trabajo Desarrollo web y ASP.NET

Aplicación de ejemplo

No es necesario descargar la aplicación de chat de ejemplo para este tutorial. La aplicación de ejemplo es la aplicación final ya operativa que se crea siguiendo los pasos de este tutorial.

Vea o descargue el código de ejemplo (cómo descargarlo)

Crear una aplicación web de Blazor

Siga las instrucciones para su elección de herramientas:

Nota

Se requiere Visual Studio 2022 o posterior y el SDK de .NET Core 8.0.0 o posterior.

Cree un nuevo proyecto.

Seleccione la plantilla Blazor Aplicación web. Seleccione Siguiente.

Escriba BlazorSignalRApp en el campo Nombre del proyecto. Confirme que la entrada de Ubicación es correcta o proporcione una ubicación para el proyecto. Seleccione Siguiente.

Confirme que el Marco sea .NET 8 o posterior. Seleccione Crear.

Adición de la biblioteca cliente de SignalR

En el Explorador de soluciones, haga clic con el botón derecho en el proyecto BlazorSignalRApp y seleccione Administrar paquetes NuGet.

En el cuadro de diálogo Administrar paquetes NuGet, confirme que Origen del paquete se ha establecido en nuget.org.

Con Examinar seleccionado, escriba Microsoft.AspNetCore.SignalR.Client en el cuadro de búsqueda.

En los resultados de la búsqueda, seleccione la versión más reciente del paquete Microsoft.AspNetCore.SignalR.Client. Seleccione Instalar.

Si aparece el cuadro de diálogo Vista previa de los cambios, seleccione Aceptar.

Si aparece el cuadro de diálogo Aceptación de la licencia, seleccione Acepto si está de acuerdo con los términos de la licencia.

Agregar un concentrador de SignalR

Cree una carpeta Hubs (plural) y agregue la siguiente clase ChatHub (Hubs/ChatHub.cs) a la raíz de la aplicación:

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

Adición de servicios y de un punto de conexión para el concentrador de SignalR

Abra el archivo Program .

Agregue los espacios de nombres para Microsoft.AspNetCore.ResponseCompression y la clase ChatHub en la parte superior del archivo:

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

Agregue servicios de middleware de compresión de respuesta:

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

Use el middleware de compresión de respuesta de la parte superior de la configuración de la canalización de procesamiento.

app.UseResponseCompression();

Agregue un punto de conexión para el centro inmediatamente después de la línea que asigna los componentes Razor (app.MapRazorComponents<T>()):

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

Agregar código de componente de Razor para chat

Abra el archivo Components/Pages/Home.razor .

Reemplace el marcado con el código siguiente:

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

<PageTitle>Home</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);
            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();
        }
    }
}

Nota

Deshabilite el middleware de compresión de respuesta en el entorno Development al usar Recarga activa. Para obtener más información, vea las Instrucciones de ASP.NET Core BlazorSignalR.

Ejecutar la aplicación

Siga las instrucciones para las herramientas:

Presione F5 para ejecutar la aplicación con depuración o Ctrl+F5 (Windows)/+F5 (macOS) para ejecutarla sin depuración.

Copie la dirección URL de la barra de direcciones, abra otra instancia o pestaña del explorador, y pegue la dirección URL en la barra de direcciones.

Elija cualquier explorador, escriba un nombre y un mensaje, y haga clic en el botón para enviar el mensaje. El nombre y el mensaje se muestran en ambas páginas al instante:

SignalRBlazor sample app open in two browser windows showing exchanged messages.

Cita: Star Trek VI: The Undiscovered Country ©1991 Paramount

Experiencia de Blazor WebAssembly hospedada

Creación de la aplicación

Siga las instrucciones para elegir herramientas para crear una aplicación de Blazor WebAssembly hospedada:

Nota

Se requiere Visual Studio 2022 o posterior y el SDK de .NET Core 6.0.0 o posterior.

Cree un nuevo proyecto.

Elija la plantilla Aplicación de Blazor WebAssembly . Seleccione Siguiente.

Escriba BlazorWebAssemblySignalRApp en el campo Nombre del proyecto. Confirme que la entrada de Ubicación es correcta o proporcione una ubicación para el proyecto. Seleccione Siguiente.

Active la casilla ASP.NET Core hospedado del cuadro de diálogo Información adicional.

Seleccione Crear.

Confirme que se ha creado una aplicación hospedadaBlazor WebAssembly: en Explorador de soluciones, confirme la presencia de un proyecto Client y un proyecto Server. Si los dos proyectos no están presentes, vuelva a iniciar y confirme la selección de la casilla ASP.NET Core hospedado antes de seleccionar Crear.

Adición de la biblioteca cliente de SignalR

En el Explorador de soluciones, haga clic con el botón derecho en el proyecto BlazorWebAssemblySignalRApp.Client y seleccione Administrar paquetes NuGet.

En el cuadro de diálogo Administrar paquetes NuGet, confirme que Origen del paquete se ha establecido en nuget.org.

Con Examinar seleccionado, escriba Microsoft.AspNetCore.SignalR.Client en el cuadro de búsqueda.

En los resultados de la búsqueda, seleccione el paquete Microsoft.AspNetCore.SignalR.Client. Establezca la versión para que coincida con el marco compartido de la aplicación. Seleccione Instalar.

Si aparece el cuadro de diálogo Vista previa de los cambios, seleccione Aceptar.

Si aparece el cuadro de diálogo Aceptación de la licencia, seleccione Acepto si está de acuerdo con los términos de la licencia.

Agregar un concentrador de SignalR

En el proyecto BlazorWebAssemblySignalRApp.Server, cree una carpeta Hubs (plural) y agregue la siguiente clase ChatHub (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);
        }
    }
}

Adición de servicios y de un punto de conexión para el concentrador de SignalR

En el proyecto BlazorWebAssemblySignalRApp.Server, abra el archivo Program.cs.

Agregue el espacio de nombres para la clase ChatHub en la parte superior del archivo:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Agregue SignalR y servicios de middleware de compresión de respuesta:

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

Use middleware de compresión de respuesta en la parte superior de la configuración de la canalización de procesamiento inmediatamente después de la línea que compila la aplicación:

app.UseResponseCompression();

Entre los puntos de conexión de los controladores y la reserva del lado cliente, agregue un punto de conexión para el concentrador. Inmediatamente después de la línea app.MapControllers();, agregue la línea siguiente:

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

En el proyecto BlazorWebAssemblySignalRApp.Server, abra el archivo Startup.cs.

Agregue el espacio de nombres para la clase ChatHub en la parte superior del archivo:

using BlazorWebAssemblySignalRApp.Server.Hubs;

Agregue SignalR y servicios de middleware de compresión de respuesta:

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

Use el middleware de compresión de respuesta de la parte superior de la configuración de la canalización de procesamiento.

app.UseResponseCompression();

Entre los puntos de conexión de los controladores y la reserva del lado cliente, agregue un punto de conexión para el concentrador después de la línea endpoints.MapControllers();:

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

Agregar código de componente de Razor para chat

En el proyecto BlazorWebAssemblySignalRApp.Client, abra el archivo Pages/Index.razor.

Reemplace el marcado con el código siguiente:

@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();
    }
}

Nota

Deshabilite el middleware de compresión de respuesta en el entorno Development al usar Recarga activa. Para obtener más información, vea las Instrucciones de ASP.NET Core BlazorSignalR.

Ejecutar la aplicación

Siga las instrucciones para las herramientas:

En el Explorador de soluciones, seleccione el proyecto BlazorWebAssemblySignalRApp.Server. Presione F5 para ejecutar la aplicación con depuración o Ctrl+F5 (Windows)/+F5 (macOS) para ejecutarla sin depuración.

Importante

Al ejecutar una aplicación hospedada Blazor WebAssembly, ejecute la aplicación desde el proyecto Serverde la solución.

El explorador seleccionado para una sesión de depuración debe ser Google Chrome o Microsoft Edge.

Si la aplicación no se inicia en el explorador:

  • En la consola de .NET, confirme que la solución se ejecuta desde el proyecto "Server".
  • Actualice el explorador mediante su botón de recarga.

Copie la dirección URL de la barra de direcciones, abra otra instancia o pestaña del explorador, y pegue la dirección URL en la barra de direcciones.

Elija cualquier explorador, escriba un nombre y un mensaje, y haga clic en el botón para enviar el mensaje. El nombre y el mensaje se muestran en ambas páginas al instante:

SignalRBlazor sample app open in two browser windows showing exchanged messages.

Cita: Star Trek VI: The Undiscovered Country ©1991 Paramount

Experiencia de Blazor Server

Creación de la aplicación

Siga las instrucciones para elegir herramientas para crear una aplicación de Blazor Server:

Nota

Se requiere Visual Studio 2022 o posterior y el SDK de .NET Core 6.0.0 o posterior.

Cree un nuevo proyecto.

Seleccione la plantilla Aplicación de Blazor Server . Seleccione Siguiente.

Escriba BlazorServerSignalRApp en el campo Nombre del proyecto. Confirme que la entrada de Ubicación es correcta o proporcione una ubicación para el proyecto. Seleccione Siguiente.

Seleccione Crear.

Adición de la biblioteca cliente de SignalR

En el Explorador de soluciones, haga clic con el botón derecho en el proyecto BlazorServerSignalRApp y seleccione Administrar paquetes NuGet.

En el cuadro de diálogo Administrar paquetes NuGet, confirme que Origen del paquete se ha establecido en nuget.org.

Con Examinar seleccionado, escriba Microsoft.AspNetCore.SignalR.Client en el cuadro de búsqueda.

En los resultados de la búsqueda, seleccione el paquete Microsoft.AspNetCore.SignalR.Client. Establezca la versión para que coincida con el marco compartido de la aplicación. Seleccione Instalar.

Si aparece el cuadro de diálogo Vista previa de los cambios, seleccione Aceptar.

Si aparece el cuadro de diálogo Aceptación de la licencia, seleccione Acepto si está de acuerdo con los términos de la licencia.

Adición del paquete System.Text.Encodings.Web

Esta sección solo se aplica a las aplicaciones para ASP.NET Core versión 3.x.

Debido a un problema de resolución de paquetes al usar System.Text.Json 5.x en una aplicación ASP.NET Core 3.x, el proyecto requiere una referencia al paquete para System.Text.Encodings.Web. El problema subyacente se resolvió en una versión de revisión y se trasladó a ASP.NET Core 5.0. Para más información, vea System.Text.Json define netcoreapp3.0 sin dependencias (dotnet/runtime #45560).

Para agregar System.Text.Encodings.Web al proyecto, siga las instrucciones correspondientes a la herramienta de su elección:

En el Explorador de soluciones, haga clic con el botón derecho en el proyecto BlazorServerSignalRApp y seleccione Administrar paquetes NuGet.

En el cuadro de diálogo Administrar paquetes NuGet, confirme que Origen del paquete se ha establecido en nuget.org.

Con Examinar seleccionado, escriba System.Text.Encodings.Web en el cuadro de búsqueda.

En los resultados de la búsqueda, seleccione el paquete System.Text.Encodings.Web. Seleccione la versión del paquete que coincida con el marco compartido en uso. Seleccione Instalar.

Si aparece el cuadro de diálogo Vista previa de los cambios, seleccione Aceptar.

Si aparece el cuadro de diálogo Aceptación de la licencia, seleccione Acepto si está de acuerdo con los términos de la licencia.

Agregar un concentrador de SignalR

Cree una carpeta Hubs (en plural) y agregue la siguiente clase ChatHub (Hubs/ChatHub.cs):

using Microsoft.AspNetCore.SignalR;

namespace BlazorServerSignalRApp.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 BlazorServerSignalRApp.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 BlazorServerSignalRApp.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 BlazorServerSignalRApp.Server.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Adición de servicios y de un punto de conexión para el concentrador de SignalR

Abra el archivo Program.cs .

Agregue los espacios de nombres para Microsoft.AspNetCore.ResponseCompression y la clase ChatHub en la parte superior del archivo:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorServerSignalRApp.Server.Hubs;

Agregue servicios de middleware de compresión de respuesta:

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

Use el middleware de compresión de respuesta de la parte superior de la configuración de la canalización de procesamiento.

app.UseResponseCompression();

Entre los puntos de conexión para asignar el concentrador Blazor y la reserva del lado cliente, agregue un punto de conexión para el concentrador inmediatamente después de la línea app.MapBlazorHub();:

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

Abra el archivo Startup.cs .

Agregue los espacios de nombres para Microsoft.AspNetCore.ResponseCompression y la clase ChatHub en la parte superior del archivo:

using Microsoft.AspNetCore.ResponseCompression;
using BlazorServerSignalRApp.Server.Hubs;

Agregue servicios de middleware de compresión de respuesta:

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

Use el middleware de compresión de respuesta de la parte superior de la configuración de la canalización de procesamiento.

app.UseResponseCompression();

Entre los puntos de conexión para asignar el concentrador Blazor y la reserva del lado cliente, agregue un punto de conexión para el concentrador inmediatamente después de la línea endpoints.MapBlazorHub();:

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

Agregar código de componente de Razor para chat

Abra el archivo Pages/Index.razor .

Reemplace el marcado con el código siguiente:

@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);
            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();
        }
    }
}
@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);
            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();
        }
    }
}
@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);
            InvokeAsync(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 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);
            InvokeAsync(StateHasChanged);
        });

        await hubConnection.StartAsync();
    }

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

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

    public async ValueTask DisposeAsync()
    {
        await hubConnection?.DisposeAsync();
    }
}

Nota

Deshabilite el middleware de compresión de respuesta en el entorno Development al usar Recarga activa. Para obtener más información, vea las Instrucciones de ASP.NET Core BlazorSignalR.

Ejecutar la aplicación

Siga las instrucciones para las herramientas:

Presione F5 para ejecutar la aplicación con depuración o Ctrl+F5 (Windows)/+F5 (macOS) para ejecutarla sin depuración.

Copie la dirección URL de la barra de direcciones, abra otra instancia o pestaña del explorador, y pegue la dirección URL en la barra de direcciones.

Elija cualquier explorador, escriba un nombre y un mensaje, y haga clic en el botón para enviar el mensaje. El nombre y el mensaje se muestran en ambas páginas al instante:

SignalRBlazor sample app open in two browser windows showing exchanged messages.

Cita: Star Trek VI: The Undiscovered Country ©1991 Paramount

Pasos siguientes

En este tutorial, ha aprendido a:

  • Creación de una aplicación Blazor
  • Adición de la biblioteca cliente de SignalR
  • Agregar un concentrador de SignalR
  • Agregar servicios de SignalR y un punto de conexión para el concentrador de SignalR
  • Agregar un código de componente de Razor para chat

Para obtener instrucciones detalladas sobre los marcos SignalR y Blazor, consulte los siguientes conjuntos de documentación de referencia:

Recursos adicionales