介绍
有时候服务端操作需要时间。如果让用户点击一个button,再为了使某些操作执行等上30秒,而唯一的进程提示信息是一个旋转的圆圈,这实在是用户体验不佳。
如果你的服务端操作较耗费时间,那么你可能想让你的用户得知服务器端的实时运行情况,这篇文章就是为你而写。
我将向你展示,在服务器上有一个进程运行时,如何使用SignalR 2.0从服务器向客户端发送消息。结果是给用户显示一个通知栏,告知服务器上的进程状况。
免责声明
事实上,你可以使用这样的技术,并不意味着你应该到处都使用它。你应该努力优化性能。作为一个例子,如果你有一个很慢的数据库查询,你应该首先试着去优化它,而如果这真是一个代价昂贵的操作,你不能改进它,那么你就可以使用这样的技术让用户更多地了解正在进行的操作。
使用代码
首先我们需要将SignalR添加到Web应用程序。有几种方法可以做到这一点,最简单的右击您的项目,管理NuGet包,在线搜索SignalR并且选择安装MicrosoftASP.NET SignalR。
我们将使用一个提供了良好的开箱即用的jQuery通知插件。仍然在NuGet包管理窗口,搜索“noty”,选择和安装名为jQuery Notification Plugin的安装包。
接下来我们在项目中添加一个OWIN Startup class。
将下面这行加到这个新的Startup class的Configuration方法:
接下来,我们要为此添加一个SignalR hub,添加一个新的SignalR Hub Class (v2)到你的项目。
这是服务器端处理类。在我这篇文章的随附例子中,我有类定义如下:
01 | public class RealtimeNotifierHub : Hub |
03 | public int recordsToBeProcessed = 100000; |
05 | public void DoLongOperation() |
07 | for ( int record = 0; record <= recordsToBeProcessed; record++) |
09 | if (ShouldNotifyClient(record)) |
11 | Clients.Caller.sendMessage( string .Format( "Processing item {0} of {1}" , record, recordsToBeProcessed)); |
17 | private static bool ShouldNotifyClient( int record) |
19 | return record % 10 == 0; |
在目前这个时刻我们的服务器已经准备好了。我们有一个从客户端调用的名为DoLongOperation的方法。该方法模拟一个具有100.000次循环的长时间运行的操作,每10次迭代,通知客户当前的现状。Thread.Sleep调用是为了减缓服务器,否则for循环跑得那么快,通知栏会反应不过来。
接下来我们要准备客户端。创建一个新的html页面(或使用您想要显示的通知的网页)。
04 | <title>Real-time notifier</title> |
05 | <script src= "Scripts/jquery-1.10.2.min.js" ></script> |
07 | <!-- Import the noty scripts --> |
08 | <script src= "Scripts/noty/jquery.noty.js" ></script> |
09 | <script src= "Scripts/noty/layouts/top.js" ></script> |
10 | <script src= "Scripts/noty/themes/default.js" ></script> |
12 | <!-- Import the SignalR scripts --> |
13 | <script src= "Scripts/jquery.signalR-2.0.0.js" ></script> |
14 | <script src= "http://www.codeproject.com/signalr/hubs" ></script> |
17 | <div style= "margin-top: 100px;" > |
18 | <!-- This button will trigger the time consuming operation --> |
19 | <input type= "button" id= "mybutton" value= "Call a time consuming server side operation" /> |
21 | <script type= "text/javascript" > |
25 | var realtimeNotifier = $.connection.realtimeNotifierHub; |
28 | realtimeNotifier.client.sendMessage = function (message) { |
29 | showOrUpdateSuccessMessage(message, false ); |
33 | $.connection.hub.start().done( function () { |
34 | $( '#mybutton' ).click( function () { |
36 | realtimeNotifier.server.doLongOperation(); |
41 | <script type= "text/javascript" > |
44 | function showOrUpdateSuccessMessage(message, timeout) { |
46 | n = noty({ text: message, type: 'success' , timeout: timeout, maxVisible: 1 }); |
上面的例子做了几件基本的事情:
- 建立从客户机到服务器的连接
- 声明一个将被服务器调用的客户端函数
- 调用服务器的方法执行耗时的操作
- 更新noty通知栏。
运行时这看起来是这样的:
随时使用此代码。我附上了一个可以运行的Visual Studio 2013的解决方案。
如果你有任何问题,我会很乐意回答他们。
参考