教程:SignalR 自承载

作者 :Patrick Fletcher

警告

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

本教程介绍如何创建自承载 SignalR 2 服务器,以及如何使用 JavaScript 客户端连接到该服务器。

本教程中使用的软件版本

通过本教程使用 Visual Studio 2012

若要在本教程中使用 Visual Studio 2012,请执行以下操作:

  • 包管理器 更新到最新版本。
  • 安装 Web 平台安装程序
  • 在 Web 平台安装程序中,搜索并安装 ASP.NET 和 Web 工具 2013.1 for Visual Studio 2012。 这将为 SignalR 类(例如 Hub)安装 Visual Studio 模板。
  • 某些模板 ((如 OWIN 启动类) )将不可用;对于这些,请改用类文件。

问题和评论

请留下反馈,说明你对本教程的喜爱程度,以及我们可以在页面底部的评论中改进的内容。 如果你有与本教程不直接相关的问题,可以将其发布到 ASP.NET SignalR 论坛StackOverflow.com

概述

SignalR 服务器通常托管在 IIS 的 ASP.NET 应用程序中,但它也可以是自承载 (,例如,在使用自承载库的控制台应用程序或 Windows 服务) 中。 与所有 SignalR 2 一样,此库基于 OWIN (Open Web Interface for .NET) 构建。 OWIN 定义 .NET Web 服务器和 Web 应用程序之间的抽象。 OWIN 将 Web 应用程序与服务器分离,这使得 OWIN 非常适合在 IIS 外部的你自己的进程中自承载 Web 应用程序。

未在 IIS 中托管的原因包括:

  • IIS 不可用或不可取的环境,例如没有 IIS 的现有服务器场。
  • 需要避免 IIS 的性能开销。
  • SignalR 功能将添加到在 Windows 服务、Azure 辅助角色或其他进程中运行的现有应用程序。

如果出于性能原因将解决方案开发为自承载,则建议同时测试 IIS 中托管的应用程序以确定性能优势。

本教程包含以下部分:

创建服务器

