一. 说在前面的话

  本节主要在前面章节的基础上补充了几个简单的知识点,比如:第三方调用通过 GlobalHost.ConnectionManager.GetHubContext<MySpecHub1>();来获取Hub对象,那么能不能封装一下不必每次都这么获取呢?再比如SignalR传输是否有大小限制,一下传输10w个字能否传输成功?最后着重整理一下跨域的各种使用情况,结合C/S程序充当客户端和服务器端。

  本节内容包括:

    ①. SignalR与MVC或者WebApi简单的整合。

    ②. 全局的几个配置。

    ③. 跨域的配置和应用。

    ④. C/S程序充当客户端或服务器端。

二. SignalR与MVC的简单整合

  在前面的章节中我们已经知道,如果要通过控制器中的Action来实现通讯,需要通过 GlobalHost.ConnectionManager.GetHubContext<MySpecHub1>(); 来获取Hub类,但是每个Action中都这么获取,显得有点麻烦,这里简单封装一下,来便捷开发。

    分析:实质在我们在Action中用到的对象无非也就这两个,IHubConnectionContext<dynamic> Clients  和  IGroupManager Groups ,所以这里利用继承的关系简单的封装一下,声明BaseController类,在里面获取这两个对象,然后其它控制器继承BaseController,并传入对应的Hub类,这样在Action中就可以直接使用 Clients和Groups了。

  PS:WepAPI程序可以采用下面类似方式进行封装。

  BaseController代码展示:

     /// <summary>
/// 整合MVC和SignalR
/// </summary>
public class BaseController<T> : Controller where T : Hub
{
public IHubConnectionContext<dynamic> Clients { get; set; } public IGroupManager Groups { get; set; } public BaseController()
{
var hub = GlobalHost.ConnectionManager.GetHubContext<T>();
Clients = hub.Clients;
Groups = hub.Groups;
}
}

  继承BaseController的代码展示:

  public class HubController : BaseController<MySpecHub1>
{ /// <summary>
/// 向所有人发送消息
/// </summary>
/// <param name="myConnectionId">当前用户的登录标记</param>
/// <param name="msg">发送的信息</param>
public string MySendAll(string myConnectionId, string msg)
{
//Hub模式
Clients.AllExcept(myConnectionId).receiveMsg($"用户【{myConnectionId}】发来消息:{msg}");
return "ok";
} }

  

三. 全局的几个配置

  这里的全局配置主要包括:传输超时时间、强制关闭时间、WebSocket模式下允许传输的数据最大值等等,以下配置代码可以在Configuration方法中进行配置,可以根据实际业务情况自行选择配置。

  1. 表示客户端在转而使用其他传输或连接失败之前应允许连接的时间。默认值为 5 秒。(传输超时时间)

    GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromSeconds(5);

  2. 表示连接在超时之前保持打开状态的时间

    GlobalHost.Configuration.ConnectionTimeout= TimeSpan.FromSeconds(5);

  3. 用于表示在连接停止之后引发断开连接事件之前要等待的时间。 (强制关闭时间)

    GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(5);

  4. 表示两次发送保持活动消息之间的时间长度。如果启用,此值必须至少为两秒。设置为 null 可禁用。

    GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(2);

  5. Websocket模式下允许传输数据的最大值,默认为64kb

    GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = 64;

PS:设置消息缓冲区大小

  GlobalHost.Configuration.DefaultMessageBufferSize = 500;

(默认情况下,SignalR 将保留在内存中的每个中心的每个连接的 1000 条消息。 如果使用大型消息时,这可能会造成内存问题,这可以通过减小此值来缓解压力)

四. 跨域的应用

  在很多情况下,前后端是分离,客户端和服务器端并不在一个地址下,比如APP(这里指混合开发能使用JS的情况下),这个时候服务器的SignalR就需要配置允许跨域,这里有两种允许跨域的策略,一种是JSONP模式,另外一种是Cors模式。

  在Startup类中的Configuration方法中进行配置,代码如下

   public class Startup
{
public void Configuration(IAppBuilder app)
{
//配置允许跨域
//1. JSONP模式
//app.MapSignalR(new HubConfiguration() { EnableJSONP = true }); //2. Cors模式(需要安装Microsoft.Owin.Cors程序集)
app.UseCors(CorsOptions.AllowAll).MapSignalR();
}
}

  注:采用Cors模式的跨域需要安装:Microsoft.Owin.Cors 程序集,并且上述代码没有单独配置模型路径,所以采用的是默认路径“/signalr”。

  当然前端代码也需要进行相应的改写:

(1). 代理模式的改写形式:

  a. 自动生成代理类代码需要改写为 <script src="http://localhost:7080/signalr/hubs"></script> ,localhost:7080,根据实际情况改为实际地址。

      b. 需要单独配置一下Hub的连接路径, conn.url = "http://localhost:7080/signalr";

 以上两步即为全部改变,其余位置不需变化。

(2). 非代理模式下的代码:

  非代理模式下就更容易,只需要在hubConnection方法中传入路径即可。如下图:

