经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
关于.net core 中的signalR组件的使用
来源:cnblogs  作者:村长lv  时间:2019/10/8 9:35:20  对本文有异议

SignalR是为了提供更方便的web交互响应式到推送式的解决方案。有了它之后可以实现客户端直接调用服务端的方法并且获得返回值 (客户端可以是各种平台,目前SignalR支持的语言版本有C#、java、javaScript、nodejs等),服务端也是可以调用客户端的方法,通过这样的方式实现了由原来的单通变成双通的目的。

在SignalR中有个非常重要的概念就是Hub,这个Hub如果拿到以前的MVC架构中所对应的就是控制器,他们的区别就是我们需要自己去注册这个Hub的路由,而控制器是可以基于约定的。

首先创建一个Hub

  1. public class NewsPushHub:Hub
  2. {
  3.  
  4. }

  这是一个新闻推送的Hub,它必须要继承至Hub这个基类,Hub这个基类还可以接收一个泛型的实现,这个泛型可以用来规范客户端的方法

  1. public class NewsPushHub : Hub<IClientFuncs>
  2. {
  3. /// <summary>
  4. /// 可以被客户端调用的方法
  5. /// </summary>
  6. /// <param name="msg"></param>
  7. /// <returns></returns>
  8. public async Task DepartmentNotice(string msg)
  9. {
  10. //这里发送只能是接口中约束的方法
  11. await Clients.All.SendMsg( msg);
  12. }
  13. }
  14. /// <summary>
  15. /// 定义客户端所监听的方法名称
  16. /// </summary>
  17. public interface IClientFuncs
  18. {
  19. Task SendMsg(string msg);
  20. }

  

  1. 这里面写的两个方法是可以被客户端直接调用的,但是在被调用之前首先要注册,在Core3.0之前 我们是用app.UseSignalR(hub=>hub.MapHub<NewsPushHub>("/SignalRNews"))来注册SignalR的访问路由,现在改成全部统一在app.UseEndpoints()这个扩展方法中去注册,现在在Startup类的代码就像这样了
 
  1. public class Startup
  2. {
  3. public void ConfigureServices(IServiceCollection services)
  4. {
  5. services.AddControllersWithViews();
  6. services.AddSignalR();
  7. }
  8. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  9. {
  10. if (env.IsDevelopment())
  11. {
  12. app.UseDeveloperExceptionPage();
  13. }
  14.  
  15. app.UseRouting();
  16. app.UseEndpoints(endpoints =>
  17. {
  18. endpoints.MapHub<NewsPushHub>("/SignalRNews");
  19. endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
  20. });
  21. }

  在这个里面我配置了包含MVC的中间件和依赖注入,在3.0中MVC的中间件和依赖注入都变了  变得更加具体,路由设置也变得统一在UseEndpoints()这个方法里面,它里面的委托是一个IEndpointRouteBuilder的参数,我们通过这个参数可以映射各种路由配置,有非常多的map,在这里配置MVC的目的是为了和SignalR交互的。下面是客户端的js代码首先需要安装aspnet-signalr

  1. //创建一个匹配 http:localhost:5000/SignalRNews路由的连接
  2. const connection = new signalR.HubConnectionBuilder()
  3. .withUrl("/SignalRNews")
  4. .configureLogging(signalR.LogLevel.Information)
  5. .build();
  6. // 开始连接,这个时候会发送一个101状态为pending的连接
  7. connection.start().then(function () {
  8. console.log("connected");
  9. });
  10. // 监听服务端调用的客户端方法
  11. connection.on("sendMsg", (msg) => {
  12. $(".dispaly-message").append(`<p>${msg}</p>`);
  13. });
  14.  
  15. $("#submit").click(e => {
  16. const msg = $("#msg").val();
  17. // 调用服务端的DepartmentNotice方法
  18. connection.invoke("DepartmentNotice", msg).then(() => {
  19. console.log("消息发送完成");
  20. });
  21. })

  

 

 

 

 上面是最终的结果 可以看出实现了不同客户端之间的消息互通  

其实Signalr还可以有依赖注入的用法例如在控制器里面注入 然后直接在MVC中随意推送消息

 

  1. public class HomeController:Controller
  2. {
  3. private readonly IHubContext<NewsPushHub> _hub;
  4.  
  5. public HomeController(IHubContext<NewsPushHub> hub)
  6. {
  7. this._hub = hub;
  8. }
  9. public IActionResult Index()
  10. {
  11. _hub.Clients.All.SendAsync("Temp", "test");
  12. return View();
  13. }
  14. }

  从上面代码中看的出在Home控制器中注入了NewsPushHub这个Hub 只要有一个客户端访问Index界面就会通知所有的客户端

总结:SignalR把原来复杂低效率的双通编程变得简单,Siganlr只要是支持3中模式进行客户端和服务端的连接(1、长轮询模式  2、服务器发送事件  3、websocket)最高效的当然是websocket 但是某一些浏览器是不支持的;

以上代码的demo地址

原文链接:http://www.cnblogs.com/lvshunbin/p/11622758.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号