前言

  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 

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 { get; set; }
//
// 摘要:
// Gets or sets the hub caller context.
public HubCallerContext Context { get; set; }
//
// 摘要:
// Gets or sets the group manager.
public IGroupManager Groups { get; set; } //
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 定义如下:

  public interface IHubCallerClients : IHubCallerClients<IClientProxy>, IHubClients<IClientProxy>
{
}

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

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

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

  DynamicHub

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

  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方法。同理,我们可以根据业务需要定义自己的方法。至少从代码上看会显得更加通俗易懂一些。比如:

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

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

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

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

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

  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

 

.Net Core SignalR 初体验的更多相关文章

  1. SignalR初体验

    简介 ASP .NET SignalR[1]  是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以 ...

  2. Consul在.Net Core中初体验

    Consul在.Net Core中初体验 简介 在阅读本文前我想您应该对微服务架构有一个基本的或者模糊的了解 Consul是一个服务管理软件,它其实有很多组件,包括服务发现配置共享键值对存储等 本文主 ...

  3. SignalR 初体验

    目录 一.前言 二.服务端 2.1.站点服务端 2.2.宿主服务或客户端 2.3.持久连接和集线器 三.客户端 3.1.使用代理客户端 3.2.不使用代理客户端 一.前言 微软官方给的说明:ASP.N ...

  4. asp net core 跨平台初体验

    标: 在 ubuntu 16.04 上部署一个 asp.net core 站点,打开网站后显示一段文字.   安装 net core 运行环境:ubuntu 16.04 LTS 1.添加 apt 源 ...

  5. vscode 创建.net core项目初体验

    微软的virtual studio编辑器那是宇宙第一大编辑器,可惜就是太笨重,遇到性能差一些的电脑设备,简直无法快速的编辑项目. 而vs code编辑器轻便易用,想要编辑哪种项目,只需扩展插件就OK, ...

  6. .Net Core Serverless初体验

    什么是Serverless Serverless 是一个当今软件世界中比较新的话题.它并没有一个普遍公认的权威定义,每个人每个企业对它的解释可能都有不同,而 Serverless 正是在这种情况下不断 ...

  7. LayIM.AspNetCore Middleware 开发日记(七)Asp.Net.Core.SignalR闪亮登场

    前言   前几篇介绍了整个中间件的构成,路由,基本配置等等.基本上没有涉及到通讯部分.不过已经实现了融云的通讯功能,由于是第三方的就不在单独去写.正好.NET Core SignalR已经出来好久了, ...

  8. .NET Core SignalR 和 .NET SignalR 区别

    由于要转 .NET Core ,对于以前用到的一些进行迁移. 在迁移 SignalR 的时候发现 .NET Core 下的和 .NET 下的区别还是挺大的. 功能差异 自定重新连接 .NET 下的 S ...

  9. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

    早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...

随机推荐

  1. [javaEE] javaweb的mvc设计思想

    Servlet:在Servlet中拼接html内容 JSP:在html中拼接java JSP+JavaBean:利用javaBean将大量的代码提取走 Servlet+JSP+JavaBean:Ser ...

  2. 【转】spring boot使用Druid和监控配置

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012100371/article/details/76602612 Druid是Java语言中最好 ...

  3. Heka 的编译

    Heka是Mozilla开源的,基于Go语言实现的,插件式log收集和分析系统. 已经编译好的 release 版本可以在下面地址下载: https://github.com/mozilla-serv ...

  4. mysql数据库详解

    001 数据库应用系统设计 1.规划   2.需求分析   3.概念模型设计   4.逻辑设计   5.物理设计   6.程序编制及调试   7.运行及维护. 002 创建数据库 CREATE DAT ...

  5. lintcode 题目记录3

    Expression Expand  Word Break II Partition Equal Subset Sum  Expression Expand  字符串展开问题,按照[]前的数字展开字符 ...

  6. js如何判断字符串里面是否含有某个字符串

    方法一: indexOf() (推荐) var str = "123"; console.log(str.indexOf("3") != -1 ); // tr ...

  7. sass变量

    sass变量用法 1.sass变量必须以$符开头,后面紧跟着变量名 2.变量值和变量名之间就需要使用冒号(:)分隔开(就像CSS属性设置一样) 3.如果值后面加上!default则表示默认值 默认变量 ...

  8. iview table数据排序不正确

    在使用iview的table组件时,要做排序 代码: sortable: true,sortMethod: (a, b, type) => { if (type === 'desc') { re ...

  9. openlayers模仿google地图--地图版权随鹰眼关闭打开而改变位置

    额..题目有点长......今天有个群友问我.想实现google地图地图版权随鹰眼关闭状态改变位置的功能.就是这种<ignore_js_op> 打开鹰眼时  地图版权也随着鹰眼位置改变而改 ...

  10. iDempiere 使用指南 开发环境搭建

    Created by 蓝色布鲁斯,QQ32876341,blog http://www.cnblogs.com/zzyan/ iDempiere官方中文wiki主页 http://wiki.idemp ...