ASP.NET SignalR 中心 API 指南 - JavaScript 客户端

警告

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

本文档介绍如何在 JavaScript 客户端(如浏览器和 Windows 应用商店 (WinJS) 应用程序)中使用 Hubs API for SignalR 版本 2。

利用 SignalR 中心 API,可以 (RPC 进行远程过程调用,) 从服务器到连接的客户端,从客户端到服务器。 在服务器代码中,定义可由客户端调用的方法,并调用在客户端上运行的方法。 在客户端代码中,定义可从服务器调用的方法,并调用在服务器上运行的方法。 SignalR 负责处理所有客户端到服务器管道。

SignalR 还提供名为“持久连接”的较低级别的 API。 有关 SignalR、中心和持久连接的简介,请参阅 SignalR 简介

本主题中使用的软件版本

本主题的早期版本

有关 SignalR 早期版本的信息,请参阅 SignalR 旧版本

问题和评论

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

概述

本文档包含以下各节:

有关如何对服务器或 .NET 客户端进行编程的文档,请参阅以下资源:

SignalR 2 服务器组件仅在 .NET 4.5 (上可用,但在 .NET 4.0) 上存在用于 SignalR 2 的 .NET 客户端。

生成的代理及其用途

你可以对 JavaScript 客户端进行编程,以使用或不使用 SignalR 为你生成的代理来与 SignalR 服务通信。 代理的作用是简化用于连接的代码的语法,编写服务器调用的方法,并在服务器上调用方法。

编写代码以调用服务器方法时,生成的代理使你能够使用看起来好像在执行本地函数的语法:可以编写 serverMethod(arg1, arg2) 而不是 invoke('serverMethod', arg1, arg2)。 如果键入服务器方法名称错误,生成的代理语法还会立即出现可理解的客户端错误。 如果手动创建定义代理的文件,还可以获取 IntelliSense 支持,以便编写调用服务器方法的代码。

例如,假设服务器上具有以下 Hub 类:

public class ContosoChatHub : Hub
{
    public void NewContosoChatMessage(string name, string message)
    {
        Clients.All.addContosoChatMessageToPage(name, message);
    }
}

以下代码示例演示在服务器上调用 NewContosoChatMessage 方法以及从服务器接收方法调用 addContosoChatMessageToPage 时 JavaScript 代码的外观。

使用生成的代理

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) {
    console.log(name + ' ' + message);
};
$.connection.hub.start().done(function () {
    // Wire up Send button to call NewContosoChatMessage on the server.
    $('#newContosoChatMessage').click(function () {
         contosoChatHubProxy.server.newContosoChatMessage($('#displayname').val(), $('#message').val());
         $('#message').val('').focus();
     });
});

没有生成的代理

var connection = $.hubConnection();
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
contosoChatHubProxy.on('addContosoChatMessageToPage', function(name, message) {
    console.log(name + ' ' + message);
});
connection.start().done(function() {
    // Wire up Send button to call NewContosoChatMessage on the server.
    $('#newContosoChatMessage').click(function () {
        contosoChatHubProxy.invoke('newContosoChatMessage', $('#displayname').val(), $('#message').val());
        $('#message').val('').focus();
                });
    });

何时使用生成的代理

如果要为服务器调用的客户端方法注册多个事件处理程序,则不能使用生成的代理。 否则,可以选择使用生成的代理,也可以不根据编码首选项使用。 如果选择不使用它,则无需在客户端代码的元素中 script 引用“signalr/hubs”URL。

客户端设置

JavaScript 客户端需要引用 jQuery 和 SignalR 核心 JavaScript 文件。 jQuery 版本必须是 1.6.4 或主要更高版本,例如 1.7.2、1.8.2 或 1.9.1。 如果决定使用生成的代理,则还需要对 SignalR 生成的代理 JavaScript 文件的引用。 以下示例显示了引用在使用生成的代理的 HTML 页中的外观。

