Tutorial: Introducción a ASP.NET Core SignalR
En este tutorial se describen los conceptos básicos de la creación de una aplicación en tiempo real con SignalR. Aprenderá a:
- Cree un proyecto web.
- Agregar la biblioteca cliente SignalR.
- Crear un concentrador de SignalR.
- Configurar el proyecto para usar SignalR.
- Agregar código que envía mensajes desde cualquier cliente a todos los clientes conectados.
Al final, tendrá una aplicación de chat funcional:

Requisitos previos
Versión 16.4 o posterior de Visual Studio 2019 con la carga de trabajo Desarrollo web y ASP.NET
Crear un proyecto de aplicación web
- En el menú, seleccione Archivo > Nuevo proyecto.
- En el cuadro de diálogo Crear un proyecto nuevo, seleccione Aplicación web ASP.NET Core y, a continuación, seleccione Siguiente.
- En el cuadro de diálogo Configurar el nuevo proyecto, asigne al proyecto el nombre SignalRChat y, a continuación, seleccione Crear.
- En el cuadro de diálogo Crear una aplicación web ASP.NET Core, seleccione .NET Core y ASP.NET Core 3.1.
- Seleccione Aplicación web para crear un proyecto en el que se use Razor Pages y luego seleccione Crear.

Adición de la biblioteca cliente de SignalR
La biblioteca de servidor de SignalR se incluye en el marco compartido de ASP.NET Core 3.1. La biblioteca cliente de JavaScript no se incluye automáticamente en el proyecto. En este tutorial, usará el Administrador de bibliotecas (LibMan) para obtener la biblioteca cliente de unpkg. unpkg es una red de entrega de contenido (CDN) que puede entregar todo lo que encuentre en npm, el administrador de paquetes de Node.js.
- En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Agregar > Biblioteca del lado cliente.
- En el cuadro de diálogo Add Client-Side Library (Agregar biblioteca del lado cliente), en Proveedor, seleccione unpkg.
- Para Biblioteca, indique
@microsoft/signalr@latest. - Seleccione Choose specific files (Elegir archivos específicos), expanda la carpeta dist/browser y seleccione signalr.js y signalr.min.js.
- Establezca Ubicación de destino en wwwroot/js/signalr/ y seleccione Instalar.

LibMan crea una carpeta wwwroot/js/signalr y copia en ella los archivos seleccionados.
Creación de un concentrador de SignalR
Un concentrador es una clase que actúa como una canalización general que controla la comunicación entre el cliente y el servidor.
- En la carpeta del proyecto SignalRChat, cree una carpeta Hubs.
- En la carpeta Hubs, cree un archivo ChatHub.cs con el código siguiente:
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace SignalRChat.Hubs
{
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
La clase ChatHub hereda de la clase Hub de SignalR. La clase Hub administra las conexiones, los grupos y la mensajería.
Puede llamarse al método SendMessage mediante un cliente conectado para enviar un mensaje a todos los clientes. El código de cliente de JavaScript que llama al método se muestra más adelante en el tutorial. El código de SignalR es asincrónico para proporcionar la máxima escalabilidad.
Configuración de SignalR
El servidor de SignalR debe estar configurado para pasar solicitudes de SignalR a SignalR.
Agregue el código resaltado siguiente al archivo Startup.cs.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using SignalRChat.Hubs; namespace SignalRChat { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddSignalR(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapHub<ChatHub>("/chatHub"); }); } } }Estos cambios agregan SignalR a los sistemas de inserción de dependencias y enrutamiento de ASP.NET Core.
Adición del código del cliente de SignalR
Reemplace el contenido de Pages/Index.cshtml con el código siguiente:
@page <div class="container"> <div class="row"> </div> <div class="row"> <div class="col-2">User</div> <div class="col-4"><input type="text" id="userInput" /></div> </div> <div class="row"> <div class="col-2">Message</div> <div class="col-4"><input type="text" id="messageInput" /></div> </div> <div class="row"> </div> <div class="row"> <div class="col-6"> <input type="button" id="sendButton" value="Send Message" /> </div> </div> </div> <div class="row"> <div class="col-12"> <hr /> </div> </div> <div class="row"> <div class="col-6"> <ul id="messagesList"></ul> </div> </div> <script src="~/js/signalr/dist/browser/signalr.js"></script> <script src="~/js/chat.js"></script>El código anterior:
- Crea cuadros de texto para el nombre y el mensaje de texto, y un botón de envío.
- Crea una lista con
id="messagesList"para mostrar los mensajes que se reciben desde el concentrador de SignalR. - Incluye las referencias de script a SignalR y el código de aplicación de chat.js que se va a crear en el paso siguiente.
En la carpeta wwwroot/js, cree un archivo chat.js con el código siguiente:
"use strict"; var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build(); //Disable send button until connection is established document.getElementById("sendButton").disabled = true; connection.on("ReceiveMessage", function (user, message) { var li = document.createElement("li"); document.getElementById("messagesList").appendChild(li); // We can assign user-supplied strings to an element's textContent because it // is not interpreted as markup. If you're assigning in any other way, you // should be aware of possible script injection concerns. li.textContent = `${user} says ${message}`; }); connection.start().then(function () { document.getElementById("sendButton").disabled = false; }).catch(function (err) { return console.error(err.toString()); }); document.getElementById("sendButton").addEventListener("click", function (event) { var user = document.getElementById("userInput").value; var message = document.getElementById("messageInput").value; connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); event.preventDefault(); });El código anterior:
- Crea e inicia una conexión.
- Agrega al botón de envío un controlador que envía mensajes al concentrador.
- Agrega al objeto de conexión un controlador que recibe mensajes desde el concentrador y los agrega a la lista.
Ejecutar la aplicación
- Presione CTRL+F5 para ejecutar la aplicación sin depurar.
- 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 Enviar mensaje. El nombre y el mensaje se muestran en ambas páginas al instante.

