钱行慕

导航

ASP.NET Core SignalR (三):教程

此为系列文章,对MSDN ASP.NET Core SignalR 的官方文档进行系统学习与翻译。其中或许会添加本人对 ASP.NET Core 的浅显理解。

本教程会教你使用SignalR建立实时app的一些基础知识。你将会学到如何:

  • 创建一个Web项目
  • 添加SignalR 客户端库
  • 创建一个SignalR 中心
  • 配置项目以使用SignalR
  • 添加从任何客户端向所有已连接的客户端发送消息的代码

      最终,你将得到一个工作聊天app:

                  

准备条件

创建一个Web app 工程

  • 在菜单栏,选择 文件 > 新建工程
  • 在 创建新工程 对话框 中,选择 ASP.NET Core Web app,然后选择 下一步
  • 在 配置你的新工称 对话框 中,将工程命名为SignalRChat,然后选择 新建
  • 在 创建新的 ASP.NET Core Web程序对话框中,选择 .NET Core 以及  ASP.NET Core 3.0
  • 选择 Web 应用程序 以创建使用Razor 页的项目,然后 选择 创建

添加SignalR 客户端库

       SignalR 服务端库已经包含在 ASP.NET Core 3.0 共享框架中。而Javascript 客户端库不会自动包含在客户端库中。对于本教程来说,你将使用 库管理器(LibMan)来从unpkg 获取客户端库。unpkg 是一个CDN,其可以传送在 npm(Node Pakage Manager)中找到的任何东西。

  • 在解决方案资源管理器中,右键项目,选择 添加 > 客户端库
  • 在添加客户端库 对话框 中,对于 提供者 选择 unpkg
  • 对于类库,输入 @microsoft/signalr@latest
  • 选择 选择特定的文件,展开  dist/browser 文件夹,选择signalr.js and signalr.min.js
  • 将目标路径设置为 wwwroot/js/signalr/ ,选择  安装

 

        LibMan 会创建一个wwwroot/js/signalr 文件夹,并将复制的文件拷贝给它。

创建一个 SignalR 中心

       中心 是一个被用作高级管道的类,其处理客户端与服务端的通信。

  • 在SignalRChat 工程文件夹下,创建一个 Hubs 文件夹
  • 在 Hubs 文件夹下,使用如下代码创建一个 ChatHub.cs 文件
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);
        }
    }
}

        ChatHub 类继承了 SignalR Hub 类。Hub 类管理着 连接,分组,以及消息。

        SendMessage 方法可以被一个已连接的客户端调用来向所有的客户端发送消息。调用这个方法的Javascript 客户端代码在本教程的后续会有所介绍。SignalR 代码是异步的 以提供最佳的可伸缩性。

配置 SignalR

       SignalR 服务必须要进行配置来给Signal 传递 SignalR 请求。

  • 在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");
            });
        }
    }
}

        这些变化将SignalR添加到 ASP.NET Core DI 以及 路由系统中。

添加SignalR客户端代码

       使用如下的代码来替换 Pages\Index.cshtml  中的内容:

@page
    <div class="container">
        <div class="row">&nbsp;</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">&nbsp;</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>

         上述代码:

  • 创建了 name文本框,message 文本框,以及一个提交按钮。
  • 创建了一个 id 为 messagesList 的列表,用来显示从SignalR 中心接受到的消息。
  • 包含引用了 SignalR 的脚本,并包含了 你将在下一节创建的 chat.js  应用程序代码。

        在wwwroot/js 文件夹下,使用如下代码创建一个 chat.js 文件。

"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, "&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().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();
});

        上述代码:

  •  创建并开启了一个连接。
  • 向提交按钮添加了一个处理器,其可以向 SignalR中心发送消息。
  • 向连接对象添加了一个处理器,其可以从 中心接收 消息 并将它们追加到列表中。

运行app

  • 运行App
  • 从地址栏中复制URL,打开另一个浏览器实例或者标签页,将URL粘贴到地址栏。
  • 选择任意一个浏览器,输入 name 和 message,点击 发送。
  • name 和 message 会立即显示在两个 浏览器上。

       提示:

       如果app 没有正常工作,打开你的浏览器开发工具(F12),找到控制台。你或许会看到与你的HTML 和 Javascript代码相关的异常。举个例子,假设你将signalr.js 文件放到与指导文档不同的文件夹,这种情况下,该文件的引用便不会工作,而你将看到一个 404。

      如果你在Chrome中得到了一个错误:ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY,运行如下命令来更新你的开发凭证:

     

dotnet dev-certs https --clean
dotnet dev-certs https --trust

 

posted on 2020-03-18 14:25  钱行慕  阅读(1170)  评论(0编辑  收藏  举报