2012-09-13 54 views
4

我知道Chris Fulstow project log4net.signalr,如果您想要非生產日誌,因爲它記錄了所有請求中的所有消息,所以這是個不錯的主意。我想通過發起請求來區分日誌消息,然後sed回合適的瀏覽器。Signalr從集線器外部呼叫特定客戶端

這裏我在附加器所做的:

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(如登錄ID-someguid),但我不知道是否有一些更聰明。

BOUNTY 我決定開始對這個問題賞金,我會還詢問有關架構,爲了看看我的策略是有道理,還是沒有。 我的疑惑是,我在從服務器到客戶端的單一「方向」中使用集線器,並使用它來記錄不是來自集線器調用的活動,而是來自其他請求(可能在其他集線器上提出的請求)這是一個正確的方法,以瀏覽器可見的log4net appender爲目標?

+0

我從來沒有解決過這樣的問題,唯一出現在我腦海的就是重寫URL,以便每個瀏覽器/標籤實例都通過url唯一標識,或者是url和cookie的組合 – Wasp

+0

@Wasp問題的應用程序是SPA :)我編輯的問題,以提出一個額外的想法,看看它是否有意義 –

+0

我猜對了:)但我仍然認爲你可以想出一些智能路由規則有一種在網址中生成的唯一ID並以某種方式處理。愚蠢的想法,用戶去http://www.foo.com,你第一次連接到http://www.foo.com/n2998fhn239重定向他,並將其保存在您的SPA – Wasp

回答

2

即使在同一SPA上打開多個選項卡,如何正確定位正確的瀏覽器實例/選項卡的想法是通過Url區分它們。一種可能的實現方式是將它們從第一次訪問http://foo.com重定向到http://foo.com/hhd83hd8hd8dh3,每次隨機生成。網址重寫也可以用其他方式完成,但這只是一種說明問題的方法。通過這種方式,appender將能夠檢查始發Url,並從Url通過一些映射您保持服務器端,您可以識別正確的SignalR ConnectionId。實現細節可能有所不同,但基本思想是這一個。跟蹤自第一次連接後在HttpContext中可用的更多信息,您還可以添加其他策略以防止任何劫持。

關於你的建築,我可以告訴你,這正是我在ElmahR中使用它的方式。我有來自通知集線器外部的消息(從其他Web應用程序發佈的錯誤),並且向連接到該集線器的所有客戶端(以及訂閱特定組)發送廣播:它工作正常。

我不是一個權威的來源,但我也猜測這樣的架構是好的,即使有多個集線器,因爲在一天結束時的集線器只是一個持久連接的抽象,它允許你按上下文對消息進行分組。在幕後(我正在簡化),你只是持久地聯繫着來回傳遞的信息,所以無論你在其上定義了什麼樣的樞紐結構(這只是爲了幫助你組織事情),你仍然堅持這種聯繫,所以你不能做任何傷害。

SignalR擅長做2件事:大規模廣播(客戶端)和一對一通信(來電者)。只要你不嘗試做怪異的事情,比如建立服務器端引用到特定的調用者,你應該沒問題,無論數量的集線器和它們之間的交互,你都可以。

這些是我的結論,來自現場。也許你可以對這個問題抽象@dfowler,看看他是否有(更多)更權威的指導方針。

+0

我很高興聽到整體架構有意義,仍然在尋找比Cookie更好的東西來將消息引導至正確的源 –