Sugerencia
Si la aplicación no funciona, abra las herramientas para desarrolladores del explorador (F12) y vaya a la consola. Es posible que vea errores relacionados con el código HTML y JavaScript. Por ejemplo, suponga que coloca signalr.js en una carpeta distinta a la indicada. En ese caso, la referencia a ese archivo no funcionará y verá un error 404 en la consola.

Si se produce el error ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY en Chrome, ejecute estos comandos para actualizar el certificado de desarrollo:
dotnet dev-certs https --clean dotnet dev-certs https --trust
En este tutorial se describen los conceptos básicos de la creación de una aplicación en tiempo real con SignalR. Aprenderá a:
- Cree un proyecto web.
- Agregar la biblioteca cliente SignalR.
- Crear un concentrador de SignalR.
- Configurar el proyecto para usar SignalR.
- Agregar código que envía mensajes desde cualquier cliente a todos los clientes conectados.
Al final, tendrá una aplicación de chat en funcionamiento:
.
Requisitos previos
- Versión 15.9 o posterior de Visual Studio 2017 con la carga de trabajo Desarrollo web y ASP.NET. Puede usar Visual Studio 2019, pero algunos pasos de creación del proyecto no son exactamente los mismos que se muestran en el tutorial.
- .NET Core SDK 2.2 o posterior
Advertencia
Si usa Visual Studio 2017, consulte dotnet/sdk problema #3124 para información sobre las versiones del SDK de .NET Core que no funcionan con Visual Studio.
Creación de un proyecto web
En el menú, seleccione Archivo > Nuevo proyecto.
En el cuadro de diálogo Nuevo proyecto, seleccione Instalado > Visual C# > Web > Aplicación web ASP.NET Core. Asigne el nombre SignalRChat al proyecto.

Seleccione Aplicación web para crear un proyecto en el que se use Razor Pages.
Seleccione una plataforma de destino de .NET Core, seleccione ASP.NET Core 2.2 y haga clic en Aceptar.

Adición de la biblioteca cliente de SignalR
La biblioteca de servidor de SignalR se incluye en el metapaquete Microsoft.AspNetCore.App. La biblioteca cliente de JavaScript no se incluye automáticamente en el proyecto. En este tutorial, usará el Administrador de bibliotecas (LibMan) para obtener la biblioteca cliente de unpkg. unpkg es una red de entrega de contenido (CDN) que puede entregar todo lo que encuentre en npm, el administrador de paquetes de Node.js.
En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Agregar > Biblioteca del lado cliente.
En el cuadro de diálogo Add Client-Side Library (Agregar biblioteca del lado cliente), en Proveedor, seleccione unpkg.
En Biblioteca, escriba
@microsoft/signalr@3y seleccione la versión más reciente que no sea una versión preliminar.
Seleccione Choose specific files (Elegir archivos específicos), expanda la carpeta dist/browser y seleccione signalr.js y signalr.min.js.
Establezca Ubicación de destino en wwwroot/lib/signalr/ y seleccione Instalar.

