教程:使用 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. Průzkumník řešení中,右键单击项目并选择“添加新>”。

  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. Průzkumník řešení中,右键单击项目并选择“添加>”。

  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. Průzkumník řešení中,选择控制器>HomeController.cs

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

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

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

  14. Průzkumník řešení中,右键单击“视图>主页”,然后选择“添加>视图”。

  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. Průzkumník řešení中,展开脚本

    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. Průzkumník řešení中,检查正在运行的应用程序的脚本文档节点。 有一个名为 SignalR 库在运行时生成的脚本文件。 此文件管理 jQuery 脚本和服务器端代码之间的通信。

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

检查代码

SignalR 聊天应用程序演示了两个基本的 SignalR 开发任务。 它演示如何创建中心。 服务器使用该中心作为主要协调对象。 中心使用 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 应用程序。