Pregunta

I'm aware of the Chris Fulstow project log4net.signalr, it is a great idea if you want a non production log since it logs all messages from all requests. I would like to have something that discriminates log messages by the request originating them and sed back to the proper browser.

Here what I've done in the appender:

 public class SignalRHubAppender:AppenderSkeleton
    {
        protected override void Append(log4net.Core.LoggingEvent loggingEvent)
        {
            if (HttpContext.Current != null)
            {
                var cookie = HttpContext.Current.Request.Cookies["log-id"];
                if (null != cookie)
                {
                    var formattedEvent = RenderLoggingEvent(loggingEvent);
                    var context = GlobalHost.ConnectionManager.GetHubContext<Log4NetHub>();
                    context.Clients[cookie.Value].onLog(new { Message = formattedEvent, Event = loggingEvent });
                }
            }
        }
    }

I'm trying to attach the session id to a cookie, but this does not work on the same machine because the cookie is overwritten. here is the code I use on the client to attach the event:

//start hubs
    $.connection.hub.start()
    .done(function () {
        console.log("hub subsystem running...");
        console.log("hub connection id=" + $.connection.hub.id);
        $.cookie("log-id", $.connection.hub.id);
        log4netHub.listen();
    });

As a result, just the last page connected shows the log messages. I would like to know if there is some strategies to have the current connection id from the browser which originate the current request, if there is any. Also I'm interested to know if there is better design to achieve a per browser logging.

EDIT

I could made a convention name based cookie ( like log-id-someguid ), but I wonder if there is something smarter.

BOUNTY I decided to start a bounty on that question, and I would additionally ask about the architecture, in order to see if my strategy makes sense or not. My doubt is, I'm using the hub in a single "direction" from server to client, and I use it to log activities not originating from calls to the hub, but from other requests ( potentially requests raised on other hubs ), is that a correct approach, having as a goal a browser visible log4net appender?

¿Fue útil?

Solución

The idea about how to correctly target the right browser instance/tab, even when multiple tabs are open on the same SPA, is to differentiate them through the Url. One possible way to implement that is to redirect them at the first access from http://foo.com to http://foo.com/hhd83hd8hd8dh3, randomly generated each time. That url rewriting could be done in other ways too, but it's just a way to illustrate the problem. This way the appender will be able to inspect the originating Url, and from the Url through some mapping you keep server side you can identify the right SignalR ConnectionId. The implementation details may vary, but the basic idea is this one. Tracking some more info available in the HttpContext since the first connection you could also put in place additional strategies in order to prevent any hijacking.

About your architecture, I can tell you that this is exactly the way I used it in ElmahR. I have messages originating from outside the notification hub (errors posted from other web apps), and I do a broadcast to all clients connected to that hub (and subscribing certain groups): it works fine.

I'm not an authoritative source, but I also guess that such an architecture is ok, even with multiple hubs, because hubs at the end of the day are just an abstraction over a (one) persistent connection which allows you to group messaging by contexts. Behind the scenes (I'm simplifying) you have just a persistent connection with messages going back and forth, so whatever hub structure you define on top of it (which is there just to help you organizing things) you still insist on that connection, so you cannot do any harm.

SignalR is good on doing 2 things: massive broadcast (Clients), and one-to-one communication (Caller). As long as you do not try to do weird things like building keeping server-side references to specific callers, you should be ok, whatever number of Hubs, and interactions among them, you have.

These are my conclusions, coming from the field. Maybe you can twit @dfowler about this question and see if he has (much) more authoritative guidelines.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top