教程:SignalR 1.x 和 MVC 4 入门

作者 :Patrick FletcherTim Teebken

警告

本文档不适用于最新版本的 SignalR。 查看 ASP.NET Core SignalR

本教程演示如何使用 ASP.NET SignalR 创建实时聊天应用程序。 你将向 MVC 4 应用程序添加 SignalR,并创建聊天视图以发送和显示消息。

概述

本教程介绍如何使用 ASP.NET SignalR 和 ASP.NET MVC 4 进行实时 Web 应用程序开发。 本教程使用与 SignalR 入门教程相同的聊天应用程序代码,但演示如何基于 Internet 模板将其添加到 MVC 4 应用程序。

在本主题中,你将了解以下 SignalR 开发任务:

  • 将 SignalR 库添加到 MVC 4 应用程序。
  • 创建中心类以将内容推送到客户端。
  • 在网页中使用 SignalR jQuery 库从中心发送消息和显示更新。

以下屏幕截图显示了在浏览器中运行的已完成的聊天应用程序。

聊天实例

各部分内容:

设置项目

先决条件:

  • Visual Studio 2010 SP1、Visual Studio 2012 或 Visual Studio 2012 Express。 如果没有 Visual Studio,请参阅 ASP.NET 下载 获取免费的 Visual Studio 2012 Express 开发工具。
  • 对于 Visual Studio 2010,请安装 ASP.NET MVC 4

本部分介绍如何创建 ASP.NET MVC 4 应用程序、添加 SignalR 库和创建聊天应用程序。

    1. 在 Visual Studio 中创建 ASP.NET MVC 4 应用程序,将其命名为 SignalRChat,然后单击“确定”。

      注意

      在 VS 2010 中,在“框架版本”下拉列表控件中选择“.NET Framework 4”。 SignalR 代码在 .NET Framework 版本 4 和 4.5 上运行。

      创建 mvc Web 2. 选择“Internet 应用程序”模板,清除“ 创建单元测试项目”选项,然后单击“确定”。

      创建 mvc Internet 站点 3. 打开 工具 > NuGet 包管理器 > 包管理器控制台 并运行以下命令。 此步骤向项目添加一组启用 SignalR 功能的脚本文件和程序集引用。

      install-package Microsoft.AspNet.SignalR -Version 1.1.34. 在解决方案资源管理器展开 Scripts 文件夹。 请注意,SignalR 的脚本库已添加到项目中。

      库参考5. 在“解决方案资源管理器”中,右键单击项目,选择“添加” |新建文件夹,并添加名为“中心”的新文件夹。 6. 右键单击 “中心 ”文件夹,单击“ 添加|类,并创建名为 ChatHub.cs 的新 C# 类。 将此类用作向所有客户端发送消息的 SignalR 服务器中心。

注意

如果使用 Visual Studio 2012 并安装了 ASP.NET 和 Web 工具 2012.2 更新,则可以使用新的 SignalR 项模板创建中心类。 为此,请右键单击 “中心 ”文件夹,单击“添加| 新建项,选择“ signalR Hub 类 (v1) ”,并将类命名为 ChatHub.cs

  1. ChatHub 类中的代码替换为以下代码。

    using System;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    
    namespace SignalRChat
    {
        public class ChatHub : Hub
        {
            public void Send(string name, string message)
            {
                // Call the addNewMessageToPage method to update clients.
                Clients.All.addNewMessageToPage(name, message);
            }
        }
    }
    
  2. 打开项目的 Global.asax 文件,并将对 方法 RouteTable.Routes.MapHubs(); 的调用添加为 方法中的 Application_Start 第一行代码。 此代码注册 SignalR 中心的默认路由,必须在注册任何其他路由之前调用此代码。 完成 Application_Start 的方法如以下示例所示。

    protected void Application_Start()
    {
        RouteTable.Routes.MapHubs();
        AreaRegistration.RegisterAllAreas();
    
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();
    }
    
  3. 编辑 Controllers HomeController/HomeController.cs 中找到的类,并将以下方法添加到 类。 此方法返回将在后续步骤中创建的 聊天 视图。

    public ActionResult Chat()
    {
        return View();
    }
    
  4. 在刚刚创建的方法中 Chat 右键单击,然后单击“ 添加视图 ”以创建新的视图文件。

  5. 在“添加视图”对话框中,确保选中“检查”框以使用布局或母版页 (清除) 的其他检查框,然后单击“添加”。

    添加视图

  6. 编辑名为 Chat.cshtml 的新视图文件。 在 <h2> 标记后,将以下 <div> 节和 @section scripts 代码块粘贴到页面中。 此脚本使页面能够发送聊天消息并显示来自服务器的消息。 聊天视图的完整代码显示在以下代码块中。

    重要

    将 SignalR 和其他脚本库添加到 Visual Studio 项目时,包管理器可能会安装比本主题中显示的版本更新的脚本版本。 确保代码中的脚本引用与项目中安装的脚本库的版本匹配。

    @{
        ViewBag.Title = "Chat";
    }
    
    <h2>Chat</h2>
    
    <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>
    
    @section scripts {
        <!--Script references. -->
        <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
        <!--Reference the SignalR library. -->
        <script src="~/Scripts/jquery.signalR-1.0.1.js"></script>
        <!--Reference the autogenerated SignalR hub script. -->
        <script src="~/signalr/hubs"></script>
        <!--SignalR script to update the chat page and send messages.--> 
        <script>
            $(function () {
                // Reference the auto-generated proxy for the hub.  
                var chat = $.connection.chatHub;
                // Create a function that the hub can call back to display messages.
                chat.client.addNewMessageToPage = function (name, message) {
                    // Add the message to the page. 
                    $('#discussion').append('<li><strong>' + htmlEncode(name) 
                        + '</strong>: ' + htmlEncode(message) + '</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();
                    });
                });
            });
            // This optional function html-encodes messages for display in the page.
            function htmlEncode(value) {
                var encodedValue = $('<div />').text(value).html();
                return encodedValue;
            }
        </script>
    }
    
  7. 全部保存 项目。

