/*
*· Persistent Connection(HTTP持久链接):持久性连接,用来解决长时间连接的能力,而且还可以由客户端主动向服务器要求数据,而服务器端也不需要实现太多细节,只需要处理 PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。
*· Hub:信息交换器,用来解决 realtime 信息交换的功能,服务器端可以利用 URL 来注册一个或多个 Hub,只要连接到这个 Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务器端可以调用客户端的脚本,不过它背后还是不离 HTTP 的标准,所以它看起来神奇,但它并没有那么神奇,只是 JavaScript 更强,强到可以用像 eval() 或是动态解释执行的方式,允许 JavaScript 能够动态的加载与执行方法调用而己。
*/
这是微软官方SignalR 2.0教程Getting Started with ASP.NET SignalR 2.0系列的翻译,这里是第四篇:开始使用SignalR 2.0
原文:Getting Started with SignalR 2.0
PS.前面的那篇从SignalR1.0升级为2.0跳过了……只有几步,有兴趣的同学可以自己去看。
概述
本教程展示了如何使用SignalR2.0构建一个基于浏览器的聊天室程序。你将把SignalR库添加到一个空的ASP.NET Web应用程序中,创建用于发送消息到客户端的集线器(Hubs)类,创建一个HTML页面让用户在该页面上发送和接收聊天信息。对于如何在MVC5环境中中创建一个聊天室,请参阅Getting Started with SignalR 2.0 and MVC 5。
SignalR是一个开源的.Net库,用于构建需要实时用户交互或实时数据更新的Web应用程序。比如社交应用,多用户在线游戏,商务协作,新闻,天气,金融或更新应用程序。以上通常被成为实时应用程序。
SignalR简化构建实时应用程序的过程。它包括一个ASP.NET服务器库和一个JavaScript客户端库,使其更易于管理客户端到服务器端的连接并推送内容更新到客户端。您可以将SignalR库添加到现有的ASP.NET应用程序以获得实时功能。
本教程将演示以下SignalR开发任务:
- 添加SignalR库到ASP.NET Web应用程序
- 建立一个集线器类来推送更新内容到客户端
- 建立一个.Net开放Web接口(OWIN)启动类来配置应用程序
- 在网页中使用SignalR jQuery库发送和显示更新消息
下面的屏幕截图显示了在浏览器中运行的聊天应用程序,每个新加入聊天室的用户都可以随意发言。
设置项目
本节说明如何使用VS2013及SignalR 2.0库来创建一个空的ASP.NET WEB引用程序并向其中添加SignalR,以创建聊天室。
1.在VS2013中创建一个新的WEB应用程序。
2.在新的ASP.NET项目窗口中,选择空项目并确定创建。
3.在解决方案资源管理器中,右击该项目,选择添加—新建项,选择SignalR集线器类(v2),命名为ChatHub.cs并添加,如下图:
这一步将创建ChatHub类,并将一组SignalR脚本和程序集引用添加到项目中。
注意:您还可以通过NuGet来添加SignalR到项目中,通过打开工具—库软件包管理器—包管理器控制台 ,并运行一个命令:
install-package Microsoft.AspNet.SignalR
如果您使用包管理器控制台来添加SignalR,请在添加后再执行创建ChatHub类这一步。
4.在解决方案资源管理器中,展开脚本文件夹,可以看到项目已经添加了jQuery及SignalR的JS引用。
5.用编辑你的ChatHub文件,删除Hello方法并添加Send方法,如下面的代码:
using System; using System.Web; using Microsoft.AspNet.SignalR; namespace SignalRChat { public class ChatHub : Hub { public void Send(string name, string message) { // Call the broadcastMessage method to update clients. Clients.All.broadcastMessage(name, message); } } }
6.在解决方案资源管理器中,右击该项目,然后单击添加—新建项—OWIN启动类,将类命名为Startup并添加。
7.在启动类的配置方法中添加SignalR的映射,如下面的代码:
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(SignalRChat.Startup))] namespace SignalRChat { public class Startup { public void Configuration(IAppBuilder app) { // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR(); } } }
8.在解决方案资源管理器中,右键单击该项目,然后单击添加—新建项—HTML页面,命名为index.html并添加。
9.用下面的代码替换掉HTML中的。
<!DOCTYPE html> <html> <head> <title>SignalR Simple Chat</title> <style type="text/css"> .container { background-color: #99CCFF; border: thick solid #808080; padding: 20px; margin: 20px; } </style> </head> <body> <div class="container"> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"> </ul> </div> <!--Script references. --> <!--Reference the jQuery library. --> <script src="Scripts/jquery-1.6.4.min.js" ></script> <!--Reference the SignalR library. --> <script src="Scripts/jquery.signalR-2.0.2.min.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="signalr/hubs"></script> <!--Add script to update the page and send messages.--> <script type="text/javascript"> $(function () { // Declare a proxy to reference the hub. var chat = $.connection.chatHub; // Create a function that the hub can call to broadcast messages. chat.client.broadcastMessage = function (name, message) { // Html encode display name and message. var encodedName = $('<div />').text(name).html(); var encodedMsg = $('<div />').text(message).html(); // Add the message to the page. $('#discussion').append('<li><strong>' + encodedName + '</strong>: ' + encodedMsg + '</li>'); }; // Get the user name and store it to prepend to messages. $('#displayname').val(prompt('Enter your name:', '')); // Set initial focus to message input box. $('#message').focus(); // Start the connection. $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub. chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); }); }); </script> </body> </html>
注意:如果你使用包管理器来安装了SignalR,请核对脚本目录中的SignalR脚本文件名和上面HTML中代码所引用的是否一致,比如下图:
11.保存全部项。
运行示例
1.按下F5在调试模式下运行该项目,如果一切正常,HTML会在浏览器中打开并提示一个对话框。
2.输入用户名并确定。
3.复制这个浏览器中的URL,打开一个新的浏览器实例,在另一个浏览器中,输入一个新用户名。
4.在每个浏览器实例中添加评论并发送,评论将被发送到所有浏览器的页面中。
注意:这个简单的聊天室没有在服务器上维护一个聊天上下文,所有发送的评论将实时广播给打开了页面的所有浏览器,所以新加入的用户无法看到以前的历史记录。
5.在解决方案资源管理器中,检查正在运行的应用程序的脚本文件,你可以看到SignalR库动态生成的Hub脚本文件,该文件管理jQuery脚本和服务器代码之间的通讯。
回顾
SignalR聊天室程序演示了两个基本的SignalR开发任务:在服务器端创建一个集线器作为主要协调对象,并使用SignalR和jQuery来发送和接收评论。
SignalR集线器(Hub)
在代码示例中的ChatHub类派生自Microsoft.AspNet.SignalR.Hub类。是最通常的建立SignalR应用程序的方法就是从Hub类派生。 你可以创建你的集线器类的公共方法,然后从网页中的脚本调用它们来访问这些方法。
这本示例中,客户端调用ChatHub.Send来发送新评论。反之,集线器通过调用Clients.All.broadcastMessage来将新评论发送至所有客户端。
Send方法演示了使用集线器的概念:
- 在集线器上建立公共方法,使客户端可以调用它们。
- 使用使用Microsoft.AspNet.SignalR.Hub.Clients动态属性访问连接到该集线器的所有客户端。
- 调用客户端方法(比如broadcastMessage函数)来更新客户端。
SignalR和jQuery
HTML页面展示了如何使用SignalR jQuery库与SignalR集线器通讯,即定义了一个代理引用集线器,声明一个函数可以让服务器推送内容到客户端,并且开始实时连接以发送消息到集线器上。
下面的代码定义了一个集线器代理的引用。
var chat = $.connection.chatHub;
注意:在JS中引用服务器类及成员应当使用驼峰(camel)式拼写法。该代码示例使用chatHub引用了服务器端的ChatHub。
下面的代码演示了如何创建一个回调函数,服务器上的集线器类调用这个函数来推送内容并更新到每个客户端。前两行代码表示将输入的内容进行HTML编码,作为一个简单的防止脚本注入的方法。
chat.client.broadcastMessage = function (name, message) { // Html encode display name and message. var encodedName = $('<div />').text(name).html(); var encodedMsg = $('<div />').text(message).html(); // Add the message to the page. $('#discussion').append('<li><strong>' + encodedName + '</strong>: ' + encodedMsg + '</li>'); };
下面的代码显示了如何打开与集线器的连接。该代码启动连接,然后传递一个函数来处理HTML页面上发送按钮的点击事件。
$.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub. chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); });
注意:此方法可确保SignalR在事件句柄处理之前就建立好通讯连接。
下一步
您已经了解到SignalR框架是如何构建起一个实时Web应用程序的,您还了解并演练了几个开发任务:添加SignalR库到Web应用程序中,创建一个集线器类及如何从集线器发送、接收消息。
要了解更多,请参阅以下连接: