前言
一早起床后,在消化RSS的过程中,看到Scott Hanselman在Russia TechDays介绍SignalR的影片,一整个让人很惊艳,马上就想动手写写看。
由于我也是初学者,先把相关Reference 列上来,有兴趣的朋友可以直接参考官网或影片,应该会比我的文章清楚的多。
Reference :
简介
SignalR 的重点,就在于即时(realtime) ,以往在设计网站的时候,基本上都是透过client 页面重新整理页面、重送request 或定时轮询server 端,以重新呈现即时的资料。但那根本不是即时,即时应该是server 端一旦有了最新的资料,会主动通知client 端更新资料的呈现。
但这样的机制,往往得透过很多机制,很多复杂的设计,才有可能达成。
SignalR 则像撰写.NET Remoting 一般
- 在server 端定义对应的hub class。
- 在client 定义hub class 所对应的proxy。
- 在client 与server间,建立一个不断的connection。
- 接着client 端可以呼叫proxy object 的方法,也就是server 端的方法,也就是送request 给server 端。
- server 端接收到request 资料后,可以针对所有的client 发送通知。
如果各位去下载SignalR.Sample ,其例子就是股票的即时资讯,股票的资讯没法子透过定时重新整理,那可能会亏死。如果每一秒都跟server 送request,那server 一定会loading 太重而炸掉。透过SignalR,这不再是无解的问题。
有兴趣的朋友,可以直接在NuGet 的Package Manager Console,输入
install-package SignalR.Sample
即时聊天室范例
这边跟着说明文件,来建立一个可即时对所有client 送出,某人送出最新的讯息。
- 建立一个ASP.NET 4.0 的WebApplication or WebSite,官网上是使用Web Application,我这边则使用WebSite 来示范。
- 在NuGet 的Package Manager Console,输入「install-package SignalR」,相关的参考档案,如下图所示:
- 建立一个范例网页: SignalR_Sample.aspx,供使用者可以透过网页发送与接收聊天室讯息。
- 建立一个Chat class,用来处理client 发送的讯息,以及发送通知给所有client 的处理。
接下来,来看网页与server 端的hub 该怎么设计。
实作
首先,设计一个最简单的发送与接收讯息的画面,程式码如下:
02 | < input type = "text" id = "message" /> |
03 | < input type = "button" id = "send" value = "送出" /> |
07 | < ul id = "wholeMessages" > |
画面:
接下来撰写server 端Chat class 的内容:
几个重点:
- HubName:这个atttibute 代表client 端要如何建立对应server 端物件的proxy object。透过HubName , server 端的class name才不会被client 绑死。如果没有设定,则会以server 端class name 为HubName 预设值。
- 继承Hub:继承Hub 之后,很多对应的设计就都不用写了,我们只需要把注意力放在client 如何送request 给server的hub , server 如何通知client 即可。Hub 上有一些属性可以使用,请参考下图:
- public void SendMessage(string message) ,就像WebService Method 或PageMethod 一般, client 端透过proxy object ,可以直接呼叫server 端这个方法。后续会介绍到如何在页面上使用。
- Clients property:代表所有有使用Chat 的页面。而Clients 的型别是dynamic ,因为要直接对应到JavaScript 的物件。
- Clients.addMessage(message):代表server 端呼叫Clients 上的addMessage 方法,也就是JavaScript 的方法。
- 总结: Chat 物件负责的,就是当client 端呼叫SendMessage() 方法后,要把这个message ,送给所有client 页面上呈现。以达到聊天室的功能。
Server 端的Hub 物件设计好后,接着来看页面上如何与server 的hub 物件互动。
页面:
01 | <script src= "Scripts/jquery-1.6.4.js" type= "text/javascript" ></script> |
02 | <script src= "Scripts/jquery.signalR-0.5.2.js" type= "text/javascript" ></script> |
03 | <%--很重要的一个参考,一定要加,且在这一行之前,一定要先参考jQuery.js与signalR.js--%> |
04 | <script src= "../SignalR_WebSite/signalr/hubs" type= "text/javascript" ></script> |
05 | <script type= "text/javascript" > |
09 | var chat = $.connection.joeyChat; |
12 | chat.addMessage = function (message) { |
14 | $( '#wholeMessages' ).append( '<li>' + message + '</li>' ); |
17 | $( "#send" ).click( function () { |
19 | chat.sendMessage($( '#message' ).val()); |
20 | $( '#message' ).val( "" ); |
24 | $.connection.hub.start(); |
- 先引用jQuery 与signalR 的js 档。
- 很重要的一个步骤:加入一个js参考,其路径为「根目录/signalr/hubs」。SignalR会建立相关的JavaScript,放置于此。
- 透过$.connection.『server端的HubName』,即可建立对应该hub的proxy object。要注意,首字母需小写。
- 定义client 端上,供server 端通知的JavaScript function,这边的范例是addMessage。
- 当按下送出按钮时,呼叫server端的SendMessage()方法,只需要直接透过proxy object即可。要注意,首字母需小写。
- 记得透过$.connection.hub.start() ,把connection 打开。
画面
我们透过多个browser 页面,来模拟是否所有client 都会收到同步的讯息。
接着在某一页上输入hello world,按下送出的同时,所有页面都会即时更新讯息。
结论
- 安装相当简单
- 使用相当简单
- 应用面相当广泛
其实我也只是初学者,但实在觉得这样的东西实在把底层复杂的机制包装的太美好了,忍不住赶紧跟大家介绍这个好物,相信很快就可以看到不同的应用或更深入的介绍了。