Использование SignalR с JavaScript

В этой статье я покажу базовые навыки построения приложения в реальном времени используя SignalR.

  • Создаем веб-проект
  • Добавить клиентскую библиотеку SignalR
  • Добавить хаб SignalR
  • Сконфигурируем проект, чтобы запустить SignalR в классе Startup.
  • Добавим код, который отсылает сообщения клиентским приложениям.
пример приложения signalr на javascript

Создаем веб-проект

  • В VisualStudio выберите File > New Project
  • В диалоговом окне «Create a new project» выберите «ASP.NET Core Web Application«, и нажмите Next.
  • В диалоговом окне «Configure your new project«, назовите проект, например «SignalRJavaScript«, и нажмите Create.
  • В диалоговом окне «Create a new ASP.NET Core web Application«, выберите .NET Core и ASP.NET Core 3.0.
  • Выберите Web Application чтобы создать проект на основе рейзор страниц (Razor Pages), и далее нажмите Create.

Добавить клиентскую библиотеку SignalR

Сама инфраструктура SignalR уже влючина в APS.NET Core 3.0. Но клиентской библиотеки нет. Поэтому запустите библиотечного менеджера (LibMan) и подгрузите библиотеку unpkg.

  • Перейдите на Обозреватель решений / Solution Explorer щелкните по проекту правой кнопкой и выберите Add > Client-Side Library.
  • В диалоге «Add Client-Side Library» в секции провайдер / Provider выберите «unpkg»
  • Чтобы подгрузить клиентскую библиотеку наберите название » @microsoft/signalr@latest«

Добавить хаб SignalR

Все классы унаследованые от класса Hub это высокоуровневая обертка над клиент-серверной комуникацией.

  • Добавим в корень проекта свой класс ChatHub.cs с кодом внутри.
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;

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

Сам класс Hub управляет соединениями, группами и сообщениями. Обратите внимание на метод SendMessage. Данный метод кастомный т.е. вы можете назвать его как угодно. Данный метод после компиляции появиться в JavaScript-е и из этого скрипта мы сможем вызвать его. Т.е. вызвать SendMessage на стороне клиента. В свою очередь метод SendAsync запускает событиеReceiveMessage к которому можно подписаться на стороне клиента.

Сконфигурируем проект, чтобы запустить SignalR в классе Startup.

Добавьте две строчки:
1. services.AddSignalR();
2. endpoints.MapHub<ChatHub>(«/chatHub»);

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace SignalRJavaScript
{
    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(); <---------- 1.
        }

        // 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"); <---------- 2.
            });
        }
    }
}

Добавим код, который отсылает сообщения клиентским приложениям.

В файл Pages/index.cshtml добавьте следующую разметкую

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<div class="container">
    <div class="row"> </div>
    <div class="row">
        <div class="col-2">User</div>
        <div class="col-4"><input class="form-control" type="text" id="userInput" /></div>
    </div>
    <div class="row">
        <div class="col-2">Message</div>
        <div class="col-4"><textarea class="form-control" type="text" id="messageInput"></textarea></div>
    </div>
    <div class="row"> </div>
    <div class="row">
        <div class="col-6">
            <input class="btn btn-primary" 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="~/lib/@@microsoft/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

Добавьте файл JavaScript chat.js с кодом.

"use strict";

// Получим наш объект "соединение"
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

// Кнопка будет неактивная, до тех пор, пока нет соединения.
document.getElementById("sendButton").disabled = true;

// Навешиваем событие click на элемент с id = "sendButton"
// Т.е. когда мы кликаем по кнопке, то запускается наша функция обраного вызова.
document.getElementById("sendButton").addEventListener("click", function (event) {
	// Берем тексты из контролов <input />
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
	
	// Тут черзе объект connection фактически запускаем метод "SendMessage" на сервере, 
	// который в свою очередь с сервера оповестит всех подписчиков методом "ReceiveMessage".
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
	
    event.preventDefault();
});

// Подписываемся к событию "ReceiveMessage". 
// Данное событие запускается на сервере (в коде c# это метод "ReceiveMessage"), а js "слушает его"
connection.on("ReceiveMessage", function (user, message) {
	// Как только событие отработает запуститься наша функция обратного вызова callback function
    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());
});

  • var connection = new signalR.HubConnectionBuilder().withUrl(«/chatHub»).build(); — получаем наш хаб.
  • connection.invoke(«SendMessage», user, message) — отправляем сообщение
  • connection.on(«ReceiveMessage», function(user, msg ){}) — слушаем событие ReceiveMessage, которое запускается на сервере.

Comments are closed.