第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)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; namespace SignalR.通讯 { public class iHub : iHubBase { public override Task OnConnected() { // 查询用户 var user = 自我意识.你们.SingleOrDefault(u => u.ContextId == Context.ConnectionId); if (user != null) return base.OnConnected(); user = new 线程(Context.ConnectionId); user.目的 += User_目的事件; 自我意识.你们.Add(user); Clients.Client(Context.ConnectionId).addMessage("请输入用户姓名 ", Context.ConnectionId); return base.OnConnected(); } private void User_目的事件(object sender, 目的事件参数 e) { var user = (线程)sender; if (e.类型 == 目的事件类型.说话) { if (user != null) { Clients.Client(user.ContextId).addMessage("电脑说:" + e.参一+ e.参二, user.ContextId); } } else if (e.类型 == 目的事件类型.学习 || e.类型 == 目的事件类型.认知) { Clients.Client(user.ContextId).doclass(e.参一, e.参二); } else if (e.类型 == 目的事件类型.意识) { Clients.Client(user.ContextId).addIdea(e.参一, e.参二); } } /// <summary> /// 获取用户名和自己的唯一编码 /// </summary> public void GetName(string 姓名) { // 查询用户。 var user = 自我意识.你们.SingleOrDefault(u => u.ContextId == Context.ConnectionId); if (user != null) { user.姓名 = 姓名; Clients.Client(Context.ConnectionId).showNameAndId(user.姓名, Context.ConnectionId); //读取用户个性数据 } GetOnlineUserList(); } public override Task OnReconnected() { // 查询用户 var user = 自我意识.你们.SingleOrDefault(u => u.ContextId == Context.ConnectionId); if (user != null) return base.OnReconnected(); user = new 线程(Context.ConnectionId); user.目的 += User_目的事件; 自我意识.你们.Add(user); //自动重新登陆 Clients.Client(Context.ConnectionId).addMessage("重新连接。。。 ", Context.ConnectionId); GetOnlineUserList(); return base.OnReconnected(); } /// <summary> /// 重写断开连接事件 /// 用户断开连接后,需要移除在线人们 /// </summary> /// <param name="stopCalled"></param> /// <returns></returns> public override Task OnDisconnected(bool stopCalled) { var user = 自我意识.你们.FirstOrDefault(u => u.ContextId == Context.ConnectionId); //判断用户是否存在,存在则删除 if (user != null) { 自我意识.你们.Remove(user); } //更新所有用户的列表 GetOnlineUserList(); return base.OnDisconnected(stopCalled); } /// <summary> /// 获取所有在线用户 /// </summary> public void GetOnlineUserList() { // var item = from a in 自我意识.人们 select new { a.印象.姓名, a.ContextId }; //var jsondata = JsonConvert.SerializeObject(item.ToList()); // Clients.All.getOnlineUserlist(jsondata);// 调用客户端的getOnlineUserlist来获得在线人们 } /// <summary> /// 发送消息 /// </summary> /// <param name="contextId">发送给用户的ContextId</param> /// <param name="message">发送的消息内容</param> public void SendMessage(string contextId, string message) { 线程 你 = 自我意识.你们.FirstOrDefault(u => u.ContextId == Context.ConnectionId); /* // 判断用户是否存在,存在则发送 if (user != null) { // 1V1 聊天,需要把消息往这2个客户端发送 // 给指定用户发送,把自己的ID传过去 // Clients.Client(contextId).addMessage(message + " " + DateTime.Now, Context.ConnectionId); // 给自己发送,把用户的ID传给自己 Clients.Client(Context.ConnectionId).addMessage(message + " " + DateTime.Now, contextId); } else { // Clients.Client(Context.ConnectionId).showMessage("该用户已离线"); } */ if (你 == null) { //重新连接 } if (你.姓名.Equals(string.Empty)) { GetName(message); Clients.Client(Context.ConnectionId).addMessage("用户" + 你.姓名 + "你好", contextId); } else { Clients.Client(Context.ConnectionId).addMessage(你.姓名 + ":" + message + " " + DateTime.Now, contextId); //开始正式聊天 你.输入(message); } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值