• 一、在 ASP.NET Core 中使用 SignalR


    一、介绍

    SignalR 是一个用于实现实时网站的 Microsoft .NET 库。它使用多种技术来实现服务器与客户端间的双向通信,服务器可以随时将消息推送到连接的客户端。

    https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?tabs=visual-studio&view=aspnetcore-3.0

    二、新建Core MVC项目并安装

    三、添加 SignalR 客户端库

    在“解决方案资源管理器” 中,右键单击项目,然后选择“添加” >“客户端库” 

    在“添加客户端库” 对话框中,对于“提供程序” ,选择“unpkg” 。

    对于“库” ,输入 @aspnet/signalr@1,然后选择不是预览版的最新版本。

    选择“选择特定文件” ,展开“dist/browser” 文件夹,然后选择“signalr.js” 和“signalr.min.js” 。

    将“目标位置” 设置为 wwwroot/lib/signalr/ ,然后选择“安装” 。

     

     四、创建 SignalR 中心即操作中心。

    Hub 消息处理中心

    public class TestHub : Hub
    {
        public TestHub()
        {
        }
    
        public async Task SendMessage(string message, string name)
        {
            #region Client
            //this.Context.ConnectionId                 //每个连接一个connectionId  表示唯一客户端
            //this.Clients.Client().SendAsync();        //指定发送消息
            //this.Clients.Clients()        
            #endregion             //给多个client发消息
    
    
            #region Group
            //this.Clients.Group();                     //给某个组发消息
            //this.Clients.Groups()                     //给多个组发消息
            //this.Groups.AddToGroupAsync()             //将指定连接加入组
            //this.Groups.RemoveFromGroupAsync()        //将指定连接移除组 
            #endregion
    
            await Clients.All.SendAsync("onMsg", DateTime.Now, message);
        }
    
    
        //上下线消息  连接、断开事件
    
        //客户端连接上
        public override Task OnConnectedAsync()
        {
            return base.OnConnectedAsync();
        }
    
        //客户端断开
        public override Task OnDisconnectedAsync(Exception exception)
        {
            string connectionId = this.Context.ConnectionId;
            return base.OnDisconnectedAsync(exception);
        }
    }

    以上可以看到SignalR封装了很多常用方法(发送指定消息、群发...),我们可以很简单的使用达到目的

    创建 Hubs 文件夹 。

    在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :

     

    using Microsoft.AspNetCore.SignalR;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace Ban.Hubs
    {
        public class ChatHub:Hub 
        {
            /// <summary>
            /// /服务端方法 发送消息--发送给所有连接的客户端
            /// </summary>
            /// <param name="user"></param>
            /// <param name="message"></param>
            /// <returns></returns>
            public async Task SendMessage(string user,string message)
            {
                //ReceiveMessage 为客户端方法,让所有客户端调用这个方法
                await Clients.All.SendAsync("ReceiveMessage",user,message);
            }
    
            /// <summary>
            /// 客户端连接的时候调用
            /// </summary>
            /// <returns></returns>
            public override Task OnConnectedAsync()
            {
                Trace.WriteLine("客户端连接成功");
                return base.OnConnectedAsync();
            }//所有链接的客户端都会在这里
    
            /// <summary>
            /// 连接终止时调用。
            /// </summary>
            /// <returns></returns>
            public override Task OnDisconnectedAsync(Exception exception)
            {
                Trace.WriteLine("连接终止");
                return base.OnDisconnectedAsync(exception);
            }
           
        }
    }

    六、配置 SignalR

    必须配置 SignalR 服务器,以将 SignalR 请求传递到 SignalR。

    startupConfigureServices方法内部添加SignalR服务services.AddSignalR();Configure中配置具体的Hub(路由器、中转):

        app.UseSignalR(routes =>
        {
            routes.MapHub<TestHub>("/testHub");     //可以多个map
        });
        
        app.UseMvc();           //注意UseSignalR需要在UseMvc()之前

    这样SignalR服务器端就开发完成了,网页、Java、.Net客户端都可以连接的

    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 test.Hubs; //3、引用 处理客户端 - 服务器通信的高级管道
    namespace test
    {
        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();//1、添加服务
            }
            // 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("/Home/Error");
                }
                app.UseStaticFiles();
                app.UseCookiePolicy();
                app.UseSignalR(routes => //2、引用
                {
                    routes.MapHub<ChatHub>("/chatHub");
                });
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }

     七、添加 SignalR 客户端代码(创建index控制器和视图)

    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
    </head>
    <body>
        <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 type="text/javascript">
            "use strict";
            var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
            //在建立连接之前禁用发送按钮
            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();
            });
        </script>
    </body>
    </html>

    Controller中调用SignalR服务

    在构造函数注入IHubContext<>就可以直接使用了,非常方便:

       private readonly IHubContext<TestHub> _hubContext;
    
        public HomeController(IHubContext<TestHub> hubContext)
        {
            _hubContext = hubContext;
        }
        
        public async Task<IActionResult> Notify()
        {
            //拿不到当前Hub的clientId  线程是唯一的
            await _hubContext.Clients.All.SendAsync("onMsg", "from controller msg");
            return Ok();
        }

     

  • 相关阅读:
    JavaScript 正则表达式
    JavaScript类型转换
    JavaScript typeof
    JavaScriptBreak 语句 continue 语句
    JavaScript for循环 while循环
    JavaScript 条件语句
    JavaScript 事件
    JavaScript 作用域
    SP2010开发和VS2010专家"食谱"--第四章节—列表定义和内容类型(3)--使用对象模型创建自定义内容类型
    SP2010开发和VS2010专家"食谱"--第四章节—列表定义和内容类型(2)--拓展现有内容类型
  • 原文地址:https://www.cnblogs.com/fger/p/11576717.html
Copyright © 2020-2023  润新知