SignalR目前使用两种通信模型:Hub和PersistentConnection,而对于这两种通信模型他们在处理异常上面也有点不同,而唯一共同之处就是对于JavaScript客户端而言他们都是返回一个 promise(),认识这一点非常关键,这会让我们少说很多话。

在处理异常之前我们需要先开启日志跟踪开关,即:

  • 针对hub路由服务端 EnableDetailedErrors:指返回详细错误,默认是关闭,如果不开启我们就无法获取到详细的 throw 异常消息,取而代之的是JavaScript客户端脚本的一次友好描述信息。
  • 针对hub客户端 $.connection.hub.logging = true;:开启后会采用 console.log 来输出所有的日志数据。
  • 针对PersistentConnection路由服务端:他可没有这么好的开关,因为对于PersistentConnection他是一个非常底层的通信模型,换句话说,他不像Hub当遇到throw之类的会包裹一个友好的消息包发送给客户端;而对于PersistentConnection是当遇到 throw 时是直接停用连接。所以在处理异常时,我们需要在服务端捕获后并友好的发送一个数据包给客户端。
  • 针对PersistentConnection客户端:没办法他就只有一个 received 事件来处理由服务端发送的任何数据包,你只能自行处理。

针对服务端部分没有什么好讲的,但是一个友好的SignalR是不应该 throw 异常,应该处理好异常再转交给客户端。

主要针对两种通信模型在客户端处理的一些方法。

Hub通信模型

连接时异常

$.connection.hub.start().done(function () {
    // 连接成功时
}).fail(function (res) {
    // 连接失败时
});

记住我上面讲的,基本上所有的返回的对象都是一个 promise(),看 start() 返回的就是一个这样类型,所以我们很自然的可以添加 donefail 事件来处理异常。而这只是针对于连接时,比如:

我们将整个Hub要求登录认证,如果没有登录,那么会返回一个401状态的页面,而 fail 就可以捕获取。

可能由于站点重启倒置重新连接SignalR可能引起的异常。

注:当服务端调用一个客户端不存在的方法时

这一点要非常谨慎,因为不管你是否开始日志跟踪,你都无法判断他是否调用成功。因为当服务端调用一个客户端方法时,实际是使用jQuery的 triggerHandler,而对于此Signal JavaScript客户端库是没有做任何的异常处理。当然应该不会出现这种错误的。

PersistentConnection通信模型

PersistentConnection 始终只有一个 received 事件来接收任何数据包,而 received 返回的是一个 connection 对象,而他有相对应的一个 error 来处理异常。

几种常见的错误

1、 方法名称拼写错误、大小写、无效hub名称

默认情况下服务端方法名称会按驼峰命名法,当然我们可以使用 [HubName("msgHub")][HubMethodName("count")] 来重新定义。对于JavaScript是大小写敏感的,要注意这一点。

2、无效JSON格式

SignalR的服务端和客户端是通过JSON传输数据的,而默认使用的是 window.JSON 来解析客户端的JSON脚本,所以如果对于低版本的浏览器还需要引入第三方JSON库

3、Hub连接开始前至少必须订阅一个供服务端调用客户端方法

原因是消息必须要有一个返回对象,所以不管怎么样都必须在JavaScript客户端有一个相对应供服务端调用客户端方法,否则是无法启用Hub连接的。

4、混淆Hub和PersistentConnection两种通信语法

SignalR使用两种通信模型:Hub和PersistentConnection,这两种不管在服务端还是客户端调用的方式都不同。

JavaScript客户端创建一个PersistentConnection连接

var myConnection = $.connection('/echo');

JavaScript客户端创建一个Hub连接

var myHub = $.connection.MyHub;

C#服务端注册一个PersistentConnection路由

RouteTable.Routes.MapConnection<MyConnection>("my", "/echo");

C#服务端注册hub路由,以下默认是所有Hub

App.MapSignalR();

参考资料

查看 SignalR系列文章