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

本教程介绍如何使用 SignalR 创建实时聊天应用程序。 将 SignalR 添加到空 ASP.NET Web 应用程序,并创建一个用于发送和显示消息的 HTML 页面。

在本教程中,你将了解:

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

警告

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

先决条件

设置项目

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

  1. 在 Visual Studio 中,创建 ASP.NET Web 应用程序。

    创建 Web

  2. “新建 ASP.NET 项目 - SignalRChat ”窗口中,选择“ ”并选择“ 确定”。

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

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

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

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

  6. 将新的 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 broadcastMessage method to update clients.
                Clients.All.broadcastMessage(name, message);
            }
        }
    }
    
  7. “解决方案资源管理器”中,右键单击项目并选择“添加新>”。

  8. “添加新项 - SignalRChat ”中,选择 “已安装>的 Visual C#>Web ”,然后选择“ OWIN 启动类”。

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

  10. Startup 类中的默认代码替换为以下代码:

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

  12. 将新页 索引 命名为 ,然后选择“ 确定”。

  13. “解决方案资源管理器”中,右键单击创建的 HTML 页面,然后选择“设置为起始页”。

  14. 将 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-3.1.1.min.js" ></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-2.2.1.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>:&nbsp;&nbsp;' + 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>
    
  15. “解决方案资源管理器”中,展开“脚本”。

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

    重要

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

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

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

    <!--Script references. -->
    <!--Reference the jQuery library. -->
    <script src="Scripts/jquery-3.1.1.min.js" ></script>
    <!--Reference the SignalR library. -->
    <script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
    
  17. 如果不匹配,请更新 .html 文件。

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

运行示例

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

    输入用户名

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

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

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

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

    注意

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

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

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

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

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

检查代码

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

ChatHub.cs 中的 SignalR 中心

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

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

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

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

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

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

    public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }
    }
    

index.html中的 SignalR 和 jQuery

代码示例中的 index.html 页演示如何使用 SignalR jQuery 库与 SignalR 中心通信。 代码执行许多重要任务。 它声明一个引用中心的代理,声明一个函数,服务器可以调用该函数将内容推送到客户端,并启动连接以将消息发送到中心。

var chat = $.connection.chatHub;

注意

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

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

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>:&nbsp;&nbsp;' + 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();
        });
    });

注意

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

代码启动连接,然后向其传递一个函数,以处理 HTML 页中 “发送 ”按钮上的单击事件。

获取代码

下载已完成项目

其他资源

有关 SignalR 的详细信息,请参阅以下资源:

后续步骤

本教程介绍以下内容:

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

请转到下一篇文章,了解如何使用 SignalR 和 MVC 5。