• MVC4中使用SignalR


    MVC4中使用SignalR

    前言

      周末在偶尔翻阅微软官网的时候看到Getting Started with SignalR and MVC 4此篇文章,知道了signalr这个东西,貌似这个出来很长时间了,奈何自己一直没有发现,不妨写篇文章敲一下代码记录这个东西。

      ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的。WebSockets是HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSockets可用时(即浏览器支持Html5)SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果。SignalR当然也提供了非常简单易用的高阶API,使服务器端可以单个或批量调用客户端上的JavaScript函数,并且非常 方便地进行连接管理,例如客户端连接到服务器端,或断开连接,客户端分组,以及客户端授权,使用SignalR都非常 容易实现。SignalR 将与客户端进行实时通信带给了ASP .NET 。当然这样既好用,而且也有足够的扩展性。以前用户需要刷新页面或使用Ajax轮询才能实现的实时显示数据,现在只要使用SignalR,就可以简单实现了。最重要的是您无需重新建立项目,使用现有ASP .NET项目即可无缝使用SignalR。

    1、向MVC4项目添加对signalr类库的引用

      新建一个mvc4项目,并通过Nugget包管理器获取Microsoft.AspNet.SignalR,如下图:

    选择第一个点击添加以后弹出所有依赖的类库安装说明,选择接受:

    安装完成以后可以看到所有依赖的类库,及项目中需要的js,和使用说明:

    2、添加Hub像客户端发送内容

    在项目中新建一个文件夹Hub,新增一个SignalR Hub类ChatHub.cs继承Hub此类将作为向客户端发送消息的服务端处理类。添加如下代码:

    复制代码
    public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                // 客户端调用addNewMessageToPage方法传送信息
                Clients.All.addNewMessageToPage(name, message);
            }
        }
    复制代码

    Global.asax中添加对hub的路由映射:

    在HomeController中添加action-chat并返回视图,在视图中添加如下代码:

    public ActionResult Chat()
            {
                return View();
            }

    视图:

     View Code

    运行程序请求/home/chat首先弹出填写用户名的对话框:

    输入名称以后,填写消息发送,所有的消息都可以及时从后台返回到也也页面上,可以多开几个窗口测试如图:

    在脚本中客户端调用ChatHub.Send方法发送新消息,后台通过Clients.All.addNewMessageToPage方法向所有客户端回发消息,在ChatHub类中,可以定义公共的方法供客户端jquery调用,通过Microsoft.AspNet.SignalR.Hub.Clients来连接所有客户端。

    周末偶然看到的一个东西也没有深入研究,本人也是初识很多地方不太了解,查了一些资料以备不时只需:

    https://github.com/SignalR/SignalR

    http://www.codeproject.com/Articles/536514/SignalRplusOnlineplusCounterplusSample

    http://www.codeproject.com/Articles/524066/SignalR-Simple-Chat-Application-in-Csharp

     
     

    ASP.NET MVC学习笔记-----ControllerFactory

      上面这张图是asp.net mvc的工作流程图,我们可以看到当一个http请求来临时,首先需要经过路由系统,路由系统从中获取一些路由信息,然后ControllerFactory根据所得到的路由信息生成相应的Controller。也就是说,ControllerFactory的作用就是根据路由信息生成相应的Controller。

    1.ASP.NET MVC内置的ControllerFactory-----DefaultControllerFactory

      在ASP.NET MVC框架中已经给我们提供了内置的ControllerFactory,即DefaultControllerFactory。它首先从routing data中获取到所请求的controller的名字,然后根据该名字去寻找相应的Controller。如果你希望一个类能被ControllerFactory当作Controller并生成需要遵循以下规则:

      (1)该类的作用域必须为public

      (2)该类必须可被实例化

      (3)该类不能是泛型类

      (4)该类的名称的结尾必须是Controller (这也是我们常说的约定大于配置)

      (5)该类必须实现IController接口

    利用DefaultControllerFactory指定命名空间优先级

      如果我们希望DefaultControllerFactory在寻找Controller时都优先在指定的命名空间下寻找,我们可以利用它的DefaultNamespaces属性。不多说,看代码就明白了:

    复制代码
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    
                ControllerBuilder.Current.DefaultNamespaces.Add("MyNamespace");
            }
        }
    复制代码

      我们在Global.asax.cs中的Application_Start方法中添加最后一句代码,ControllerBuilder.Current属性返回的是当前的ControllerFactory(在这里就DefaultControllerFactory实例)。这样,DefaultControllerFactroy在寻找相应的Controller都优先在MyNamespace空间下寻找。如果在MyNamespace空间未找到,则继续在其他命名空间寻找。

    2.使用自定义ControllerFactory

      如果ASP.NET MVC内置的DefaultControllerFactory无法满足需求的话,我们可以自定义ControllerFactory来替代DefaultControllerFactory。

      首先,一个ControllerFactory需要实现IControllerFactory接口:

    复制代码
        public interface IControllerFactory
        {
            IController CreateController(RequestContext requestContext, string controllerName);
            SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
            void ReleaseController(IController controller);
        }
    复制代码

      其中CreateController方法是关键,它定义了一个ControllerFactory是如何根据信息寻找相应的Controller。而GetControllerSessionBehavior定义指定Controller的Session行为,ReleaseController  方法则是释放指定Controller。

      下面来看一个例子吧:

    复制代码
        public class CustomControllerFactory : IControllerFactory
        {
            public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
            {
                //在这里,为了简单,我不管当前http请求信息是什么,都生成HomeController实例。
                Type targetType = typeof(HomeController);
                return (IController)DependencyResolver.Current.GetService(targetType);
            }
    
            public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(System.Web.Routing.RequestContext requestContext, string controllerName)
            {
                //默认的Session行为
                return SessionStateBehavior.Default;
            }
    
            public void ReleaseController(IController controller)
            {
                IDisposable disposable = controller as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
    复制代码

      在这个例子,不管http请求的信息是什么CustomControllerFactory都生成HomeController实例。

      接着我们需要在Global.asax.cs的Application_Start方法中注册我们自定义的CustomControllerFactory:

    复制代码
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
    //注册自定义ControllerFactory ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory()); } }
    复制代码

      现在,MVC使用的就是我们自定义的ControllerFactory了:无论请求信息是什么,生成的都是HomeController。

        

     
     
     
     
    标签: .net mvc
  • 相关阅读:
    CSS margin重叠 & CSS BFC(Block Formatting Context)
    require.js
    bind()函数的作用
    JavaScript DOM 总结
    插入排序-直接插入排序、希尔排序
    交换排序-起泡排序、快速排序算法
    JavaScript全局函数
    JavaScript命名空间的理解与实现
    document.documentElement.clientWidth
    Python-删除多级目录
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3280877.html
Copyright © 2020-2023  润新知