<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/jquery.signalR-2.1.0.min.js"></script>
<script src="signalr/hubs"></script>

这些引用必须按以下顺序包含:jQuery first,SignalR core after,SignalR 代理最后。

如何引用动态生成的代理

在前面的示例中,对 SignalR 生成的代理的引用是动态生成的 JavaScript 代码,而不是物理文件。 SignalR 动态创建代理的 JavaScript 代码,并将其提供给客户端以响应“/signalr/hubs”URL。 如果在方法中 MapSignalR 为服务器上的 SignalR 连接指定了不同的基 URL,则动态生成的代理文件的 URL 是追加了“/hubs”的自定义 URL。

注意

对于 Windows 8 (Windows 应用商店) JavaScript 客户端,请使用物理代理文件,而不是动态生成的代理文件。 有关详细信息,请参阅本主题后面的 如何为 SignalR 生成的代理创建物理文件

在 ASP.NET MVC 4 或 5 Razor 视图中,使用波形符引用代理文件引用中的应用程序根:

<script src="~/signalr/hubs"></script>

有关在 MVC 5 中使用 SignalR 的详细信息,请参阅使用 SignalR 和 MVC 5 入门

在 ASP.NET MVC 3 Razor 视图中,使用 Url.Content 作为代理文件引用:

<script src="@Url.Content("~/signalr/hubs")"></script>

在 ASP.NET Web Forms 应用程序中,使用 ResolveClientUrl 作为代理文件引用,或通过 ScriptManager 使用应用根相对路径 (从波形符) 开始注册它:

<script src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script>

一般情况下,使用与指定用于 CSS 或 JavaScript 文件的“/signalr/hubs”URL 相同的方法。 如果在不使用波形符的情况下指定 URL,在某些情况下,在 Visual Studio 中使用 IIS Express 测试时,应用程序将正常工作,但在部署到完整 IIS 时将失败并显示 404 错误。 有关详细信息,请参阅 MSDN 网站上的解析对 Visual Studio 中 Web 服务器中 ASP.NET Web 项目的Root-Level资源的引用

在 Visual Studio 2017 中以调试模式运行 Web 项目时,如果使用 Internet Explorer 作为浏览器,则可以在脚本解决方案资源管理器查看代理文件。

若要查看文件的内容,请双击“ 中心”。 如果未使用 Visual Studio 2012 或 2013 和 Internet Explorer,或者未处于调试模式,则还可以通过浏览到“/signalR/hubs”URL 来获取文件的内容。 例如,如果站点在 http://localhost:56699处运行,请在浏览器中转到 http://localhost:56699/SignalR/hubs

如何为 SignalR 生成的代理创建物理文件

作为动态生成的代理的替代方法,可以创建具有代理代码的物理文件并引用该文件。 你可能希望这样做是为了控制缓存或捆绑行为,或者在对服务器方法的调用进行编码时获取 IntelliSense。

若要创建代理文件,请执行以下步骤:

  1. 安装 Microsoft.AspNet.SignalR.Utils NuGet 包。

  2. 打开命令提示符并浏览到包含 SignalR.exe 文件 的工具 文件夹。 工具文件夹位于以下位置:

    [your solution folder]\packages\Microsoft.AspNet.SignalR.Utils.2.1.0\tools

  3. 输入以下命令:

    signalr ghp /path:[path to the .dll that contains your Hub class]

    .dll的路径通常是项目文件夹中的 bin 文件夹。

    此命令在 与signalr.exe 相同的文件夹中创建名为 server.js的文件。

  4. server.js 文件放在项目中的相应文件夹中,根据应用程序情况将其重命名,并添加对它的引用来代替“signalr/hubs”引用。

如何建立连接

在建立连接之前,必须创建连接对象、创建代理,并为可从服务器调用的方法注册事件处理程序。 设置代理和事件处理程序后,通过调用 start 方法建立连接。

