教程:使用 SignalR 2 和 MVC 5 进行实时聊天

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

在本教程中,你将了解:

  • 设置项目
  • 运行示例
  • 检查代码

警告

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

先决条件

设置项目

本部分介绍如何使用 Visual Studio 2017 和 SignalR 2 创建空 ASP.NET MVC 5 应用程序、添加 SignalR 库以及创建聊天应用程序。

  1. 在 Visual Studio 中,创建面向 .NET Framework 4.5 的 C# ASP.NET 应用程序,将其命名为 SignalRChat,然后单击“确定”。

    创建 Web

  2. “新建 ASP.NET Web 应用程序 - SignalRMvcChat”中,选择“ MVC ”,然后选择“ 更改身份验证”。

  3. “更改身份验证”中,选择“ 无身份验证 ”,然后单击“ 确定”。

    选择“无身份验证”

  4. “新建 ASP.NET Web 应用程序 - SignalRMvcChat”中,选择“ 确定”。

  5. “解决方案资源管理器”中,右键单击项目并选择“添加新>”。

  6. “添加新项 - SignalRChat”中,选择“ 已安装>的 Visual C#>Web>SignalR ”,然后选择“ signalR 中心类” (v2)

  7. 将类命名为 ChatHub 并将其添加到项目中。

    此步骤创建 ChatHub.cs 类文件,并将一组支持 SignalR 的脚本文件和程序集引用添加到项目。

  8. 将新的 ChatHub.cs 类文件中的代码替换为以下代码:

    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);
            }
        }
    }
    
  9. “解决方案资源管理器”中,右键单击项目并选择“添加>”。

  10. 将新类命名为 Startup 并将其添加到项目中。

  11. Startup.cs 类文件中的代码替换为以下代码:

    using Owin;
    using Microsoft.Owin;
    [assembly: OwinStartup(typeof(SignalRChat.Startup))]
    namespace SignalRChat
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // Any connection or hub wire up and configuration should go here
                app.MapSignalR();
            }
        }
    }
    
  12. “解决方案资源管理器”中,选择“控制器>”“HomeController.cs”。

  13. 将此方法添加到 HomeController.cs

    public ActionResult Chat()
    {
        return View();
    }
    

    此方法返回在后面的步骤中创建的 聊天 视图。

  14. 解决方案资源管理器中,右键单击“视图>主页”,然后选择“添加>视图”。

  15. “添加视图”中,将新视图命名为 “聊天 ”,然后选择“ 添加”。

  16. Chat.cshtml 的内容替换为以下代码:

    @{
        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-2.1.0.min.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>
    }
    
  17. “解决方案资源管理器”中,展开“脚本”。

    jQuery 和 SignalR 的脚本库在项目中可见。

    重要

    包管理器可能已安装更高版本的 SignalR 脚本。

  18. 检查代码块中的脚本引用是否与项目中脚本文件的版本相对应。

    原始代码块中的脚本引用:

    <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
    
  19. 如果不匹配,请更新 .cshtml 文件。

  20. 从菜单栏中,选择“ 文件>全部保存”。

运行示例

  1. 在工具栏中,打开 “脚本调试 ”,然后选择“播放”按钮以在调试模式下运行示例。

    输入用户名

  2. 当浏览器打开时,输入聊天标识的名称。

  3. 从浏览器中复制 URL,打开其他两个浏览器,然后将 URL 粘贴到地址栏中。

  4. 在每个浏览器中,输入唯一的名称。

  5. 现在,添加注释并选择“ 发送”。 在其他浏览器中重复此操作。 批注实时显示。

    注意

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

    了解聊天应用程序如何在三个不同的浏览器中运行。 当 Tom、Anand 和 Susan 发送消息时,所有浏览器都会实时更新:

    所有三个浏览器都显示相同的聊天历史记录

  6. 解决方案资源管理器中,检查正在运行的应用程序的“脚本文档”节点。 有一个名为 hubs 的 脚本文件,SignalR 库在运行时生成。 此文件管理 jQuery 脚本与服务器端代码之间的通信。

    “脚本文档”节点中自动生成的中心脚本

检查代码

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

ChatHub.cs 中的 SignalR 中心

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

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

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

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

  • Microsoft.AspNet.SignalR.Hub.Clients使用动态属性与连接到此中心的所有客户端通信。

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

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

SignalR 和 jQuery Chat.cshtml

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

var chat = $.connection.chatHub;

注意

在 JavaScript 中,对服务器类及其成员的引用位于 camelCase 中。 代码示例将 JavaScript 中的 C# ChatHub 类引用为 chatHub

在此代码块中,你将在脚本中创建一个回调函数。

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

服务器上的中心类调用此函数将内容更新推送到每个客户端。 对 函数的 htmlEncode 可选调用显示了一种在将消息内容显示在页面中之前对消息内容进行 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 的详细信息,请参阅以下资源:

后续步骤

在本教程中,你将了解:

  • 设置项目
  • 运行示例
  • 已检查代码

请转到下一篇文章,了解如何创建使用 ASP.NET SignalR 2 提供高频消息传递功能的 Web 应用程序。