asp.net-mvc - Signalr 从集线器外部调用特定客户端

标签 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 });
                }
            }
        }
    }

我正在尝试将 session 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 ),但我想知道是否有更智能的东西。

赏金
我决定在这个问题上开始悬赏,我还会询问架构,看看我的策略是否有意义。
我的疑问是,我在从服务器到客户端的单一“方向”上使用集线器,我用它来记录事件不是源自对集线器的调用,而是来自其他请求(可能是在其他集线器上提出的请求),是这是一种正确的方法,目标是浏览器可见的 log4net appender?

最佳答案

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

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

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

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

这些是我的结论,来自该领域。也许您可以就这个问题向 @dfowler 发推,看看他是否有(更)权威的指导方针。

关于asp.net-mvc - Signalr 从集线器外部调用特定客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12402497/

相关文章:

javascript - SignalR 拒绝连接到 [url],因为它违反了以下内容安全策略指令

c# - 无法从 singelton 事件取消订阅 signalR 集线器功能

html - 如何为 Angular JS 下拉菜单应用 CSS 样式

swift - 使用 Cocoapods 在 ios 中使用 Swift 的 SignalR 集成 - 协商请求期间出错

Azure SignalR 服务

asp.net - 将数据发送到各个客户端而不是使用 SignalR 中的 Clients.All

c# - 向空的 ASP.NET SignalR 组广播会浪费资源吗?

asp.net-mvc - Request.Files.Count 在 MVC 5 中上传图像时始终为 0

c# - 获取在 lambda 中定义的属性 o => o.Property1 的值

asp.net-mvc - 将 Glimpse 添加到引用 EF 项目的 MVC 项目的正确方法是什么?