如果使用生成的代理,则无需在自己的代码中创建连接对象,因为生成的代理代码会为你创建连接对象。

与生成的代理) 建立连接 (

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addContosoChatMessageToPage = function (name, message) {
    console.log(userName + ' ' + message);
};
$.connection.hub.start()
    .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
    .fail(function(){ console.log('Could not Connect!'); });

在没有生成的代理) 的情况下建立连接 (

var connection = $.hubConnection();
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
contosoChatHubProxy.on('addContosoChatMessageToPage', function(userName, message) {
    console.log(userName + ' ' + message);
});
connection.start()
    .done(function(){ console.log('Now connected, connection ID=' + connection.id); })
    .fail(function(){ console.log('Could not connect'); });

示例代码使用默认的“/signalr”URL 连接到 SignalR 服务。 有关如何指定其他基 URL 的信息,请参阅 ASP.NET SignalR 中心 API 指南 - 服务器 - /signalr URL

默认情况下,中心位置是当前服务器;如果要连接到其他服务器,请在调用 start 方法之前指定 URL,如以下示例所示:

$.connection.hub.url = '<yourbackendurl>;

注意

通常,在调用 start 方法之前注册事件处理程序以建立连接。 如果要在建立连接后注册某些事件处理程序,可以这样做,但在调用 start 方法之前,必须注册至少一个事件处理程序 () 。 其中一个原因是应用程序中可能有多个中心,但如果只使用其中一个中心,则不希望在每个中心上触发 OnConnected 事件。 建立连接后,中心代理上存在客户端方法会告知 SignalR 触发事件 OnConnected 。 如果在调用 start 方法之前未注册任何事件处理程序,则可以在中心上调用方法,但不会调用中心 OnConnected 的方法,也不会从服务器调用任何客户端方法。

$.connection.hub 是 $.hubConnection () 创建的同一对象

如示例中所示,使用生成的代理时, $.connection.hub 引用连接对象。 这是不使用生成的代理时通过调用 $.hubConnection() 获取的同一对象。 生成的代理代码通过执行以下语句为你创建连接:

在生成的代理文件中创建连接

使用生成的代理时,可以在不使用生成的代理时使用连接对象执行的任何 $.connection.hub 操作。

start 方法的异步执行

方法 start 异步执行。 它返回 jQuery Deferred 对象,这意味着可以通过调用 、 donefailpipe方法添加回调函数。 如果要在建立连接后执行的代码(例如对服务器方法的调用),请将该代码放入回调函数或从回调函数调用它。 回调 .done 方法在建立连接后执行,并在服务器上的事件处理程序方法中的任何 OnConnected 代码完成执行之后执行。

如果将前面示例中的“Now connected”语句作为方法调用后的 start 下一行代码放在 (不在回调) 中 .done ,则 console.log 行将在建立连接之前执行,如以下示例所示:

编写建立连接后运行的代码的方式不正确

如何建立跨域连接

通常,如果浏览器从 http://contoso.com加载页面,则 SignalR 连接位于 位于 的同一域中 http://contoso.com/signalr。 如果 中的 http://contoso.com 页面与 http://fabrikam.com/signalr建立连接,则表示跨域连接。 出于安全原因,默认禁用跨域连接。

在 SignalR 1.x 中,跨域请求由单个 EnableCrossDomain 标志控制。 此标志控制 JSONP 和 CORS 请求。 为了获得更大的灵活性,已从 SignalR 的服务器组件中删除所有 CORS 支持 (如果检测到浏览器) 支持 CORS,并且已提供新的 OWIN 中间件来支持这些方案,则 JavaScript 客户端仍会正常使用 CORS。

如果在客户端 (上需要 JSONP 来支持旧浏览器中的跨域请求) ,则需要通过将 对象true上的 HubConfiguration 设置为 EnableJSONP 显式启用,如下所示。 JSONP 默认处于禁用状态,因为它的安全性低于 CORS。

将 Microsoft.Owin.Cors 添加到项目: 若要安装此库,请在包管理器控制台中运行以下命令:

Install-Package Microsoft.Owin.Cors

此命令会将包的 2.1.0 版本添加到项目中。

调用 UseCors

以下代码片段演示如何在 SignalR 2 中实现跨域连接。

在 SignalR 2 中实现跨域请求

以下代码演示如何在 SignalR 2 项目中启用 CORS 或 JSONP。 此代码示例使用 MapRunSignalR 而不是 MapSignalR,因此 CORS 中间件仅针对需要 CORS 支持 (的 SignalR 请求运行,而不是针对 .) Map 中指定的路径上 MapSignalR的所有流量运行,也可用于需要针对特定 URL 前缀运行的任何其他中间件,而不是整个应用程序。

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;
namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Branch the pipeline here for requests that start with "/signalr"
            app.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can 
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);
                var hubConfiguration = new HubConfiguration 
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
        }
    }
}