五. C/S程序充当客户端

  C/S程序(这里采用控制台)充当客户端,当然服务器端必须已经配置了允许跨域,且C/S程序是没有JS的,所以只能采用非代理模式。

 步骤如下:

  1:安装程序集 Microsoft.AspNet.SignalR.Client

  2:代码配置

    a. 与服务器路径匹配的时候要注意,默认路径的话,要加上signalr/

    b. 如果定义的方法大于一个参数的时候,需要声明一个类来接收

    eg:Proxy.On<Person>("方法名", Person=>

      Console.WriteLine("ID{0} Name{1}", Person.ID, Person.Name));

 代码如下:

   class Program
{
static void Main(string[] args)
{ //一. 基础信息配置
//1. 与服务器路径进行匹配
var conn = new HubConnection("http://localhost:8099/signalr/");
//2. 创建代理类
var proxy = conn.CreateHubProxy("MySpecHub1"); //二. 定义客户端的方法
//特别注意,如果定义的方法大于一个参数的时候,msg的位置需要声明一个类来接受
//1 接受用户登录成功后的提示 proxy.On("LoginSuccessNotice", (msg) =>
{
Console.WriteLine(msg);
}); //2 接收自己的connectionId
proxy.On("ReceiveOwnCid", (msg) =>
{
Console.WriteLine(msg);
}); //三. 启动
conn.Start().Wait(); Console.ReadKey(); }
}

六. C/S程序充当服务器端

  在很多情况下,我们需要避免使用IIS的性能开销,或者要将SignalR部署成Windows服务,这个使用就需要使用C/S程序作为服务器端了。

 配置步骤比较简单,如下: 

1. 安装程序集:Microsoft.AspNet.SignalR.SelfHost 和 Microsoft.Owin.Cors(跨域使用)

2. 添加集线器类MySpecHub1

3. 在Startup中配置允许跨域

4. 编写启动代码

 PS:以上步骤2和步骤3在前面章节中已经多次提到过了,这里指展示一下启动代码:

       static void Main(string[] args)
{
try
{
string url = "http://localhost:7080";
using (WebApp.Start<Startup>(url))
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}

  特别注意:如果报System.Reflection.TargetInvocationException was unhandled,直接去bin文件里以管理员身份运行exe程序即可或者以管理员身份运行VS程序然后启动即可。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)的更多相关文章

  1. 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)

    并发编程概述   前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...

  2. .NET MVC & Web API Cors让AJAX 实现跨域

    什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...

  3. spring mvc 图片上传,图片压缩、跨域解决、 按天生成文件夹 ,删除,限制为图片代码等相关配置

    spring mvc 图片上传,跨域解决 按天生成文件夹 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ ...

  4. MVC上的jsonp扩展,解决跨域访问问题

    总是有人会遇到跨域问题,然后有个jsonp的解决方案,MVC中代码如下: public class JsonpResult : System.Web.Mvc.JsonResult { object d ...

  5. jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求

    这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的Acti ...

  6. 第四节:跨域请求的解决方案和WebApi特有的处理方式

    一. 简介 前言: 跨域问题发生在Javascript发起Ajax调用,其根本原因是因为浏览器对于这种请求,所给予的权限是较低的,通常只允许调用本域中的资源, 除非目标服务器明确地告知它允许跨域调用. ...

  7. SignalR 跨域设置

    参考文章:http://www.cnblogs.com/nywd/p/3691813.html 上一节,已经实现了,当前域内的通信,这一节中,介绍一下跨域的即时通信,既然要做,我们肯定要把这个推送及聊 ...

  8. Web API(五):Web API跨域问题

    一.什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本.是由浏览器的同源策略造成的,是浏览器施加的安全限制.(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器 ...

  9. Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置

    Asp.Net SignalR 使用记录   工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...

随机推荐

  1. A Deep Learning-Based System for Vulnerability Detection(一)

    接着上一篇,讨论讨论具体步骤实现方法.步骤1-3分别在下面进行阐述,步骤4,6都是标准的,步骤5类似于步骤1-3. 结合这个图进行讨论详细步骤: 步骤1:提取库/API函数调用和程序片段 1.1将库/ ...

  2. June. 24th 2018, Week 26th. Sunday

    Beautiful things don't ask for attention. 真正美丽的东西,并不会刻意寻求别人的注目. From The Secret Life of Walter Mitty ...

  3. flink Standalone Cluster

    Requirements Software Requirements Flink runs on all UNIX-like environments, e.g. Linux, Mac OS X, a ...

  4. 【转】Android中保持Service的存活

    这几天一直在准备考试,总算有个半天时间可以休息下,写写博客. 如何让Service keep alive是一个很常见的问题. 在APP开发过程中,需要Service持续提供服务的应用场景太多了,比如闹 ...

  5. scipy.stats.multivariate_normal的使用

    参考:https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.multivariate_normal.html ...

  6. 前端——HTML

    HTML HTML叫做超文本标记语言,是一种制作万维网页面标准语言.相当于定义一套规则,大家都来遵守它,这样浏览器就可以去解释它. 浏览器负责将标签翻译成用户看得懂的格式,呈现给用户. 作为开发者需要 ...

  7. 哈希长度扩展攻击(Hash Length Extension Attack)利用工具hexpand安装使用方法

    去年我写了一篇哈希长度扩展攻击的简介以及HashPump安装使用方法,本来已经足够了,但HashPump还不是很完善的哈希长度扩展攻击,HashPump在使用的时候必须提供original_data, ...

  8. git revert用法以及与git reset的区别

    git revert用法 git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销 作为一次最新的提交 * git revert HEAD     ...

  9. HttpPost方式调用接口的3种方式

    第一种:需要httpclient的依赖包 <dependency> <groupId>org.apache.httpcomponents</groupId> < ...

  10. python之collection模块

    collections模块 一.总览 在内置数据类型(int.float.complex.dict.list.set.tuple)的基础上, collections模块还提供了几个额外的数据类型:Co ...