第18章 初识SignalR
1 注意:
在.Net6框架中不必在通过Nuget引用“Microsoft.AspNetCore.SignalR”包,来把SignalR中间件集成到
.Net6框架中了,因为“Microsoft.AspNetCore.SignalR”包已经被弃用,且.Net6框架已经内置集成了SignalR中间件。
2 重构Program.cs
//把内置中间件“SignalR”的实例,依赖注入到.Net(Core)6框架内置容器中。
builder.Services.AddSignalR();
//通过AddRazorRuntimeCompilation依赖注入中间件实现页面修改热加载(Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation)。
builder.Services
.AddControllersWithViews()
.AddRazorRuntimeCompilation();
//为内置中间件“SignalR”配置指定的节点("/chatHub"=Linkage.Hubs.ChatHub=“Controllers”)路由,并集成到.Net(Core)6框架内置管道中。
//注意:由于需要使用JavaScript获取路由数据,所以"/chatHub"中的第1个字母必须小写。
app.MapHub<ChatHub>("/chatHub");
app.Run();
3 SignalR示例:
3.1 SignalRModel
using System.ComponentModel.DataAnnotations;
namespace Linkage.Models
{
/// <summary>
/// 【SignalR模型--纪录】
/// </summary>
/// <remarks>
/// 摘要:
/// 为通过SignalR中间件实现信息交互,提供数据支撑。
/// </remarks>
public record SignalRModel
{
/// <summary>
/// 【用户名】
/// <remarks>
/// </summary>
/// 摘要:
/// 获取/设置发送信息的1个指定用户名。
/// </remarks>
[Display(Name = "用户名")]
public string UserName { get; set; }
/// <summary>
/// 【信息】
/// <remarks>
/// </summary>
/// 摘要:
/// 获取/设置1个指定用户名所发送的1条指定信息。
/// </remarks>
[Display(Name = "发送信息")]
public string Message { get; set; }
}
}
3.2 ChatHub
using Linkage.Models;
using Microsoft.AspNetCore.SignalR;
namespace Linkage.Hubs
{
/// <summary>
/// 【聊天中心】
/// </summary>
/// <remarks>
/// 摘要:
/// 该类通过内置中间件“SignalR”的实例,指定客户的条聊天信息的数据发送到客户端,为页面渲染显示提供数据支撑,
/// </remarks>
public class ChatHub : Hub
{
#region 方法
/// <summary>
/// 【向所有客户端发送系统信息】
/// <remarks>
/// 摘要:
/// 把系统信息的数据发送到客户端,为页面渲染显示提供数据支撑,
/// </remarks>
/// </summary>
public Task AllClientResponse()
{
SignalRModel data = new SignalRModel { UserName = "系统", Message = "正在与服务器链接中..." };
return Clients.All.SendAsync("ReceiveMessage", data);
}
/// <param name="signalRModel">SignalR模型纪录的1个指定实例。</param>
/// <summary>
/// 【向所有客户端发送聊天信息】
/// <remarks>
/// 摘要:
/// 把1个指定客户的1条聊天信息的数据发送到客户端,为页面渲染显示提供数据支撑,
/// </remarks>
/// </summary>
public async Task SendMessage(SignalRModel signalRModel)
{
await Clients.All.SendAsync("ReceiveMessage", signalRModel);
}
#endregion
}
}
3.3SignalRTest\Index.cshtml
@model Linkage.Models.SignalRModel
@{
ViewData["Title"] = "初识SignalR";
}
<div class="row">
<div class="col-md-4">
<form id="SignalRForm">
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Message" class="control-label"></label>
<input asp-for="Message" class="form-control" />
</div>
<div class="form-group mt-3">
<button type="button" id="sendButton" class="btn btn-primary">发 送</button>
</div>
</form>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<h1 id="conntecionState" class="text-center text-danger"></h1>
<hr />
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<ul id="messagesList" class="nav flex-column"></ul>
</div>
</div>
@section Scripts {
<!--引用SignalR中间件的JavaScript库。-->
<script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script>
$(document).ready(function () {
SignalRInstance();
});
//初始化SignalR中间件。
function SignalRInstance()
{
// 初始化路由:通过SignalR中间件的JavaScript包获取指定节点的路由:"/chatHub"=Linkage.Hubs.ChatHub。
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//显示系统连接成功信息(有Bug)。
connection.start().then(() => {
connection.invoke("AllClientResponse");
connection.on("ReceiveMessage", function (data) {
if (data.userName == "系统")
$("#conntecionState").append("<strong>" + ` ${data.message}` + "</strong>");
})
});
//服务器回调方法,相当于Ajax中的: success: function (data)
connection.on("ReceiveMessage", function (data) {
if (data.userName == 1) {
// 向页面添加消息
$("#messagesList").append("<li class='nav-item bg-danger mb-2'><strong>" + `用户${data.userName}: ${data.message}` + "</strong></li>");
}
else if (data.userName == 2) {
// 向页面添加消息
$("#messagesList").append("<li class='nav-item bg-success mb-2'><strong>" + `用户${data.userName}: ${data.message}` + "</strong></li>");
}
else if (data.userName != "系统") {
// 向页面添加消息
$("#messagesList").append("<li class='nav-item bg-warning mb-2'><strong>" + `用户${data.userName}: ${data.message}` + "</strong></li>");
}
})
//指定节点的路由:"/chatHub"=Linkage.Hubs.ChatHub,通过SignalR中间件,把信息在页面上进行渲染显示。
connection.start();
//单击事件,最好定义在“ SignalRInstance()”方法之外。
$("#sendButton").click(function () {
//注意:SignalR中间件的JavaScript包获不支持:$("#SignalRForm").serialize();
connection.invoke("SendMessage", { UserName: $("#UserName").val(), Message: $("#Message").val() });
// 清空输入框信息并获取焦点。
$("#Message").val("").focus();
});
}
</script>
}
4 参考:
1、“ASP.NET Core SignalR 入门 | Microsoft Learn”。
2、“【SignalR全套系列】之在.Net6中实SignalR通信 (qq.com)”。
3、“SignalR系列文章02---netCoreMvc创建Demo - 爱生活,爱代码 - 博客园 (cnblogs.com)”。
对以上功能更为具体实现和注释见:221029_18Linkage(初识SignalR)。
第18章 初识SignalR相关推荐
- 从新手到高手c++全方位学习 pdf + 视频教程 共18章
淘宝已经和谐了这个网站,原网址:https://item.taobao.com/item.htm?spm=a1z09.8149145.0.0.mb00D0&id=17350311256& ...
- 《我和PIC单片机:基于PIC18》——第1章 初识PIC 1.1 与众不同的PIC
第1章 初识PIC 我们可以把单片机简单地理解成单芯片计算机.经过多年的发展,单片机的内涵被不断丰富,越来越多的功能被赋予给了这个单芯片计算机,使得其功能变得愈发强大.可以说,在单片机的江湖中,家族林 ...
- 第9章 初识STM32固件库—零死角玩转STM32-F429系列
第9章 初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...
- Camel实战第二版 第一章 初识Camel
目录 第一部分:迈出第一步 第一章:初识Camel 第二章:Camel路由 本章包含: Camel介绍 Camel的主要功能 初次使用Camel Camel的架构与概念 从零开始构建一个复杂的系统代价 ...
- 第一章 初识NANO板卡
第一章 初识NANO板卡 一. 英伟达Jetson Nano 是什么 二. 为什么要用NVIDIA DIGITS 三. 我们可以在Jetson Nano上运行什么样的算法? 四.英伟达 NANO板卡配 ...
- 尚学堂百战程序员1573题---答案总结第一章 初识Java
第一章 初识Java 1. 你学习编程的目的是什么?学习编程最快的办法是什么? 答:我觉得的我喜欢计算机,我认为计算机是一个很神奇的东西,所以我要学计算机专业,同时,我认为学计算机学编程是一个比较容易 ...
- 第18章:MYSQL分区
第18章:分区 目录 18.1. MySQL中的分区概述18.2. 分区类型 18.2.1. RANGE分区18.2.2. LIST分区18.2.3. HASH分区18.2.4. KEY分区18.2. ...
- 第18章 类加载机制与反射
第18章 类加载机制与反射 18.1 类的加载.连接和初始化 18.1.1 JVM和类 18.1.2 类的加载 18.1.3 类的连接 18.1.4 类的初始化 18.1.5 类初始化的时机 18.2 ...
- Spring - Java/J2EE Application Framework 应用框架 第 18 章 使用Quartz或Timer完成时序调度工作
第 18 章 使用Quartz或Timer完成时序调度工作 18.1. 简介 Spring提供了支持时序调度(译者注:Scheduling,下同)的整合类.现在, Spring支持内置于1.3版本以来 ...
最新文章
- 数据库中的字段varchar类型和char类型的区别?
- python设计模式-观察者
- ML之FE:对pandas的dataframe中的类别型字段进行数字编码化(类别型特征数值化)并导出映射表daiding
- python数据清洗实例_python 数据的清理行为实例详解
- java让服务器停止运行,java调用远程服务器的shell脚本以及停止的方法实现
- CentOS查看分区的方式
- RTT学习笔记3-时钟定时器管理
- 怎么用U盘重装系统?
- INSERT INTO SELECT语句概述和示例
- Python多重继承(一分钟读懂)
- 基于JSP的题库试卷管理系统免费下载
- CH340串口驱动(包含各系统平台)
- 委外订单--采购入库单不能记账
- 负载均衡实现的各种优缺点
- 大学不会教,但是程序员第一天工作需要知道的事儿...
- vue 计数器_vuex实现简易计数器
- “三体”域名纠纷案受关注,企业应如何做好域名品牌保护?
- 培训班出身的同学简历怎么做?面试要注意哪些?来自资深大厂HR的忠告
- 费马小定理、威尔逊定理
- 1688API接口(item_get-获得1688商品详情)