LibMan crea una carpeta wwwroot/lib/signalr y copia en ella los archivos seleccionados.
Creación de un concentrador de SignalR
Un concentrador es una clase que actúa como una canalización general que controla la comunicación entre el cliente y el servidor.
En la carpeta del proyecto SignalRChat, cree una carpeta Hubs.
En la carpeta Hubs, cree un archivo ChatHub.cs con el código siguiente:
using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRChat.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } } }La clase
ChatHubhereda de la claseHubde SignalR. La claseHubadministra las conexiones, los grupos y la mensajería.Puede llamarse al método
SendMessagemediante un cliente conectado para enviar un mensaje a todos los clientes. El código de cliente de JavaScript que llama al método se muestra más adelante en el tutorial. El código de SignalR es asincrónico para proporcionar la máxima escalabilidad.
Configuración de SignalR
El servidor de SignalR debe estar configurado para pasar solicitudes de SignalR a SignalR.
Agregue el código resaltado siguiente al archivo Startup.cs.
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SignalRChat.Hubs; namespace SignalRChat { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSignalR(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseSignalR(routes => { routes.MapHub<ChatHub>("/chathub"); }); app.UseMvc(); } } }Estos cambios agregan SignalR al sistema de inserción de dependencias de ASP.NET Core y a la canalización de software intermedio.
Adición del código del cliente de SignalR
Reemplace el contenido de Pages/Index.cshtml con el código siguiente:
@page <div class="container"> <div class="row"> </div> <div class="row"> <div class="col-6"> </div> <div class="col-6"> User..........<input type="text" id="userInput" /> <br /> Message...<input type="text" id="messageInput" /> <input type="button" id="sendButton" value="Send Message" /> </div> </div> <div class="row"> <div class="col-12"> <hr /> </div> </div> <div class="row"> <div class="col-6"> </div> <div class="col-6"> <ul id="messagesList"></ul> </div> </div> </div> <script src="~/lib/signalr/dist/browser/signalr.js"></script> <script src="~/js/chat.js"></script>El código anterior:
- Crea cuadros de texto para el nombre y el mensaje de texto, y un botón de envío.
- Crea una lista con
id="messagesList"para mostrar los mensajes que se reciben desde el concentrador de SignalR. - Incluye las referencias de script a SignalR y el código de aplicación de chat.js que se va a crear en el paso siguiente.
En la carpeta wwwroot/js, cree un archivo chat.js con el código siguiente:
"use strict"; var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build(); //Disable send button until connection is established document.getElementById("sendButton").disabled = true; connection.on("ReceiveMessage", function (user, message) { var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); var encodedMsg = user + " says " + msg; var li = document.createElement("li"); li.textContent = encodedMsg; document.getElementById("messagesList").appendChild(li); }); connection.start().then(function(){ document.getElementById("sendButton").disabled = false; }).catch(function (err) { return console.error(err.toString()); }); document.getElementById("sendButton").addEventListener("click", function (event) { var user = document.getElementById("userInput").value; var message = document.getElementById("messageInput").value; connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); event.preventDefault(); });El código anterior:
- Crea e inicia una conexión.
- Agrega al botón de envío un controlador que envía mensajes al concentrador.
- Agrega al objeto de conexión un controlador que recibe mensajes desde el concentrador y los agrega a la lista.
Ejecutar la aplicación
- Presione CTRL+F5 para ejecutar la aplicación sin depurar.
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 Enviar mensaje.
El nombre y el mensaje se muestran en ambas páginas al instante.

Sugerencia
Si la aplicación no funciona, abra las herramientas para desarrolladores del explorador (F12) y vaya a la consola. Es posible que vea errores relacionados con el código HTML y JavaScript. Por ejemplo, suponga que coloca signalr.js en una carpeta distinta a la indicada. En ese caso, la referencia a ese archivo no funcionará y verá un error 404 en la consola.