注意

  • 不要在代码中设置为 jQuery.support.cors true。

    不要将 jQuery.support.cors 设置为 true

    SignalR 处理 CORS 的使用。 将 设置为 jQuery.support.cors true 会禁用 JSONP,因为它会导致 SignalR 假定浏览器支持 CORS。

  • 连接到 localhost URL 时,Internet Explorer 10 不会将其视为跨域连接,因此即使尚未在服务器上启用跨域连接,应用程序也能在本地使用 IE 10。

  • 有关将跨域连接与 Internet Explorer 9 配合使用的信息,请参阅 此 StackOverflow 线程

  • 有关将跨域连接与 Chrome 配合使用的信息,请参阅 此 StackOverflow 线程

  • 示例代码使用默认的“/signalr”URL 连接到 SignalR 服务。 有关如何指定其他基 URL 的信息,请参阅 ASP.NET SignalR 中心 API 指南 - 服务器 - /signalr URL

如何配置连接

在建立连接之前,可以指定查询字符串参数或指定传输方法。

如何指定查询字符串参数

如果要在客户端连接时将数据发送到服务器,可以将查询字符串参数添加到连接对象。 以下示例演示如何在客户端代码中设置查询字符串参数。

在使用生成的代理 (调用 start 方法之前设置查询字符串值)

$.connection.hub.qs = { 'version' : '1.0' };

在调用 start 方法之前设置查询字符串值, (不使用生成的代理)

var connection = $.hubConnection();
connection.qs = { 'version' : '1.0' };

以下示例演示如何在服务器代码中读取查询字符串参数。

public class ContosoChatHub : Hub
{
    public override Task OnConnected()
    {
        var version = Context.QueryString['version'];
        if (version != '1.0')
        {
            Clients.Caller.notifyWrongVersion();
        }
        return base.OnConnected();
    }
}

如何指定传输方法

在连接过程中,SignalR 客户端通常会与服务器协商以确定服务器和客户端都支持的最佳传输。 如果已经知道要使用哪种传输,则可以在调用 start 方法时通过指定传输方法来绕过此协商过程。

指定传输方法的客户端代码 (生成的代理)

$.connection.hub.start( { transport: 'longPolling' });

指定传输方法的客户端代码 (没有生成的代理)

var connection = $.hubConnection();
connection.start({ transport: 'longPolling' });

或者,可以按照希望 SignalR 尝试它们的顺序指定多种传输方法:

使用生成的代理 (指定自定义传输回退方案的客户端代码)

$.connection.hub.start( { transport: ['webSockets', 'longPolling'] });

指定自定义传输回退方案的客户端代码 (没有生成的代理)

var connection = $.hubConnection();
connection.start({ transport: ['webSockets', 'longPolling'] });

可以使用以下值指定传输方法:

  • “webSockets”
  • “foreverFrame”
  • “serverSentEvents”
  • “longPolling”

以下示例演示如何找出连接正在使用的传输方法。

显示连接使用生成的代理 (使用的传输方法的客户端代码)

