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相关推荐

  1. 从新手到高手c++全方位学习 pdf + 视频教程 共18章

    淘宝已经和谐了这个网站,原网址:https://item.taobao.com/item.htm?spm=a1z09.8149145.0.0.mb00D0&id=17350311256& ...

  2. 《我和PIC单片机:基于PIC18》——第1章 初识PIC 1.1 与众不同的PIC

    第1章 初识PIC 我们可以把单片机简单地理解成单芯片计算机.经过多年的发展,单片机的内涵被不断丰富,越来越多的功能被赋予给了这个单芯片计算机,使得其功能变得愈发强大.可以说,在单片机的江湖中,家族林 ...

  3. 第9章 初识STM32固件库—零死角玩转STM32-F429系列

    第9章     初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  4. Camel实战第二版 第一章 初识Camel

    目录 第一部分:迈出第一步 第一章:初识Camel 第二章:Camel路由 本章包含: Camel介绍 Camel的主要功能 初次使用Camel Camel的架构与概念 从零开始构建一个复杂的系统代价 ...

  5. 第一章 初识NANO板卡

    第一章 初识NANO板卡 一. 英伟达Jetson Nano 是什么 二. 为什么要用NVIDIA DIGITS 三. 我们可以在Jetson Nano上运行什么样的算法? 四.英伟达 NANO板卡配 ...

  6. 尚学堂百战程序员1573题---答案总结第一章 初识Java

    第一章 初识Java 1. 你学习编程的目的是什么?学习编程最快的办法是什么? 答:我觉得的我喜欢计算机,我认为计算机是一个很神奇的东西,所以我要学计算机专业,同时,我认为学计算机学编程是一个比较容易 ...

  7. 第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. ...

  8. 第18章 类加载机制与反射

    第18章 类加载机制与反射 18.1 类的加载.连接和初始化 18.1.1 JVM和类 18.1.2 类的加载 18.1.3 类的连接 18.1.4 类的初始化 18.1.5 类初始化的时机 18.2 ...

  9. Spring - Java/J2EE Application Framework 应用框架 第 18 章 使用Quartz或Timer完成时序调度工作

    第 18 章 使用Quartz或Timer完成时序调度工作 18.1. 简介 Spring提供了支持时序调度(译者注:Scheduling,下同)的整合类.现在, Spring支持内置于1.3版本以来 ...

最新文章

  1. 数据库中的字段varchar类型和char类型的区别?
  2. python设计模式-观察者
  3. ML之FE:对pandas的dataframe中的类别型字段进行数字编码化(类别型特征数值化)并导出映射表daiding
  4. python数据清洗实例_python 数据的清理行为实例详解
  5. java让服务器停止运行,java调用远程服务器的shell脚本以及停止的方法实现
  6. CentOS查看分区的方式
  7. RTT学习笔记3-时钟定时器管理
  8. 怎么用U盘重装系统?
  9. INSERT INTO SELECT语句概述和示例
  10. Python多重继承(一分钟读懂)
  11. 基于JSP的题库试卷管理系统免费下载
  12. CH340串口驱动(包含各系统平台)
  13. 委外订单--采购入库单不能记账
  14. 负载均衡实现的各种优缺点
  15. 大学不会教,但是程序员第一天工作需要知道的事儿...
  16. vue 计数器_vuex实现简易计数器
  17. “三体”域名纠纷案受关注,企业应如何做好域名品牌保护?
  18. 培训班出身的同学简历怎么做?面试要注意哪些?来自资深大厂HR的忠告
  19. 费马小定理、威尔逊定理
  20. 1688API接口(item_get-获得1688商品详情)

热门文章

  1. 正在被世界淘汰的九种人!!!
  2. 平安入选人工智能“国家队” 金融壹账通将搭建三层开放平台
  3. 【原创】锡林格勒木兰围场乌兰布统大草原
  4. 采用WTL及LibXML2进行传真软件的开发
  5. iperf(网络性能测试)
  6. vue关闭页面时停止计数器
  7. 快手全民特效大赛与王者荣耀双IP联合,200+优质魔表作品助力项目实现超34亿曝光
  8. python——paramiko详解
  9. HTTP协议请求错误总结
  10. 蓝桥杯-历届试题 分巧克力