首页 > 其他分享 >.Net Core SignalR 初体验

.Net Core SignalR 初体验

时间:2022-12-02 22:58:01浏览次数:81  
标签:Core 初体验 Hub message Clients SignalR Task Net public

前言

  Asp.Net SignalR已经出来很久了,但是一直没有静下心来好好看看。昨天花了几个小时的时间看了下。首先借鉴了官方文档,如何搭建一个SignalR的Demo。

  参考文章:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs=visual-studio 

  SignalR地址:https://github.com/aspnet/SignalR

  所以为了快速搭建和体验.Net Core版本的SignalR,我选择了下载官方的Demo和参考官方给的教程。所以具体的搭建过程我就不再本文中写了。

体验效果

  官网给出的DEMO运行如下图:

   

  点击connect,查看一下network。可以发现,它在当前浏览器支持三种方式。

  

  而且和.NET Framework版本不同的是,新版SignalR中的Hub类型也是蛮丰富的。Demo中给出了 普通Hub,DynamicHub,Hub<T> 三种类型。我们去看看其中的区别吧。

  普通Hub

  查看定义,可以看到普通Hub中的Clients类型是 IHubCallerClients 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 namespace Microsoft.AspNetCore.SignalR {     //     // 摘要:     //     A base class for a SignalR hub.     public abstract class Hub : IDisposable     {         protected Hub();           //         // 摘要:         //     Gets or sets an object that can be used to invoke methods on the clients connected         //     to this hub.         public IHubCallerClients Clients { getset; }         //         // 摘要:         //     Gets or sets the hub caller context.         public HubCallerContext Context { getset; }         //         // 摘要:         //     Gets or sets the group manager.         public IGroupManager Groups { getset; }           //         public void Dispose();         //         // 摘要:         //     Called when a new connection is established with the hub.         //         // 返回结果:         //     A System.Threading.Tasks.Task that represents the asynchronous connect.         public virtual Task OnConnectedAsync();         //         // 摘要:         //     Called when a connection with the hub is terminated.         //         // 返回结果:         //     A System.Threading.Tasks.Task that represents the asynchronous disconnect.         public virtual Task OnDisconnectedAsync(Exception exception);         //         // 摘要:         //     Releases all resources currently used by this Microsoft.AspNetCore.SignalR.Hub         //     instance.         //         // 参数:         //   disposing:         //     true if this method is being invoked by the Microsoft.AspNetCore.SignalR.Hub.Dispose         //     method, otherwise false.         protected virtual void Dispose(bool disposing);     } }

  IHubCallerClients 定义如下:

1 2 3 public interface IHubCallerClients : IHubCallerClients<IClientProxy>, IHubClients<IClientProxy>   {   }

  而框架又给IClientProxy增加了扩展方法:SendAsync

  所以在普通Hub中,定义客户端方法的时候,需要把方法名当作参数传入SendAsync方法中。例如如下代码:

1 2 3 4 public Task Send(string message)        {            return Clients.All.SendAsync("Receive", $"{Context.ConnectionId}: {message}");        }

  DynamicHub

  DynamicHub我是比较喜欢的,因为他和 Framework版的是一样(或者说看起来是一样的)的。动态Hub我们就可以不必拘泥于只能调用SendAsync方法了。例如:

1 2 3 4 public Task SendToOthers(string message)       {           return Clients.Others.ThisIsMyReceiveMethod($"{Context.ConnectionId}: {message}");       }

  DynamicHub的Clients类型为:DynamicHubClients ,它的内部变量全都是dynamic类型的。

  

  Hub<T>

  泛型Hub就把规约交给开发者制定。在Demo中 Hub<IChatClient> 中的IChatClient接口定义了Receive方法,因此Clients中的对象可以调用Receive方法。同理,我们可以根据业务需要定义自己的方法。至少从代码上看会显得更加通俗易懂一些。比如:

1 2 3 4 5 public interface IChatClient    {        Task Receive(string message);        Task LoginSuccess(long userId);    }
1 2 3 4 public Task Login(long userId)    {        return Clients.Caller.LoginSuccess(userId);    }

  其实从代码上来看的话,他们都是Hub,只不过是不同的扩展实现而已。而泛型Hub不过是用户自定义泛型接口,而默认Hub中的默认泛型接口为:IClientProxy.所以看到这里,如果我就想使用原生的Hub而又想自定义方法怎么办呢?很简单,加扩展就可以了。

  为什么自己加就可以呢,其实 SendAsync 就是扩展方法,它内部也是调用了SendCoreAsync方法。于是乎,写下自己的扩展方法,那这样子就很灵活了。我们把method参数去掉,直接写死试试:

1 2 3 4 public static Task LoginAsync(this IClientProxy clientProxy, string message, CancellationToken cancellationToken = default(CancellationToken))       {           return clientProxy.SendCoreAsync("LoginSuccess"new object[] { message}, cancellationToken);       }

  其实说白了,这个扩展方法还是需要传入method参数的,只不过封装了一层(似乎感觉这么做有意义吗?哈哈,还是老老实实用泛型吧),那么我们在去看Hub中的方法,修改Send方法如下:

1 2 3 4 public Task Send(string message)       {           return Clients.All.LoginAsync($"{Context.ConnectionId}: {message}");       }

  是不是这样子就实现了自己自定义方法了呢?个人觉得这么写还绕了一圈,不如用泛型或者Dynamic了。

  运行一下,看看效果:

  

  其实我也是抱着试试的态度,没想到还真是这样,和新方法就是SendCoreAsync,而其他方法只不过是上层封装使得代码更加通俗易懂。

使用Redis

  Demo中的其他例子就不再演示了。广播,一对一,一对多,加入组,退出组等基本和之前一样。这里在演示一下使用Redis做不同实例之间的通信效果。

  首先程序集是不能少的:Microsoft.AspNetCore.SignalR.Redis,然后在Startup中补充代码:

  

  打开Redis客户端,使用MONITOR命令监听一下,从程序启动,到连接,在发送一条广播消息:hello redis。  redis 监听结果如下:

  

  所以,PUB/SUB还是立了大功呢。

  这里用CMD运行了两个实例,端口分别为 8881,8882来模拟两个站点。

  

  演示效果如下:

 

   没问题的哦,其实仔细想想,虽然运行了两个网站实例,但是连接信息都保存在同一个Redis上,那肯定通信是木的问题的啦。

总结

  只是简单的运行了一下DEMO,大致了解了一下 .Net Core SignalR的表层,至少跑Demo是跑起来了,并且使用Redis也是没有问题的。不过好像会出现运行一旦时间,程序自动停掉的问题,不知道是不是我电脑的问题。。今天就到这里吧,希望大家能有所收获。 本文代码地址:https://github.com/fanpan26/LayIM.AspNetCore/tree/master/src/LayIM.AspNetCore.Demo/SignalRSamples

 

 

标签:Core,初体验,Hub,message,Clients,SignalR,Task,Net,public
From: https://www.cnblogs.com/webenh/p/16945901.html

相关文章

  • ASP.NET Core SignalR .NET 客户端
    项目2022/11/2913个参与者反馈通过ASP.NETCoreSignalR.NET客户端库可以从.NET应用与SignalR中心进行通信。查看或下载示例代码(如何下载)本文......
  • .Net中的DataTime类型 和 time_t类型转换
    今天碰到一个问题:数据库表中一个记录时间的FIELD是用time_t类型,也就是long类型存储的,需要转换为yyyy-MM-ddHH:mm:ss格式显示到界面上。当初用time_t类型大概是为了提高存取......
  • ASP.NET 向SQLSERVER中批量插入数据
    usingSystem.Data;usingSystem.Diagnostics;usingSystem.Data.SqlClient;stringconnectionString="DataSource=HG-J3EJJ9LSW5PY;InitialCatalog=Test......
  • 《Netty权威指南》之I/O基础入门
    I/O基础入门:​​1.Java的I/O演进​​​​2.NIO入门​​​​2.1BIO通信模型(同步阻塞式I/O)​​​​2.2伪异步I/O编程​​1.Java的I/O演进从JDK1.0到JDK1.3,Java的I/O类......
  • C#中数据的批量插入和更新_Asp.net
    对于海量数据的插入和更新,ADO.NET确实不如JDBC做到好,JDBC有统一的模型来进行批操作.使用起来非常方便: PreparedStatementps=conn.prepareStatement("insertorupd......
  • .NET Socket开发之异步Socket
    在基于.NET的网络服务端的开发中,我们用到和听到的最多的恐怕就是异步Socket了。异步Socket的性能比同步高出很多,但是编写代码比较复杂。因此异步Socket也是网络上讨论比......
  • 使用.NET7和C#11打造最快的序列化程序-以MemoryPack为例
    使用.NET7和C#11打造最快的序列化程序-以MemoryPack为例 译者注本文是一篇不可多得的好文,MemoryPack的作者neuecc大佬通过本文解释了他是如何将序列化程序性能提......
  • ASP.NET中如何调用存储过程
     用ASP.NET与SQLSERVER可是缘份最好了,稍大的程序一般第一先考虑的是SQLSERVER,只是一些很考虑经济的才使用ACCESS等了。用SQLSERVER,为了使数据库的效率更好,一般都会才取......
  • ConfigMap/Secret:怎样配置、定制应用(chrono《kubernetes入门实战课》笔记整理)
     【概念说明】Kubernetes里专门用来管理配置信息的两种对象:ConfigMap和Secret,使用它们来灵活地配置、定制我们的应用。配置根据数据安全划分,分为两种:明文配置:不加密......
  • ASP.NET Web API的Controller是如何被创建的?
    WebAPI调用请求的目标是定义在某个HttpController类型中的某个Action方法,所以消息处理管道最终需要激活目标HttpController对象。调用请求的URI会携带目标HttpController的......