Thứ Tư, 19 tháng 9, 2018

Làm quen với SignalR trên ASP.NET Core sử dụng Visual Studio


Bài viết này hướng dẫn bạn những điều cơ bản về xây dựng ứng dụng thời gian thực (real-time) bằng cách sử dụng thư viện SignalR. Bạn sẽ học làm thế nào để:

  • Tạo 1 ứng dụng web sử dụng SignalR trên ASP.NET Core.
  • Tạo 1 SignalR hub trên server.
  • Kết nối đến SignalR hub từ client thông qua Javascript.
  • Sử dụng hub để gửi tin nhắn từ máy khách bất kỳ đến tất cả máy khách đã kết nối với ứng dụng.
Cuối cùng, bạn sẽ có 1 ứng dụng chat trực tuyến như hình dưới:



Điều kiện tiên quyết



Tạo project


  • Từ Menu chọn File > New Project.
  • Trong hộp thoại New Project, chọn Installed > Visual C# > Web > ASP.NET Core Web Application. Đặt tên project là SignalRChat.


  • Chọn Web Application để tạo project sử dụng Razor Pages.
  • Chọn ASP.NET Core 2.1 và click OK


Thêm thư viện SignalR


Để thêm thư viện SignalR bạn phải sử dụng công cụ Library Manager (LibMan) có sẵn ở Visual Studio 2017 15.8 trở lên. 
  • Trong Solution Explorer, click phải vào project và chọn Add > Client-Side Library.
  • Trên hộp thoại Add Client-Side Library, chọn Provider unpk.
  • Ở ôLibrary, nhập @aspnet/signalr@1 và chọn phiên bản mới nhất không phải bản preview.


  • Chọn Choose specific files, mở rộng thư mục dist/browser và chọn 2 file signalr.jssignalr.min.js.
  • Nhập Target Location là wwwroot/lib/signalr/ và click Install.
LibMan sẽ tạo thư mục wwwroot/lib/signalr và sao chép các file vào đó.

Tạo SignalR hub


Hub là 1 class phía máy chủ đóng vai trò như một đường ống (pipeline) để xử lý việc giao tiếp giữa client và server. 
  • Từ project, tạo thư mục Hubs.
  • Trong thư mục Hubs, tạo file ChatHub.cs với nội dung như sau: 
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);
        }
    }
}

Class ChatHub kế thừa class Hub. Hub là class quản lý các kết nối, nhóm và nhắn tin.

Phương thức SendMessage có thể được gọi từ bất kỳ client nào đã kết nối. Nó sẽ gửi tin nhắn nhận được đến tất cả client. Mã SignalR là bất đồng bộ để cung cấp khả năng mở rộng tối đa.


Cấu hình project sử dụng SignalR


Chúng ta cần cấu hình SignalR trong file Startup.cs trước khi sử dụng.  Thêm các đoạn mã được tô vàng phía dưới vào file 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();
        }
    }
}

Tạo mã phía client


Thay thế nội dung ở trang Pages/Index.cshtml bằng nội dung sau:
@page
<div class="container">
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-6">&nbsp;</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">&nbsp;</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>

Giải thích bước trên:
  1. Chúng ta vừa tạo ra textbox namemessage và button submit.
  2. Tạo thêm 1 danh sách <ul></ul> với id="messageList" để hiển thị nội dung tin nhắn nhận được từ hub
  3. Khai báo các tập tin script signalr.js và tập tin chat.js mà ta sẽ tạo ở bước dưới.
  • Tạo tập tin chat.js đặt trong thư mục wwwroot/js với nội dung sau:
"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

connection.on("ReceiveMessage", function (user, message) {
    var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    var encodedMsg = user + " says " + msg;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

connection.start().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();
});
Giải thích bước trên:
  1. Tạo và khởi động kết nối đến hub ChatHub.
  2. Thêm xử lý cho nút submit bằng cách gửi tin nhắn đến hub.
  3. Thêm vào đối tượng connection một trình xử lý nhận các tin nhắn từ hub và thêm chúng vào danh sách.

Chạy ứng dụng


Nhấn CTRL + F5 để chạy ứng dụng ở chế độ không debug.
Sau đó mở trang web từ 2 trình duyệt khác nhau và thử chat qua nhau. Nếu thành công thì thành quả sẽ như hình dưới đây.


Mọi thắc mắc bạn có thể comment phía dưới bài viết nhé. Chúc bạn thành công.


EmoticonEmoticon