在本教程中,你将创建一个托管在控制台应用程序中的服务器,但该服务器可以托管在任何类型的进程中,例如 Windows 服务或 Azure 辅助角色。 有关在 Windows 服务中托管 SignalR 服务器的示例代码,请参阅 Windows 服务中的自承载 SignalR

  1. 使用管理员权限打开Visual Studio 2013。 依次选择“ 文件”、“ 新建项目”。 在“模板”窗格中,选择“Visual C#节点下的“Windows”,然后选择“控制台应用程序”模板。 将新项目命名为“SignalRSelfHost”,然后单击“ 确定”。

    “新建项目”屏幕的屏幕截图,其中突出显示了“Windows”选项、“控制台应用程序”模板和“名称”字段。

  2. 通过选择“工具>”“NuGet 包管理器”“包管理器>控制台”打开NuGet 包管理器控制台

  3. 在包管理器控制台中,输入以下命令:

    Install-Package Microsoft.AspNet.SignalR.SelfHost
    

    此命令将 SignalR 2 Self-Host库添加到项目中。

  4. 在包管理器控制台中,输入以下命令:

    Install-Package Microsoft.Owin.Cors
    

    此命令将 Microsoft.Owin.Cors 库添加到项目中。 此库将用于跨域支持,这是托管 SignalR 的应用程序和不同域中的网页客户端所必需的。 由于你将在不同的端口上托管 SignalR 服务器和 Web 客户端,这意味着必须启用跨域才能在这些组件之间进行通信。

  5. 将 Program.cs 的内容替换为以下代码。

    using System;
    using Microsoft.AspNet.SignalR;
    using Microsoft.Owin.Hosting;
    using Owin;
    using Microsoft.Owin.Cors;
    
    namespace SignalRSelfHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                // This will *ONLY* bind to localhost, if you want to bind to all addresses
                // use http://*:8080 to bind to all addresses. 
                // See http://msdn.microsoft.com/library/system.net.httplistener.aspx 
                // for more information.
                string url = "http://localhost:8080";
                using (WebApp.Start(url))
                {
                    Console.WriteLine("Server running on {0}", url);
                    Console.ReadLine();
                }
            }
        }
        class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.UseCors(CorsOptions.AllowAll);
                app.MapSignalR();
            }
        }
        public class MyHub : Hub
        {
            public void Send(string name, string message)
            {
                Clients.All.addMessage(name, message);
            }
        }
    }
    

    上述代码包括三个类:

    • 程序,包括定义执行的主路径的 Main 方法。 在此方法中, Startup 类型的 Web 应用程序在指定的 URL (http://localhost:8080) 启动。 如果终结点上需要安全性,则可以实现 SSL。 有关详细信息 ,请参阅如何:使用 SSL 证书配置端口
    • 启动时,包含 SignalR 服务器的配置的类 (本教程使用的唯一配置是调用 UseCors) 和对 MapSignalR的调用,后者为项目中的任何中心对象创建路由。
    • MyHub,应用程序将提供给客户端的 SignalR Hub 类。 此类有一个方法 Send,客户端将调用该方法将消息广播到所有其他连接的客户端。
  6. 编译并运行该应用程序。 服务器正在运行的地址应显示在控制台窗口中。

    在控制台窗口中运行的服务器的屏幕截图。

  7. 如果执行失败并出现异常 System.Reflection.TargetInvocationException was unhandled,则需要使用管理员权限重启 Visual Studio。

  8. 在继续下一部分之前停止应用程序。

使用 JavaScript 客户端访问服务器

在本部分中,你将使用 入门 教程中的同一 JavaScript 客户端。 我们将仅对客户端进行一次修改,即显式定义中心 URL。 对于自承载应用程序,由于反向代理和负载均衡器) ,服务器不一定与连接 URL (位于同一地址,因此需要显式定义 URL。

  1. “解决方案资源管理器”中,右键单击解决方案,然后选择“添加”、“新建项目”。 选择 “Web” 节点,然后选择“ ASP.NET Web 应用程序 ”模板。 将项目命名为“JavascriptClient”,然后单击“ 确定”。

    “添加新项目”屏幕的屏幕截图,其中突出显示了“Web”节点、A S P dot NET Web 应用程序模板和“名称”字段。

  2. 选择 “空 ”模板,并将其余选项保留为未选中状态。 选择“创建项目”。

    “新建 A S P dot NET 项目”屏幕的屏幕截图,其中选择了“空模板”并突出显示了“创建项目”选项。

  3. 在包管理器控制台中,在 “默认项目 ”下拉列表中选择“JavascriptClient”项目,并执行以下命令:

    Install-Package Microsoft.AspNet.SignalR.JS
    

    此命令将安装客户端中所需的 SignalR 和 JQuery 库。

  4. 右键单击项目,然后选择“添加”、“新建项”。 选择 “Web” 节点,然后选择“HTML 页面”。 将页面 命名为Default.html

    “添加新项”屏幕的屏幕截图,其中突出显示了“Web”选项、“URL 页面”模板和“名称”字段。

  5. 将新 HTML 页的内容替换为以下代码。 验证此处的脚本引用是否与项目的 Scripts 文件夹中的脚本匹配。

    <!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-1.6.4.min.js"></script>
        <!--Reference the SignalR library. -->
        <script src="Scripts/jquery.signalR-2.1.0.min.js"></script>
        <!--Reference the autogenerated SignalR hub script. -->
        <script src="http://localhost:8080/signalr/hubs"></script>
        <!--Add script to update the page and send messages.-->
        <script type="text/javascript">
            $(function () {
            //Set the hubs URL for the connection
                $.connection.hub.url = "http://localhost:8080/signalr";
                
                // Declare a proxy to reference the hub.
                var chat = $.connection.myHub;
                
                // Create a function that the hub can call to broadcast messages.
                chat.client.addMessage = 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>
    

    除了将 (代码升级到 SignalR 版本 2 beta) 之外,) 上面的代码示例中突出显示了以下代码 (在获取星标教程 (中对客户端所做的添加。 此代码行显式设置服务器上的 SignalR 的基本连接 URL。

    //Set the hubs URL for the connection
    $.connection.hub.url = "http://localhost:8080/signalr";
    
  6. 右键单击解决方案,然后选择“ 设置启动项目...”。选择“ 多个启动项目 ”单选按钮,并将两个项目的 “操作 ”设置为 “启动”。

    “解决方案属性页”屏幕的屏幕截图,其中突出显示了“多个启动项目”单选按钮和“启动操作”条目。

  7. 右键单击“Default.html”,然后选择“ 设为起始页”。

  8. 运行应用程序。 服务器和页面将启动。 可能需要重新加载网页 (或在启动服务器之前加载页面) 在调试器中选择“ 继续 ”。

  9. 在浏览器中,出现提示时提供用户名。 将页面的 URL 复制到另一个浏览器选项卡或窗口中,并提供其他用户名。 你将能够将消息从一个浏览器窗格发送到另一个浏览器窗格,如入门教程中所示。