第五节: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代码展示:

 1     /// <summary>
 2     /// 整合MVC和SignalR
 3     /// </summary>
 4     public class BaseController<T> : Controller where T : Hub
 5     {
 6         public IHubConnectionContext<dynamic> Clients { get; set; }
 7
 8         public IGroupManager Groups { get; set; }
 9
10         public BaseController()
11         {
12             var hub = GlobalHost.ConnectionManager.GetHubContext<T>();
13             Clients = hub.Clients;
14             Groups = hub.Groups;
15         }
16     }

  继承BaseController的代码展示:

 1  public class HubController : BaseController<MySpecHub1>
 2     {
 3
 4         /// <summary>
 5         /// 向所有人发送消息
 6         /// </summary>
 7         /// <param name="myConnectionId">当前用户的登录标记</param>
 8         /// <param name="msg">发送的信息</param>
 9         public string MySendAll(string myConnectionId, string msg)
10         {
11             //Hub模式
12             Clients.AllExcept(myConnectionId).receiveMsg($"用户【{myConnectionId}】发来消息:{msg}");
13             return "ok";
14         }
15
16     }

  

三. 全局的几个配置

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

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

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

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

    GlobalHost.Configuration.TransportConnectTimeout = 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;

四. 跨域的应用

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

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

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

  注:采用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));

 代码如下:

 1   class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5
 6             //一. 基础信息配置
 7             //1. 与服务器路径进行匹配
 8             var conn = new HubConnection("http://localhost:8099/signalr/");
 9             //2. 创建代理类
10             var proxy = conn.CreateHubProxy("MySpecHub1");
11
12
13             //二. 定义客户端的方法
14             //特别注意,如果定义的方法大于一个参数的时候,msg的位置需要声明一个类来接受
15             //1 接受用户登录成功后的提示
16
17             proxy.On("LoginSuccessNotice", (msg) =>
18             {
19                 Console.WriteLine(msg);
20             });
21
22             //2  接收自己的connectionId
23             proxy.On("ReceiveOwnCid", (msg) =>
24             {
25                 Console.WriteLine(msg);
26             });
27
28             //三. 启动
29             conn.Start().Wait();
30
31             Console.ReadKey();
32
33         }
34     }

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

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

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

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

2. 添加集线器类MySpecHub1

3. 在Startup中配置允许跨域

4. 编写启动代码

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

 1       static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 string url = "http://localhost:7080";
 6                 using (WebApp.Start<Startup>(url))
 7                 {
 8                     Console.WriteLine("Server running on {0}", url);
 9                     Console.ReadLine();
10                 }
11             }
12             catch (Exception ex)
13             {
14                 Console.WriteLine(ex.Message);
15             }
16             Console.ReadKey();
17         }

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

!

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

原文地址:https://www.cnblogs.com/yaopengfei/p/9327321.html

时间: 2024-11-05 21:31:19

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

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

spring mvc 图片上传,跨域解决 按天生成目录 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ #fs.domains=182=http://172.16.100.182:18080,localhost=http://localhost:8080 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE be

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

spring mvc 图片上传,跨域解决 按天生成文件夹 ,删除,限制为图片代码,等相关配置 fs.root=data/ #fs.root=/home/dev/fs/ #fs.root=D:/fs/ #fs.domains=182=http://172.16.100.182:18080,localhost=http://localhost:8080 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE b

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

总是有人会遇到跨域问题,然后有个jsonp的解决方案,MVC中代码如下: public class JsonpResult : System.Web.Mvc.JsonResult { object data = null; public JsonpResult() { } public JsonpResult(object data) { this.data = data; } public override void ExecuteResult(ControllerContext contro

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

这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的ActionFilterAttribute,我们就是这么实现的: public class AllowCorsAttribute : ActionFilterAttribute { private string[] _domains; public AllowCorsAttribute(string dom

SignalR 和跨域问题 (ASP.NET)

SignalR 有三块, Server: Hub Server Custom Message Sender Service (Sender Proxy) Client: Message Sender Message Receiver 1. Hub Server & Sender Proxy ServiceHub Server 和 Custom Message Sender Service 在一个app中,"Custom Message Sender Service" 通过api

SignalR 跨域设置

参考文章:http://www.cnblogs.com/nywd/p/3691813.html 上一节,已经实现了,当前域内的通信,这一节中,介绍一下跨域的即时通信,既然要做,我们肯定要把这个推送及聊天服务器做为一个单独的服务器,以方便扩展使用,这样就要使用跨域技术,既然基于ajax,那么跨域肯定是基于jsonp,下面我们介绍一下跨域的基本配置: 1.服务器的配置,我们打开项目中的Global.asax,在Application_Start中做如下配置: protected void Appli

jQuery中Ajax+Spring MVC实现跨域请求

项目开发中,某个可独立.也可集成的子业务模块须要向外开放相关API接口,先说下项目本身使用了jersery来实现RESTful webservice以名词形式公布API.有意思的是在实际的操作中同事却通过Ajax跨域请求的方式去调用该API,先不说成功与否,这样的方式本就是"滑稽"的.和他一起探讨了此种做法的不合理性,之后选择jersey client的方式进行远程调用.只是他在跨域请求中遇到了问题,自己闲暇时间予以解决,这才是此篇文章的由来. jQuery对跨域请求有两种解决方式各自

浅谈Web Api配合SignalR的跨域支持

最近接手的一个项目中,涉及到一个简单的消息模块,由于之前有简单了解过SignalR,所以打算尝试着摸索摸索~! 首先,通过Nuget管理器添加Microsoft ASP.NET SignalR引用~目前最新版本2.2.0,依赖项目也有点多,什么Microsoft.AspNet.SignalR.JS,Microsoft.AspNet.SignalR.SystemWeb,还有Owin相关的项目,没法咯,一起统一引用! 添加启动设置 1 [assembly: OwinStartup(typeof(Si

spring MVC cors跨域实现源码解析 CorsConfiguration UrlBasedCorsConfigurationSource

spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就是跨域. spring MVC自4.2开始添加了跨域的支持. 跨域具体的定义请移步mozilla查看 使用案例 spring mvc中跨域使用有3种方式: 在web.xml中配置CorsFilter <filter> <filter-name>cors</filter-name> <