运行示例

  1. 按 F5 以调试模式运行项目。

  2. 在浏览器地址行中,将 /home/chat 追加到项目默认页面的 URL。 “聊天”页面在浏览器实例中加载,并提示输入用户名。

    输入用户名

  3. 输入用户名。

  4. 从浏览器的地址行复制 URL,然后使用它打开另外两个浏览器实例。 在每个浏览器实例中,输入唯一的用户名。

  5. 在每个浏览器实例中,添加注释并单击“ 发送”。 注释应显示在所有浏览器实例中。

    注意

    这个简单的聊天应用程序不维护服务器上的讨论上下文。 中心向所有当前用户广播注释。 稍后加入聊天的用户将看到从他们加入时开始添加的消息。

  6. 以下屏幕截图显示了在浏览器中运行的聊天应用程序。

    聊天浏览器

  7. 解决方案资源管理器中,检查正在运行的应用程序的“脚本文档”节点。 如果使用 Internet Explorer 作为浏览器,则此节点在调试模式下可见。 SignalR 库在运行时动态生成的名为 hubs 的脚本文件。 此文件管理 jQuery 脚本与服务器端代码之间的通信。 如果使用 Internet Explorer 以外的浏览器,还可以通过直接浏览到动态 中心 文件来访问该文件,例如 http://mywebsite/signalr/hubs.

    生成的中心脚本

检查代码

SignalR 聊天应用程序演示了两个基本的 SignalR 开发任务:创建中心作为服务器上的main协调对象,以及使用 SignalR jQuery 库发送和接收消息。

SignalR 中心

在代码示例中, ChatHub 类派生自 Microsoft.AspNet.SignalR.Hub 类。 从 Hub 类派生是生成 SignalR 应用程序的有用方法。 可以在中心类上创建公共方法,然后通过网页中的 jQuery 脚本调用这些方法来访问这些方法。

在聊天代码中,客户端调用 ChatHub.Send 方法以发送新消息。 中心反过来通过调用 Clients.All.addNewMessageToPage 将消息发送到所有客户端。

Send 方法演示了几个中心概念:

  • 在中心上声明公共方法,以便客户端可以调用它们。

  • 使用 Microsoft.AspNet.SignalR.Hub.Clients 属性访问连接到此中心的所有客户端。

  • 在客户端 (上调用 jQuery 函数,例如 addNewMessageToPage 函数) 以更新客户端。

    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            Clients.All.addNewMessageToPage(name, message);
        }
    }
    

SignalR 和 jQuery

代码示例中的 Chat.cshtml 视图文件演示如何使用 SignalR jQuery 库与 SignalR 中心通信。 代码中的基本任务是创建对中心自动生成的代理的引用,声明服务器可以调用以将内容推送到客户端的函数,以及启动连接以将消息发送到中心。

以下代码声明中心的代理。

var chat = $.connection.chatHub;

注意

在 jQuery 中,对服务器类及其成员的引用采用 camel 大小写形式。 该代码示例将 jQuery 中的 C# ChatHub 类引用为 chatHub。 如果要像在 C# 中那样使用传统的 Pascal 大小写在 jQuery 中引用 ChatHub 类,请编辑 ChatHub.cs 类文件。 添加语句 using 以引用 Microsoft.AspNet.SignalR.Hubs 命名空间。 然后将 属性添加到 HubName 类, ChatHub 例如 [HubName("ChatHub")]。 最后,更新对 类的 ChatHub jQuery 引用。

以下代码演示如何在脚本中创建回调函数。 服务器上的中心类调用此函数将内容更新推送到每个客户端。 对 函数的 htmlEncode 可选调用显示了一种在将消息内容显示在页面中之前对消息内容进行 HTML 编码的方法,作为防止脚本注入的方法。

chat.client.addNewMessageToPage = function (name, message) {
    // Add the message to the page. 
    $('#discussion').append('<li><strong>' + htmlEncode(name) 
        + '</strong>: ' + htmlEncode(message) + '</li>');
};

以下代码演示如何打开与中心的连接。 该代码启动连接,然后向其传递一个函数,用于处理“聊天”页面中“ 发送 ”按钮上的单击事件。

注意

此方法可确保在事件处理程序执行之前建立连接。

$.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 是用于构建实时 Web 应用程序的框架。 你还了解了多个 SignalR 开发任务:如何将 SignalR 添加到 ASP.NET 应用程序、如何创建中心类以及如何从中心发送和接收消息。

若要了解更多高级 SignalR 开发概念,请访问以下站点以获取 SignalR 源代码和资源: