zoukankan      html  css  js  c++  java
  • SignalR简单封装

    需求:Asp.Net MVC 开发客户端,实现与服务器端实时通信。

    众所周知,Web开发是基于http的请求响应模型,每次刷新都需要客户端(浏览器)主动发起请求,那么,这个问题怎么解?Asp.Net SignalR是一个Asp.Net 下的类库,可以在Asp.Net  的Web项目中实现实时通信,完美解决这个问题。关于SignalR具体的介绍可以查阅其他资料,或者查看官方文档:http://signalr.net/,今天我写这篇文章的主要目的是记录学习过程,以及对SignalR的使用进行一个简单的封装。

    开发工具:VS2013

    1.首先,新建一个空的Asp.Net MVC项目,然后按照官方网站上提供的NuGet命令 Install-Package Microsoft.AspNet.SignalR 安装SignalR。

    2.新建一个SignalR集线器类(V2.1)

     public class HelloHub : Hub
        {
            public void Hello(string message)
            {
                //Clients.All.hello();
                GlobalHost.ConnectionManager.GetHubContext<HelloHub>().Clients.All.sayHello("这是服务器转发的内容:" + message);
            }
        }
    View Code

    3.新建一个OWIN Startup类型

    public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
                app.MapSignalR();
            }
        }
    View Code

    4.新建一个HomeController,以及对应的View

     public class HomeController : Controller
        {
            // GET: Home
            public ActionResult Index()
            {
                return View();
            }
        }

    Index.cshtml

    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    <script src="~/Scripts/jquery-1.6.4.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.3.0.min.js"></script>
    <script src="~/signalr/hubs" type="text/JavaScript"></script>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        <script type="text/javascript">
            $(function () {
                var hello = $.connection.HelloHub;
                $.connection.hub.start().done(function () {
                    $("#btnSubmit").click(function () {
                        var message = $("#txtMessage").val();
                        hello.server.Hello(message);
                    });
                });
    
                hello.client.sayHello = function (data) {
                    $("#content").html(data);
                };
    
            });
    
        </script>
    </head>
    <body>
        <div>
            <p id="content"></p>
            <input id="txtMessage" type="text" />
            <input id="btnSubmit" type="button" value="submit" />
        </div>
    </body>
    </html>
    View Code

    准备工作都已经完成了,接下来,直接访问,网页跳转后,查看调试信息,报了一个错。Cannot read property 'client' of undefined(无法读取未定义的属性'client'),这是怎么回事?

    其实,细心的人都已经发现了,我们之前Index.cshtml中引入js文件的时候,引入了一个虚拟目录<script src="~/signalr/hubs" type="text/JavaScript"></script>,这个目录是用来干嘛的?查看调试器中我们请求的资源不难发现,多了一个hubs的js文件,而这个js文件中为我们自动生成了代理,而创建代理的时候使用的Hub的名称为helloHub(小驼峰命名法),与我们创建的Hub的名称HelloHub(大驼峰命名法)不一致,导致代理创建失败。

     为了证明我的猜想,我将hello对象打印出来,事实证明,代理确实创建失败了。

     问题已经找到了,就很好解决,修改我们的类名称,采用小驼峰命名法。批注:方法名称也存在同样的问题,所以一并改为小驼峰命名法。

    public class helloHub : Hub
        {
            public void hello(string message)
            {
                //Clients.All.hello();
                GlobalHost.ConnectionManager.GetHubContext<helloHub>().Clients.All.sayHello("这是服务器转发的内容:" + message);
            }
        }
    <script type="text/javascript">
            $(function () {
                var hello = $.connection.helloHub;
                console.log(hello);
                $.connection.hub.start().done(function () {
                    $("#btnSubmit").click(function () {
                        var message = $("#txtMessage").val();
                        hello.server.hello(message);
                    });
                });
    
                hello.client.sayHello = function (data) {
                    $("#content").html(data);
                };
    
            });
    
        </script>

    再次,请求网页,代理创建成功!

     测试发送内容,完全没有问题。不完美的地方是C#类名称与方法名称都是采用大驼峰命名法,改成了小驼峰是不是有点不爽,其实我们还可以通过特性的方式重命名就可以解决这个问题,就不做演示了,代码如下:

     [HubName("helloHub")]
        public class HelloHub : Hub
        {
            [HubMethodName("hello")]
            public void Hello(string message)
            {
                //Clients.All.hello();
                GlobalHost.ConnectionManager.GetHubContext<HelloHub>().Clients.All.sayHello("这是服务器转发的内容:" + message);
            }
        }
    View Code

    以上演示的内容都是原生的写法,但是每次调用都这么写还是挺麻烦的,所以在此基础上做了一个JQuery的封装:

    jquery.signalR.helper.js

    function SignalRHelper(serverHub) {
        (function ($) {
            var signalRHelper = {
                Conn: undefined,
                ServerHub: undefined,
                ResultData: undefined,
                PushData: undefined,
                //初始化连接
                InitConn: function () {
                    var self = this;
                    if (!self.Conn)
                        self.Conn = $.connection;
                },
                //创建服务代理
                Start: function () {
                    var self = this;
                    self.InitConn();
                    if (!serverHub)
                        serverHub = "hello";
                    self.ServerHub = self.Conn[serverHub];
                    self.Conn.hub.start();
                },
                //订阅服务端推送的数据
                SubscribeServerData: function (clientMethodName,callBack) {
                    var self = this;
                    self.ResultData = null;
                    self.ServerHub.client[clientMethodName] = function (data) {
                        try {
                            self.ResultData = JSON.parse(data);
                        } catch (e) {
                            self.ResultData = data;
                        }
                        callBack(data);
                    };
                },
                //上送数据到服务端
                PushClientData: function () {
                    var self = this;
                    if (arguments.length == 2) {
                        self.ServerHub.server[arguments[0]](arguments[1]);
                    } else if (arguments.length == 3) {
                        self.ServerHub.server[arguments[0]](arguments[1], arguments[2]);
                    } else if (arguments.length == 4) {
                        self.ServerHub.server[arguments[0]](arguments[1], arguments[2], arguments[2]);
                    }
                },
            };
    
            signalRHelper.Start();
            $.SignalRHelper = signalRHelper;
    
        })(jQuery);
    }
    View Code

    使用方式如下:

    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    <script src="~/Scripts/jquery-1.6.4.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.3.0.min.js"></script>
    <script src="~/Scripts/jquery.signalR,helper.js"></script>
    <script src="~/signalr/hubs" type="text/JavaScript"></script>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Index</title>
        <script type="text/javascript">
            $(function () {
                //var hello = $.connection.helloHub;
                //console.log(hello);
                //$.connection.hub.start().done(function () {
                //    $("#btnSubmit").click(function () {
                //        var message = $("#txtMessage").val();
                //        hello.server.hello(message);
                //    });
                //});
    
                //hello.client.sayHello = function (data) {
                //    $("#content").html(data);
                //};
              
                window.SignalRHelper("helloHub");
                $("#btnSubmit").click(function () {
                    var msg = $("#txtMessage").val();
                    $.SignalRHelper.PushClientData("hello", msg);
                });
    
                $.SignalRHelper.SubscribeServerData("sayHello", function (data) {
                    $("#content").html(data);
                });
    
            });
    
        </script>
    </head>
    <body>
        <div>
            <p id="content"></p>
            <input id="txtMessage" type="text" />
            <input id="btnSubmit" type="button" value="submit" />
        </div>
    </body>
    </html>
    View Code

     每天,进步一点点....

  • 相关阅读:
    状态模式
    maven-war-plugin 插件 web.xml 缺失时忽略
    Java远程方法协议(JRMP)
    Java Singleton的3种实现方式
    浅谈分布式消息技术 Kafka
    浅谈分布式事务
    J2EE开发时的包命名规则,养成良好的开发习惯
    使用Dom4j创建xml文档
    Java HttpClient Basic Credential 认证
    Spring MVC的Post请求参数中文乱码的原因&处理
  • 原文地址:https://www.cnblogs.com/dwBurning/p/SignalR.html
Copyright © 2011-2022 走看看