【问题标题】:How to handle SignalR server exception at client?如何在客户端处理 SignalR 服务器异常?
【发布时间】:2016-03-21 15:41:42
【问题描述】:

错误处理程序在客户端添加如下:

$.connection.hub.url = "/signalr";
$.connection.hub.logging = true;
$.connection.hub.error(function(error) {
    console.log('SignalrAdapter: ' + error);
});

$.connection.hub.start().done(function() { me.onStartDone(); });
// ...

在服务器上是:

hubConfiguration.EnableDetailedErrors = true;

按照the docs的说法应该足够了。

在我抛出异常时,它只显示一个日志文本,而不调用处理程序:

[18:18:19 GMT+0000()] SignalR: ... [[[my error description here]]] ... 

在我的 cshtml 页面:

<script src="~/Scripts/vendor/jquery.signalR-2.1.2.js"></script>
<script src="~/signalr/hubs"></script>

但是,如果我将错误处理程序附加到方法本身,它就会被调用:

$.connection.operatorHub.server.myMethodName(someParam).fail(function(error) {
    console.log("Error handler called: " + error);
});

如何处理一般错误?

更新。 答案如下。另请参阅:

希望对某人有所帮助。

【问题讨论】:

  • 您可以尝试禁用日志记录$.connection.hub.logging = true;
  • @QuentinRoger 不,它没有帮助。
  • 奇怪的是,如果我在方法的错误处理程序上停下来并评估堆栈中捕获的内容,则会调用通用错误处理程序。

标签: javascript asp.net signalr


【解决方案1】:

我在一个小聊天项目(downloaded here)上测试过,这个方法似乎只处理连接错误。

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

我能够使用 HubPipelineModule 类处理所有异常。

1) 我创建了一个SOHubPipelineModule

public class SOHubPipelineModule : HubPipelineModule
{
    protected override void OnIncomingError(ExceptionContext exceptionContext,
                                            IHubIncomingInvokerContext invokerContext)
    {
        dynamic caller = invokerContext.Hub.Clients.Caller;
        caller.ExceptionHandler(exceptionContext.Error.Message);
    }
}

2) 我将模块添加到GlobalHost.HubPipeline

  // Any connection or hub wire up and configuration should go here
  GlobalHost.HubPipeline.AddModule(new SOHubPipelineModule());
  var hubConfiguration = new HubConfiguration { EnableDetailedErrors = true };
  app.MapSignalR(hubConfiguration);

3) 我的ChatHub 班级:

 public class ChatHub : Hub
    {
        public void Send(string name, string message)
        {
            throw new Exception("exception for Artyom");
            Clients.All.broadcastMessage(name, message);
        }

    }

4) 在 js 中,我使用此代码获取异常消息:

$.connection.chatHub.client.exceptionHandler = function (error) {
      console.log('SignalrAdapter: ' + error);
      alert('SignalrAdapter: ' + error);
};       

【讨论】:

  • 有趣的方式。不知道HubPipelineModule.OnIncomingError。尝试了小聊天项目。它在那里工作。但这在我的项目中不起作用。研究这个。在我的项目中,我有信号器组、autofac、owin 等。而在客户端......这似乎很复杂。
  • 这似乎是一些黑客行为。为什么不首先得到错误,而不是向客户发出第二次调用?
  • 我知道这很丑,但我认为这是处理集线器所有异常的唯一方法:(
  • 我认为这个解决方案适用于 ASP.NET SignalR 而不是 ASP.NET Core SingnalR,因为 HubPipelineModule 在命名空间 Microsoft.AspNet.SignalR.Hubs 中; ASP.NET Core SignalR 的任何解决方案?
  • 在 .NET Core 的新 SignalR 版本中,这不再是一个选项。
【解决方案2】:

我在客户端上使用了这样的错误处理:

适用于 SignalR 版本 2

更多详情:SignalR documentation - How to handle errors in the Hub class

集线器 - AppHub.cs:

public class AppHub : Hub
    {
        public void Send(string message)
        {
            throw new HubException("Unauthorized", new { status = "401" });
        }
    }

客户端:

$(function () {

            var appHub = $.connection.appHub;

            $.connection.hub.start().done(function () {

                appHub.server.send("test message")
                    .fail(function (e) {

                        if (e.source === 'HubException') {
                            console.error("Error message: ", e.message);
                            console.error("Error status: ", e.data.status);
                        }

                    });
            });

        });

【讨论】:

  • 值得注意的是,这是随 SignalR 2 添加的
  • 这行得通!应该是在客户端检索异常的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2018-09-18
  • 2012-06-23
  • 1970-01-01
  • 2013-06-24
  • 2019-06-12
  • 1970-01-01
相关资源
最近更新 更多