使用 ASP.NET SignalR 构建聊天应用程序






3.77/5 (12投票s)
使用 ASP.NET SignalR 构建聊天应用程序
ASP.NET SignalR 是当今开发技术领域的一项重大革新。设想一个应用程序,其中有一个页面,您需要随着最新数据的可用立即更新用户界面。此类应用程序被称为实时应用程序,用户界面会随着最新数据的可用而立即更新。
最好的例子是股票市场应用程序,它必须在股价发生变化时立即更新用户界面。另一个例子是聊天应用程序,它会立即将最新消息从发送者发送给接收者。一些技术可能包括定时向服务器发出请求以获取数据,或者使用轮询概念来获取数据。一个很好的替代方案是使用 SignalR
。
众所周知,我们的 Web 应用程序模型主要由托管应用程序的服务器和代表应用程序最终用户的客户端组成。
为了创建基于 SignalR
的应用程序,我们需要在服务器上创建一个集线器 (hub),该集线器负责使用最新数据更新客户端或最终用户。这个集线器只不过是一个继承自 Hub
类的简单 class
。在客户端,我们会获得一个(在运行时)自动生成的基于 JavaScript 的代理文件,客户端可以使用它来连接集线器。客户端代码还包含一个 JavaScript 函数,集线器使用该函数向客户端提供最新数据。请参见下图
为了详细解释这个过程,我们的集线器直接调用客户端 JavaScript 函数来提供最新数据。另一方面,通过使用客户端上自动生成的 JavaScript 代理文件,客户端代码可以使用此代理来调用服务器集线器的方法(如果需要)。此处使用的词语如果需要是特意使用的,考虑到客户端可能不需要调用集线器。例如,在一个拥有来自数据库的一些数据的用户仪表板的应用程序中,我们可以使用 SqlDependency
和 SignalR
的概念,在数据库记录发生任何更改时保持用户界面更新。在这种情况下,客户端不需要向服务器发出任何请求即可获取更新。另一方面,如果我们有一个聊天应用程序,客户端代码将调用服务器集线器并转发消息。然后,集线器将通过调用客户端的 JavaScript 方法将此消息广播给应用程序的用户。
上面段落中一个非常重要的点是,客户端永远不会为了获取最新数据而调用集线器。客户端可能只调用集线器,以便集线器可以将消息转发给其他已连接的客户端。如果客户端代码需要向服务器发出请求以获取最新数据,那么使用 SignalR
的全部目的就失败了,我们可以为此使用定时器或页面刷新等旧概念。
在 15 分钟内使用 SignalR 构建简单的群聊应用程序
是的,没错。一旦您了解了 SignalR
的基本概念/流程,就可以非常轻松地完成。我们现在将创建一个群聊,而无需使用任何数据库。如果我们考虑应用程序的流程,整个过程需要客户端将消息发送到服务器,服务器将把该消息广播给所有已连接的客户端用户。所以服务器需要有一个组件,能够将消息广播给客户端。这个角色由集线器类扮演。这是客户端需要调用服务器集线器的示例。让我们尝试可视化这个过程,然后我们将创建应用程序。
创建一个名为 SignalRChat.
的新项目。使用 nuget
添加对 SignalR
库的引用。它将自动添加对 OWIN
托管选项库的引用,该库允许将 SignalR
应用程序添加到 OWIN
管道。除了服务器库之外,它还添加了使用 SignalR
所需的客户端库。请参见下面添加的引用
为应用程序创建 OWIN 主机
我们将使用基于 OWIN
的托管来托管此应用程序。在不深入研究 OWIN
托管的情况下,让我们添加一个名为 Startup.cs 的类。根据 OWIN
基于托管的规范,名称必须是 Startup
,并且其 namespace
必须用 assembly
属性进行装饰,指定 Startup
程序集是应用程序的起点。接下来,我们定义一个名为 Configuration
的方法,并使用 app.MapSignalR()
在 OWIN
管道中注册 SignalR
。
在服务器上创建集线器
我们的下一步是在服务器上创建集线器,这不过是一个类文件。我们将它命名为 SignalRChatHub
,并从中派生 Hub
类。它将包含一个名为 BroadCastMessage
的方法,带有 2 个参数。客户端代码将使用此方法(使用在其末尾生成的代理)与集线器进行通信,并将参数作为要发送到集线器的数据。在此方法中,使用 Hub
类的 Clients
属性来调用客户端函数。这个函数是一个简单的 JavaScript 函数,它将接收集线器发送的数据并更新用户的聊天窗口。我们将在客户端(稍后的代码中)定义一个名为 receiveMessage
的函数。所以现在,我们将使用这个方法名。
这里需要注意的一点是,我们不会获得对客户端方法的任何智能感知帮助,当然。这个方法将被动态解析。请参见下图
设置客户端代码
服务器设置已完成。现在,我们将添加一个名为 ChatWindow.html 的 HTML 页面,这将是我们的用户聊天窗口。我们还将在此页面上添加对 jquery-1.6.4.min.js 和 jquery.signalR-2.2.0 .min,js 的引用,
这些是由 nuget 包管理器添加的。
我们之前讨论过,SignalR
会在运行时自动生成一个代理类,供客户端代码连接到集线器。所以我们也需要引用这个文件。由于这个文件是在运行时生成的,它对我们来说并不实际存在。根据 ASP.NET 官方网站上的 SignalR
教程,它指出
SignalR creates the JavaScript code for the proxy on the fly and serves it to the client in response to the "/signalr/hubs" URL.
所以我们也需要添加这个引用。
我们还可以选择禁用此自动生成的代理文件生成(这超出了本次讨论的范围),并自己创建代理。在这种情况下,我们需要相应地引用该文件。接下来,让我们添加一些 HTML 标记来生成聊天窗口,并使用 CSS 样式来设计它。
现在,是时候让客户端代码连接到集线器并发送消息了,这样集线器就可以广播给所有用户。为此,我们首先在名为 chatProxy
的变量中获取代理实例。
请注意下面客户端代码的驼峰式语法。这是在创建 SignalR
应用程序时要遵循的约定。有关详细规范,我建议您查看 ASP.NET 官方 SignalR 网站。在不进一步深入细节的情况下,让我们继续代码。在这里,signalRChatHub
是服务器上集线器的名称(我们之前在服务器上创建的)。
接下来,我们在连接到集线器成功启动后附加按钮的点击事件(用于将消息发送给用户的按钮)。此事件将使用代理实例调用集线器的方法,该方法将接收消息并将其广播给用户。请参见下面的代码
我们还声明了当集线器需要更新所有用户收到的消息时将调用的函数。这就是我们在讨论开始时从集线器方法引用的函数名。所以这个函数在这里充当一种回调函数。
所以所有客户端代码也已设置完毕,我们现在可以运行应用程序了。因此,我们完整的客户端代码现在将如下所示
现在,我们可以运行应用程序了。复制 URL 并打开另一个浏览器实例或任何其他浏览器,我们就可以开始聊天了。
难道不简单吗?所以我们有了自己的聊天信使。祝编码愉快...!!!