$.connection.hub.start().done(function () {
    console.log("Connected, transport = " + $.connection.hub.transport.name);
});

显示连接 (使用的传输方法的客户端代码,而不使用生成的代理)

var connection = $.hubConnection();
connection.hub.start().done(function () {
    console.log("Connected, transport = " + connection.transport.name);
});

有关如何在服务器代码中检查传输方法的信息,请参阅 ASP.NET SignalR Hubs API 指南 - 服务器 - 如何从 Context 属性获取有关客户端的信息。 有关传输和回退的详细信息,请参阅 SignalR 简介 - 传输和回退

如何获取中心类的代理

创建的每个连接对象封装有关与包含一个或多个中心类的 SignalR 服务的连接的信息。 若要与 Hub 类通信,请使用自己创建的代理对象, (如果不使用生成的代理) 或为你生成的代理对象。

在客户端上,代理名称是中心类名的驼峰大小写版本。 SignalR 会自动进行此更改,以便 JavaScript 代码符合 JavaScript 约定。

服务器上的中心类

public class ContosoChatHub : Hub

获取对中心生成的客户端代理的引用

var myHubProxy = $.connection.contosoChatHub

在不使用生成的代理) 的情况下为中心类 (创建客户端代理

var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');

如果使用属性修饰 Hub 类 HubName ,请使用确切名称,而不更改大小写。

服务器上具有 HubName 属性的中心类

[HubName("ContosoChatHub")]
public class ChatHub : Hub

获取对中心生成的客户端代理的引用

var contosoChatHubProxy = $.connection.ContosoChatHub

在不使用生成的代理) 的情况下为中心类 (创建客户端代理

var contosoChatHubProxy = connection.createHubProxy('ContosoChatHub');

如何在客户端上定义服务器可以调用的方法

若要定义服务器可以从中心调用的方法,请使用 client 生成的代理的 属性将事件处理程序添加到中心代理,或者如果不使用生成的代理,则调用 on 方法。 参数可以是复杂对象。

在调用 start 方法以建立连接之前添加事件处理程序。 (如果要在调用 start 方法后添加事件处理程序,请参阅本文档前面 如何建立连接 中的说明,并使用所示的语法定义方法而不使用生成的 proxy.)

方法名称匹配不区分大小写。 例如, Clients.All.addContosoChatMessageToPage 在服务器上将在客户端上执行 AddContosoChatMessageToPageaddContosoChatMessageToPageaddcontosochatmessagetopage

使用生成的代理) 在客户端 (上定义方法

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addContosoChatMessageToPage = function (userName, message) {
    console.log(userName + ' ' + message);
};
$.connection.hub.start()
    .done(function(){ console.log('Now connected, connection ID=' + $.connection.hub.id); })
    .fail(function(){ console.log('Could not Connect!'); });

使用生成的代理) 在客户端 (上定义方法的另一种方法

$.extend(contosoChatHubProxy.client, {
    addContosoChatMessageToPage: function(userName, message) {
    console.log(userName + ' ' + message);
    };
});

在没有生成的代理的情况下在客户端 (上定义方法,或者在调用 start 方法后添加时)

var connection = $.hubConnection();
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
contosoChatHubProxy.on('addContosoChatMessageToPage', function(userName, message) {
    console.log(userName + ' ' + message);
});
connection.start()
    .done(function(){ console.log('Now connected, connection ID=' + connection.id); })
    .fail(function(){ console.log('Could not connect'); });

调用客户端方法的服务器代码

public class ContosoChatHub : Hub
{
    public void NewContosoChatMessage(string name, string message)
    {
        Clients.All.addContosoChatMessageToPage(name, message);
    }
}

以下示例包含一个复杂对象作为方法参数。

在客户端上定义方法,该方法使用生成的代理 (复杂对象)

var contosoChatHubProxy = $.connection.contosoChatHub;
contosoChatHubProxy.client.addMessageToPage = function (message) {
    console.log(message.UserName + ' ' + message.Message);
});

