信号器从集线器外部呼叫特定客户端

时间:2012-09-13 08:40:38

标签: asp.net-mvc signalr signalr-hub

我知道Chris Fulstow project log4net.signalr,如果你想要一个非生产日志,这是一个好主意,因为它记录了所有请求的所有消息。我希望有一些东西通过发起它们的请求区分日志消息并返回到正确的浏览器。

这是我在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 });
                }
            }
        }
    }

我正在尝试将会话ID附加到cookie,但这不能在同一台机器上运行,因为cookie会被覆盖。 这是我在客户端上用来附加事件的代码:

//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();
    });

因此,只有连接的最后一页显示日志消息。我想知道是否有一些策略可以从浏览器获取当前连接ID,如果有的话。 另外,我很想知道是否有更好的设计来实现每个浏览器的日志记录。

修改

我可以创建一个基于会议名称的cookie(比如log-id-someguid),但我想知道是否有更聪明的东西。

BOUNTY 我决定开始对这个问题给予赏金,我还会询问架构,以便了解我的策略是否有意义。 我的疑问是,我在从服务器到客户端的单一“方向”中使用集线器,并且我使用它来记录不是来自对集线器的调用的活动,而是来自其他请求(可能是在其他集线器上发出的请求),一个正确的方法,以浏览器可见的log4net appender为目标?

1 个答案:

答案 0 :(得分:2)

即使在同一个SPA上打开多个标签页,如何正确定位正确的浏览器实例/标签的想法是通过网址区分它们。实现这一目标的一种可能方法是在每次随机生成的http://foo.comhttp://foo.com/hhd83hd8hd8dh3的第一次访问时重定向它们。网址重写也可以通过其他方式完成,但这只是一种说明问题的方法。通过这种方式,appender将能够检查原始Url,并且通过一些映射,您可以保留服务器端,从而可以识别正确的SignalR ConnectionId。实现细节可能有所不同,但基本思路就是这个。跟踪HttpContext中可用的更多信息,因为第一次连接您还可以实施其他策略以防止任何劫持。

关于您的架构,我可以告诉您,这正是我在ElmahR中使用它的方式。我的消息来自通知中心外部(从其他网络应用程序发布的错误),我向连接到该中心的所有客户端(以及订阅某些组)进行广播:它工作正常。

我不是权威来源,但我也猜测这样的架构是可以的,即使有多个集线器,因为在一天结束时的集线器只是一个(一个)持久连接的抽象,它允许你按上下文分组消息。在幕后(我正在简化)你只是一个持续的消息来回连接,所以无论你在它上面定义什么集线器结构(这只是为了帮助你组织事情)你仍然坚持这种连接,所以你不能做任何伤害。

SignalR擅长做两件事:大规模广播(客户端)和一对一通信(来电者)。只要你不尝试做一些奇怪的事情,比如建立对特定呼叫者的服务器端引用,你应该没问题,无论有多少个集线器,以及它们之间的交互,你都有。

这些是我的结论,来自该领域。也许你可以对@dfowler提出这个问题,看看他是否有更多权威指南。