SignalR 1.x 中心 API 指南 - JavaScript 客户端

作者 :Patrick FletcherTom Dykstra

警告

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

本文档介绍如何在 JavaScript 客户端(例如浏览器和 Windows 应用商店)中使用适用于 SignalR 版本 1.1 的中心 API (WinJS) 应用程序。

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

SignalR 还提供名为“持久连接”的较低级别的 API。 有关 SignalR、中心和持久连接的简介,或有关如何生成完整 SignalR 应用程序的教程,请参阅 SignalR - 入门

概述

本文档包含以下各节:

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

API 参考主题的链接指向 API 的 .NET 4.5 版本。 如果使用的是 .NET 4,请参阅 .NET 4 版本的 API 主题

生成的代理及其用途

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

编写代码以调用服务器方法时,生成的代理使你能够使用看起来好像正在执行本地函数的invoke('serverMethod', arg1, arg2)语法:可以编写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.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-1.0.1.min.js"></script>
<script src="signalr/hubs"></script>

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

如何引用动态生成的代理

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

注意

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

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

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

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

在 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,在某些情况下,使用 IIS Express 在 Visual Studio 中进行测试时,应用程序将正常工作,但在部署到完整 IIS 时会失败并显示 404 错误。 有关详细信息,请参阅在 MSDN 网站上 解析对Visual Studio 中 Web 服务器中Root-Level资源的引用,以 ASP.NET Web 项目

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

解决方案资源管理器 中 JavaScript 生成的代理文件

若要查看文件的内容,请双击 中心。 如果未使用 Visual Studio 2012 和 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.1.0.1\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 方法之前注册事件处理程序以建立连接。 如果要在建立连接后注册某些事件处理程序,可以这样做,但在调用 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建立连接,则表示跨域连接。 出于安全原因,默认禁用跨域连接。 若要建立跨域连接,请确保在服务器上启用跨域连接,并在创建连接对象时指定连接 URL。 SignalR 将使用适当的技术进行跨域连接,例如 JSONPCORS

在服务器上,在调用 MapHubs 方法时,通过选择该选项来启用跨域连接。

var hubConfiguration = new HubConfiguration();
hubConfiguration.EnableCrossDomain = true;
RouteTable.Routes.MapHubs(hubConfiguration);

在客户端上,在没有生成的代理) 的情况下 (创建连接对象时,或者在使用生成的代理) 调用 start 方法 (之前,指定 URL。

指定跨域连接的客户端代码 (生成的代理)

$.connection.hub.url = 'http://fabrikam.com/signalr'
$.connection.hub.start().done(init);

指定跨域连接 (的客户端代码,而不使用生成的代理)

var connection = $.hubConnection('http://fabrikam.com/');

使用 $.hubConnection 构造函数时,无需在 signalr URL 中包含,因为除非指定 useDefaultUrlfalse) ,否则该 URL 会自动添加 (。

可以创建到不同终结点的多个连接。

var connection1 = $.hubConnection('http://contoso.com/');
var connection2 = $.hubConnection('http://fabrikam.com/');

注意

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

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

    SignalR 处理 JSONP 或 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;
RouteTable.Routes.MapHubs(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也会引发 事件,因此方法处理程序和方法回调中的error.fail代码将执行。

如何启用客户端日志记录

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

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

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

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

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

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