SignalR简单封装
Posted dwburning
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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); } }
3.新建一个OWIN Startup类型
public class Startup { public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR(); } }
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>
准备工作都已经完成了,接下来,直接访问,网页跳转后,查看调试信息,报了一个错。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); } }
以上演示的内容都是原生的写法,但是每次调用都这么写还是挺麻烦的,所以在此基础上做了一个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); }
使用方式如下:
@{ 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>
每天,进步一点点....
以上是关于SignalR简单封装的主要内容,如果未能解决你的问题,请参考以下文章
《ASP.NET SignalR系列》第二课 SignalR的使用说明
VSCode自定义代码片段14——Vue的axios网络请求封装