第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
一. 说在前面的话
本节主要在前面章节的基础上补充了几个简单的知识点,比如:第三方调用通过 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)的更多相关文章
- 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)
并发编程概述 前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...
- .NET MVC & Web API Cors让AJAX 实现跨域
什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...
- spring mvc 图片上传,图片压缩、跨域解决、 按天生成文件夹 ,删除,限制为图片代码等相关配置
spring mvc 图片上传,跨域解决 按天生成文件夹 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ ...
- MVC上的jsonp扩展,解决跨域访问问题
总是有人会遇到跨域问题,然后有个jsonp的解决方案,MVC中代码如下: public class JsonpResult : System.Web.Mvc.JsonResult { object d ...
- jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求
这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的Acti ...
- 第四节:跨域请求的解决方案和WebApi特有的处理方式
一. 简介 前言: 跨域问题发生在Javascript发起Ajax调用,其根本原因是因为浏览器对于这种请求,所给予的权限是较低的,通常只允许调用本域中的资源, 除非目标服务器明确地告知它允许跨域调用. ...
- SignalR 跨域设置
参考文章:http://www.cnblogs.com/nywd/p/3691813.html 上一节,已经实现了,当前域内的通信,这一节中,介绍一下跨域的即时通信,既然要做,我们肯定要把这个推送及聊 ...
- Web API(五):Web API跨域问题
一.什么是跨域问题 跨域:指的是浏览器不能执行其他网站的脚本.是由浏览器的同源策略造成的,是浏览器施加的安全限制.(服务端可以正常接收浏览器发生的请求,也可以正常返回,但是由于浏览器的安全策略,浏览器 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
随机推荐
- 数据库訪问技术之JDBC
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhuojiajin/article/details/32150883 在了解JDBC之前呢, ...
- 基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势)
基于winserver的Apollo配置中心分布式&集群部署实践(正确部署姿势) 前言 前几天对Apollo配置中心的demo进行一个部署试用,现公司已决定使用,这两天进行分布式部署的时候 ...
- 通过Docker发布RestAPI遇到的种种问题
目标:发布一个分词API 问题1:Docker外无法访问API 原因: Docker映射的地址是0.0.0.0:8888端口,而flask启动的时候默认地址是127.0.0.1:5000,需要手动配置 ...
- .net core2.1 三层中使用Autofac代替原来Ioc
首先,现有的三层项目的结构 其中 Repository public interface IPersonRepository { string Eat(); } public class Perso ...
- iis+nginx实现负载均衡
简要说明:nginx的简介自行百度. 目的:把用户的请求分到各个服务器减轻压力.nginx把监听的端口的请求平均转到布署了网站的服务器. 一.windows上安装nginx 1.官网下载windows ...
- 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控
前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...
- Jquery密码强度校验
function passValidate(){ var password=$password.val().trim() if(password===""){ $mima.addC ...
- oracle--数据筛选
一:当统一社会信用代码或者工商注册号两个字段中,有的时候只有一个字段含有数据,但是所取的值必须要拥有字段,这个时候,语句为下: select t.entname, case when t.unisci ...
- 使用IDEA2017在Windows下编程并测试Hadoop2.7+Spark2.2+Azkaban
1. 下载好IDEA HADOOP SPARK 首先,配置IDEA, 在插件管理中使用IDEA在线库安装scala插件, 在在线库直接搜索即可; 其次,配置Maven选项, 将Maven添加到IDEA ...
- Asp.Net core 视图组件ViewComponent
视图组件 ViewComponent 最近用了一下视图组件,还挺方便的,如果遇到公共的部分,可以抽出来,写成视图组件,方便调用 先上图看一下效果:比如首页的4个画红框的地方是4个模块,有些地方可能要重 ...