在客户端上定义方法,该方法在没有生成的代理 (复杂对象)

var connection = $.hubConnection();
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
chatHubProxy.on('addMessageToPage', function (message) {
    console.log(message.UserName + ' ' + message.Message);
});

定义复杂对象的服务器代码

public class ContosoChatMessage
{
    public string UserName { get; set; }
    public string Message { get; set; }
}

使用复杂对象调用客户端方法的服务器代码

public void SendMessage(string name, string message)
{
    Clients.All.addContosoChatMessageToPage(new ContosoChatMessage() { UserName = name, Message = message });
}

如何从客户端调用服务器方法

若要从客户端调用服务器方法,请使用 server 生成的代理的 属性或 invoke 中心代理上的 方法(如果未使用生成的代理)。 返回值或参数可以是复杂对象。

在中心上传入方法名称的 camel 大小写版本。 SignalR 会自动进行此更改,以便 JavaScript 代码符合 JavaScript 约定。

以下示例演示如何调用没有返回值的服务器方法,以及如何调用具有返回值的服务器方法。

没有 HubMethodName 属性的服务器方法

public class ContosoChatHub : Hub
{
    public void NewContosoChatMessage(ChatMessage message)
    {
        Clients.All.addContosoChatMessageToPage(message);
    }
}

定义在参数中传递的复杂对象的服务器代码

public class ChatMessage
{
    public string UserName { get; set; }
    public string Message { get; set; }
}

