SignalR exception logging?

2019-02-03 02:46发布

问题:

This is more of two questions, but :

  1. What's the best way to have a top level exception handler for my Hub? It doesn't seem possible with the current version of SignalR

  2. Why doesn't this actually do anything on the client when I throw an error in my Hub?

    $.connection.hub.error(function() { return alert("test"); });

When I debug, I can see my error method being wired up, but when I throw an exception on the Hub, I can see there's never any attempt to call the method I setup above. The only thing that happens is SignalR barfs the error to the console.

For the record, I can wire up other events just fine

//Called during exceptions just fine 
$.connection.hub.received(function() {
  return alert("Received Data");
});

//Seems to do nothing?
$.connection.hub.error(function() {
  return alert("Received Exception");
});

回答1:

$.connection.hub.error is used to handle hub connection failures. You can use jQuery's deferred.fail() to handle an exception thrown from a particular hub invocation ($.connection.hub.methodThatThrows().fail(function() { ... }), but this obviously doesn't handle exceptions thrown from any invocation.

SignalR v1.0.0 will add support for IHubPipelineModules. Then you will be able to override HubPipelineModule.BuildIncoming or HubPipelineModule.OnIncomingError which can then be added to the HubPipeline via GlobalHost.HubPipeline.AddModule(myHubPipelineModule).

https://github.com/SignalR/SignalR/issues/548

https://github.com/SignalR/SignalR/commit/83fdbfd9baa1f1cc3399d7f210cb062597c8084c

Example implementation:

using Microsoft.AspNet.SignalR.Hubs;

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

protected void Application_Start()
{
    GlobalHost.HubPipeline.AddModule(new MyHubPipelineModule());
}

// JS
// hub.client is also introduced in SignalR v1.0.0
$.connection.myHub.client.exceptionHandler = function (message) {
    alert(message);
};