使用生成的代理) 调用服务器方法 (的客户端代码

contosoChatHubProxy.server.newContosoChatMessage({ UserName: userName, Message: message}).done(function () {
        console.log ('Invocation of NewContosoChatMessage succeeded');
    }).fail(function (error) {
        console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
    });

在没有生成的代理) 的情况下 (调用服务器方法的客户端代码

contosoChatHubProxy.invoke('newContosoChatMessage', { UserName: userName, Message: message}).done(function () {
        console.log ('Invocation of NewContosoChatMessage succeeded');
    }).fail(function (error) {
        console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
    });

如果使用属性修饰了 Hub 方法 HubMethodName ,请使用该名称而不更改大小写。

具有 HubMethodName 属性的服务器方法

public class ContosoChatHub : Hub
{
    [HubMethodName("NewContosoChatMessage")]
    public void NewContosoChatMessage(string name, string message)
    {
        Clients.All.addContosoChatMessageToPage(name, message);
    }
}

使用生成的代理) 调用服务器方法 (的客户端代码

contosoChatHubProxy.server.NewContosoChatMessage(userName, message).done(function () {
        console.log ('Invocation of NewContosoChatMessage succeeded');
    }).fail(function (error) {
        console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
    });

在没有生成的代理) 的情况下 (调用服务器方法的客户端代码

contosoChatHubProxy.invoke('NewContosoChatMessage', userName, message).done(function () {
        console.log ('Invocation of NewContosoChatMessage succeeded');
    }).fail(function (error) {
        console.log('Invocation of NewContosoChatMessage failed. Error: ' + error);
    });

前面的示例演示如何调用没有返回值的服务器方法。 以下示例演示如何调用具有返回值的服务器方法。

具有返回值的方法的服务器代码

public class StockTickerHub : Hub
{
    public IEnumerable<Stock> GetAllStocks()
    {
        return _stockTicker.GetAllStocks();
    }
}

用于返回值的 Stock 类

public class Stock
{
    public string Symbol { get; set; }
    public decimal Price { get; set; }
}

使用生成的代理) 调用服务器方法 (的客户端代码

function init() {
    return stockTickerProxy.server.getAllStocks().done(function (stocks) {
        $.each(stocks, function () {
            var stock = this;
            console.log("Symbol=" + stock.Symbol + " Price=" + stock.Price);
        });
    }).fail(function (error) {
        console.log('Error: ' + error);
    });
}

在没有生成的代理) 的情况下 (调用服务器方法的客户端代码

function init() {
    return stockTickerProxy.invoke('getAllStocks').done(function (stocks) {
        $.each(stocks, function () {
            var stock = this;
            console.log("Symbol=" + stock.Symbol + " Price=" + stock.Price);
        });
    }).fail(function (error) {
        console.log('Error: ' + error);
    });
}

如何处理连接生存期事件

SignalR 提供可以处理的以下连接生存期事件:

  • starting:在通过连接发送任何数据之前引发。
  • received:在连接上收到任何数据时引发。 提供接收的数据。
  • connectionSlow:当客户端检测到连接速度缓慢或频繁断开时引发。
  • reconnecting:基础传输开始重新连接时引发。
  • reconnected:在基础传输重新连接时引发。
  • stateChanged:连接状态更改时引发。 (连接、已连接、重新连接或断开连接) 提供旧状态和新状态。
  • disconnected:连接断开连接时引发。

例如,如果要在存在可能导致明显延迟的连接问题时显示警告消息,请处理 事件 connectionSlow

使用生成的代理) 处理 connectionSlow 事件 (

$.connection.hub.connectionSlow(function () {
    console.log('We are currently experiencing difficulties with the connection.')
});

在没有生成的代理) 的情况下处理 connectionSlow 事件 (

var connection = $.hubConnection();
connection.connectionSlow(function () {
    console.log('We are currently experiencing difficulties with the connection.')
});

有关详细信息,请参阅 了解和处理 SignalR 中的连接生存期事件

如何处理错误

SignalR JavaScript 客户端提供 error 可为其添加处理程序的事件。 还可以使用失败方法为服务器方法调用导致的错误添加处理程序。

如果未在服务器上显式启用详细的错误消息,则 SignalR 在发生错误后返回的异常对象包含有关错误的最少信息。 例如,如果对 newContosoChatMessage 的调用失败,则错误对象中的错误消息包含“There was an error invoking Hub method 'contosoChatHub.newContosoChatMessage'.”出于安全考虑,不建议向生产中的客户端发送详细错误消息,但如果要启用详细的错误消息以进行故障排除,请在服务器上使用以下代码。

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableDetailedErrors = true;
app.MapSignalR(hubConfiguration);

以下示例演示如何为错误事件添加处理程序。

使用生成的代理 (添加错误处理程序)

$.connection.hub.error(function (error) {
    console.log('SignalR error: ' + error)
});

在没有生成的代理) 的情况下添加错误处理程序 (

var connection = $.hubConnection();
connection.error(function (error) {
    console.log('SignalR error: ' + error)
});

以下示例演示如何处理方法调用中的错误。

使用生成的代理处理方法调用 (的错误)

contosoChatHubProxy.newContosoChatMessage(userName, message)
    .fail(function(error) { 
        console.log( 'newContosoChatMessage error: ' + error) 
    });

在没有生成的代理的情况下处理方法调用 (的错误)

contosoChatHubProxy.invoke('newContosoChatMessage', userName, message)
    .fail(function(error) { 
        console.log( 'newContosoChatMessage error: ' + error) 
    });

如果方法调用失败,也会引发 事件error,以便执行方法处理程序和方法回调中的.fail代码error

如何启用客户端日志记录

若要对连接启用客户端日志记录,请在调用 start 方法建立连接之前,在连接对象上设置 logging 属性。

使用生成的代理) 启用日志记录 (

$.connection.hub.logging = true;
$.connection.hub.start();

在没有生成的代理) 的情况下启用日志记录 (

var connection = $.hubConnection();
connection.logging = true;
connection.start();

若要查看日志,请打开浏览器的开发人员工具并转到“控制台”选项卡。有关显示分步说明的教程和演示如何执行此操作的屏幕截图,请参阅 使用 ASP.NET Signalr 进行服务器广播 - 启用日志记录